summaryrefslogtreecommitdiff
path: root/target/linux/s3c24xx/patches-2.6.31/057-pcf50633.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.31/057-pcf50633.patch')
-rw-r--r--target/linux/s3c24xx/patches-2.6.31/057-pcf50633.patch487
1 files changed, 0 insertions, 487 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.31/057-pcf50633.patch b/target/linux/s3c24xx/patches-2.6.31/057-pcf50633.patch
deleted file mode 100644
index 3143215..0000000
--- a/target/linux/s3c24xx/patches-2.6.31/057-pcf50633.patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From 20fb4fd1e317dadaaaaeb9c153098b57d0fc86fe Mon Sep 17 00:00:00 2001
-From: Lars-Peter Clausen <lars@metafoo.de>
-Date: Tue, 21 Jul 2009 12:47:03 +0200
-Subject: [PATCH] 056-pcf50633.patch
-
----
- drivers/mfd/pcf50633-core.c | 16 +++--
- drivers/power/pcf50633-charger.c | 121 ++++++++++++++++++++++++++++---
- drivers/regulator/pcf50633-regulator.c | 60 +++++++++++++---
- drivers/rtc/rtc-pcf50633.c | 12 +++-
- include/linux/mfd/pcf50633/core.h | 5 +-
- 5 files changed, 180 insertions(+), 34 deletions(-)
-
-diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
-index 8d3c38b..e81c967 100644
---- a/drivers/mfd/pcf50633-core.c
-+++ b/drivers/mfd/pcf50633-core.c
-@@ -15,6 +15,7 @@
- #include <linux/kernel.h>
- #include <linux/device.h>
- #include <linux/sysfs.h>
-+#include <linux/device.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/interrupt.h>
-@@ -345,6 +346,8 @@ static void pcf50633_irq_worker(struct work_struct *work)
- goto out;
- }
-
-+ pcf50633_reg_write(pcf, PCF50633_REG_OOCSHDWN, 0x04 ); /* defeat 8s death from lowsys on A5 */
-+
- /* We immediately read the usb and adapter status. We thus make sure
- * only of USBINS/USBREM IRQ handlers are called */
- if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
-@@ -482,13 +485,13 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
- }
-
- #ifdef CONFIG_PM
--static int pcf50633_suspend(struct device *dev, pm_message_t state)
-+static int pcf50633_suspend(struct i2c_client *client, pm_message_t state)
- {
- struct pcf50633 *pcf;
- int ret = 0, i;
- u8 res[5];
-
-- pcf = dev_get_drvdata(dev);
-+ pcf = i2c_get_clientdata(client);
-
- /* Make sure our interrupt handlers are not called
- * henceforth */
-@@ -523,12 +526,12 @@ out:
- return ret;
- }
-
--static int pcf50633_resume(struct device *dev)
-+static int pcf50633_resume(struct i2c_client *client)
- {
- struct pcf50633 *pcf;
- int ret;
-
-- pcf = dev_get_drvdata(dev);
-+ pcf = i2c_get_clientdata(client);
-
- /* Write the saved mask registers */
- ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
-@@ -625,6 +628,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
- }
-
- if (client->irq) {
-+ set_irq_handler(client->irq, handle_level_irq);
- ret = request_irq(client->irq, pcf50633_irq,
- IRQF_TRIGGER_LOW, "pcf50633", pcf);
-
-@@ -683,12 +687,12 @@ static struct i2c_device_id pcf50633_id_table[] = {
- static struct i2c_driver pcf50633_driver = {
- .driver = {
- .name = "pcf50633",
-- .suspend = pcf50633_suspend,
-- .resume = pcf50633_resume,
- },
- .id_table = pcf50633_id_table,
- .probe = pcf50633_probe,
- .remove = __devexit_p(pcf50633_remove),
-+ .suspend = pcf50633_suspend,
-+ .resume = pcf50633_resume,
- };
-
- static int __init pcf50633_init(void)
-diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
-index e8b278f..41fa421 100644
---- a/drivers/power/pcf50633-charger.c
-+++ b/drivers/power/pcf50633-charger.c
-@@ -36,6 +36,7 @@ struct pcf50633_mbc {
-
- struct power_supply usb;
- struct power_supply adapter;
-+ struct power_supply ac;
-
- struct delayed_work charging_restart_work;
- };
-@@ -47,16 +48,21 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
- u8 bits;
- int charging_start = 1;
- u8 mbcs2, chgmod;
-+ unsigned int mbcc5;
-
-- if (ma >= 1000)
-+ if (ma >= 1000) {
- bits = PCF50633_MBCC7_USB_1000mA;
-- else if (ma >= 500)
-+ ma = 1000;
-+ } else if (ma >= 500) {
- bits = PCF50633_MBCC7_USB_500mA;
-- else if (ma >= 100)
-+ ma = 500;
-+ } else if (ma >= 100) {
- bits = PCF50633_MBCC7_USB_100mA;
-- else {
-+ ma = 100;
-+ } else {
- bits = PCF50633_MBCC7_USB_SUSPEND;
- charging_start = 0;
-+ ma = 0;
- }
-
- ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
-@@ -66,7 +72,22 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
- else
- dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
-
-- /* Manual charging start */
-+ /*
-+ * We limit the charging current to be the USB current limit.
-+ * The reason is that on pcf50633, when it enters PMU Standby mode,
-+ * which it does when the device goes "off", the USB current limit
-+ * reverts to the variant default. In at least one common case, that
-+ * default is 500mA. By setting the charging current to be the same
-+ * as the USB limit we set here before PMU standby, we enforce it only
-+ * using the correct amount of current even when the USB current limit
-+ * gets reset to the wrong thing
-+ */
-+
-+ mbcc5 = (ma << 8) / mbc->pcf->pdata->chg_ref_current_ma;
-+ if (mbcc5 > 255)
-+ mbcc5 = 255;
-+ pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
-+
- mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
- chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
-
-@@ -81,7 +102,7 @@ int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
- PCF50633_MBCC1_RESUME, PCF50633_MBCC1_RESUME);
-
- mbc->usb_active = charging_start;
--
-+
- power_supply_changed(&mbc->usb);
-
- return ret;
-@@ -156,9 +177,44 @@ static ssize_t set_usblim(struct device *dev,
-
- static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim);
-
-+static ssize_t
-+show_chglim(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
-+ u8 mbcc5 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC5);
-+ unsigned int ma;
-+
-+ ma = (mbc->pcf->pdata->chg_ref_current_ma * mbcc5) >> 8;
-+
-+ return sprintf(buf, "%u\n", ma);
-+}
-+
-+static ssize_t set_chglim(struct device *dev,
-+ struct device_attribute *attr, const char *buf, size_t count)
-+{
-+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
-+ unsigned long ma;
-+ unsigned int mbcc5;
-+ int ret;
-+
-+ ret = strict_strtoul(buf, 10, &ma);
-+ if (ret)
-+ return -EINVAL;
-+
-+ mbcc5 = (ma << 8) / mbc->pcf->pdata->chg_ref_current_ma;
-+ if (mbcc5 > 255)
-+ mbcc5 = 255;
-+ pcf50633_reg_write(mbc->pcf, PCF50633_REG_MBCC5, mbcc5);
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(chg_curlim, S_IRUGO | S_IWUSR, show_chglim, set_chglim);
-+
- static struct attribute *pcf50633_mbc_sysfs_entries[] = {
- &dev_attr_chgmode.attr,
- &dev_attr_usb_curlim.attr,
-+ &dev_attr_chg_curlim.attr,
- NULL,
- };
-
-@@ -239,6 +295,7 @@ pcf50633_mbc_irq_handler(int irq, void *data)
-
- power_supply_changed(&mbc->usb);
- power_supply_changed(&mbc->adapter);
-+ power_supply_changed(&mbc->ac);
-
- if (mbc->pcf->pdata->mbc_event_callback)
- mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq);
-@@ -248,8 +305,7 @@ static int adapter_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
- {
-- struct pcf50633_mbc *mbc = container_of(psy,
-- struct pcf50633_mbc, adapter);
-+ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, adapter);
- int ret = 0;
-
- switch (psp) {
-@@ -269,10 +325,34 @@ static int usb_get_property(struct power_supply *psy,
- {
- struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
- int ret = 0;
-+ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
-+ PCF50633_MBCC7_USB_MASK;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
-- val->intval = mbc->usb_online;
-+ val->intval = mbc->usb_online &&
-+ (usblim <= PCF50633_MBCC7_USB_500mA);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-+ return ret;
-+}
-+
-+static int ac_get_property(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, ac);
-+ int ret = 0;
-+ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
-+ PCF50633_MBCC7_USB_MASK;
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_ONLINE:
-+ val->intval = mbc->usb_online &&
-+ (usblim == PCF50633_MBCC7_USB_1000mA);
- break;
- default:
- ret = -EINVAL;
-@@ -337,6 +417,17 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
- mbc->usb.supplied_to = mbc->pcf->pdata->batteries;
- mbc->usb.num_supplicants = mbc->pcf->pdata->num_batteries;
-
-+ mbc->ac.name = "ac";
-+ mbc->ac.type = POWER_SUPPLY_TYPE_MAINS;
-+ mbc->ac.properties = power_props;
-+ mbc->ac.num_properties = ARRAY_SIZE(power_props);
-+ mbc->ac.get_property = ac_get_property;
-+ mbc->ac.supplied_to = mbc->pcf->pdata->batteries;
-+ mbc->ac.num_supplicants = mbc->pcf->pdata->num_batteries;
-+
-+ INIT_DELAYED_WORK(&mbc->charging_restart_work,
-+ pcf50633_mbc_charging_restart);
-+
- ret = power_supply_register(&pdev->dev, &mbc->adapter);
- if (ret) {
- dev_err(mbc->pcf->dev, "failed to register adapter\n");
-@@ -352,9 +443,15 @@ static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
- return ret;
- }
-
-- INIT_DELAYED_WORK(&mbc->charging_restart_work,
-- pcf50633_mbc_charging_restart);
--
-+ ret = power_supply_register(&pdev->dev, &mbc->ac);
-+ if (ret) {
-+ dev_err(mbc->pcf->dev, "failed to register ac\n");
-+ power_supply_unregister(&mbc->adapter);
-+ power_supply_unregister(&mbc->usb);
-+ kfree(mbc);
-+ return ret;
-+ }
-+
- ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
- if (ret)
- dev_err(mbc->pcf->dev, "failed to create sysfs entries\n");
-diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
-index 8e14900..4809789 100644
---- a/drivers/regulator/pcf50633-regulator.c
-+++ b/drivers/regulator/pcf50633-regulator.c
-@@ -24,11 +24,12 @@
- #include <linux/mfd/pcf50633/core.h>
- #include <linux/mfd/pcf50633/pmic.h>
-
--#define PCF50633_REGULATOR(_name, _id) \
-+#define PCF50633_REGULATOR(_name, _id, _n) \
- { \
- .name = _name, \
- .id = _id, \
- .ops = &pcf50633_regulator_ops, \
-+ .n_voltages = _n, \
- .type = REGULATOR_VOLTAGE, \
- .owner = THIS_MODULE, \
- }
-@@ -193,6 +194,40 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
- return millivolts * 1000;
- }
-
-+static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
-+ unsigned int index)
-+{
-+ struct pcf50633 *pcf;
-+ int regulator_id, millivolts;
-+
-+ pcf = rdev_get_drvdata(rdev);;
-+
-+ regulator_id = rdev_get_id(rdev);
-+
-+ switch (regulator_id) {
-+ case PCF50633_REGULATOR_AUTO:
-+ millivolts = auto_voltage_value(index + 0x2f);
-+ break;
-+ case PCF50633_REGULATOR_DOWN1:
-+ case PCF50633_REGULATOR_DOWN2:
-+ millivolts = down_voltage_value(index);
-+ break;
-+ case PCF50633_REGULATOR_LDO1:
-+ case PCF50633_REGULATOR_LDO2:
-+ case PCF50633_REGULATOR_LDO3:
-+ case PCF50633_REGULATOR_LDO4:
-+ case PCF50633_REGULATOR_LDO5:
-+ case PCF50633_REGULATOR_LDO6:
-+ case PCF50633_REGULATOR_HCLDO:
-+ millivolts = ldo_voltage_value(index);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return millivolts * 1000;
-+}
-+
- static int pcf50633_regulator_enable(struct regulator_dev *rdev)
- {
- struct pcf50633 *pcf = rdev_get_drvdata(rdev);
-@@ -246,6 +281,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
- static struct regulator_ops pcf50633_regulator_ops = {
- .set_voltage = pcf50633_regulator_set_voltage,
- .get_voltage = pcf50633_regulator_get_voltage,
-+ .list_voltage = pcf50633_regulator_list_voltage,
- .enable = pcf50633_regulator_enable,
- .disable = pcf50633_regulator_disable,
- .is_enabled = pcf50633_regulator_is_enabled,
-@@ -253,27 +289,27 @@ static struct regulator_ops pcf50633_regulator_ops = {
-
- static struct regulator_desc regulators[] = {
- [PCF50633_REGULATOR_AUTO] =
-- PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO),
-+ PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 80),
- [PCF50633_REGULATOR_DOWN1] =
-- PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1),
-+ PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 95),
- [PCF50633_REGULATOR_DOWN2] =
-- PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2),
-+ PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 95),
- [PCF50633_REGULATOR_LDO1] =
-- PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1),
-+ PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 27),
- [PCF50633_REGULATOR_LDO2] =
-- PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2),
-+ PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 27),
- [PCF50633_REGULATOR_LDO3] =
-- PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3),
-+ PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 27),
- [PCF50633_REGULATOR_LDO4] =
-- PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4),
-+ PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 27),
- [PCF50633_REGULATOR_LDO5] =
-- PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5),
-+ PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 27),
- [PCF50633_REGULATOR_LDO6] =
-- PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6),
-+ PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 27),
- [PCF50633_REGULATOR_HCLDO] =
-- PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO),
-+ PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 26),
- [PCF50633_REGULATOR_MEMLDO] =
-- PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO),
-+ PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 27),
- };
-
- static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
-diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
-index f4dd87e..8669815 100644
---- a/drivers/rtc/rtc-pcf50633.c
-+++ b/drivers/rtc/rtc-pcf50633.c
-@@ -58,6 +58,7 @@ struct pcf50633_time {
- struct pcf50633_rtc {
- int alarm_enabled;
- int second_enabled;
-+ int alarm_pending;
-
- struct pcf50633 *pcf;
- struct rtc_device *rtc_dev;
-@@ -70,7 +71,7 @@ static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf)
- rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]);
- rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]);
- rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]);
-- rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]);
-+ rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]) - 1;
- rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100;
- }
-
-@@ -81,7 +82,7 @@ static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc)
- pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour);
- pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday);
- pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday);
-- pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon);
-+ pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon + 1);
- pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100);
- }
-
-@@ -209,6 +210,7 @@ static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
- rtc = dev_get_drvdata(dev);
-
- alrm->enabled = rtc->alarm_enabled;
-+ alrm->pending = rtc->alarm_pending;
-
- ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA,
- PCF50633_TI_EXTENT, &pcf_tm.time[0]);
-@@ -244,9 +246,12 @@ static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
- /* Returns 0 on success */
- ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
- PCF50633_TI_EXTENT, &pcf_tm.time[0]);
-+ if (!alrm->enabled)
-+ rtc->alarm_pending = 0;
-
-- if (!alarm_masked)
-+ if (!alarm_masked || alrm->enabled)
- pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
-+ rtc->alarm_enabled = alrm->enabled;
-
- return ret;
- }
-@@ -267,6 +272,7 @@ static void pcf50633_rtc_irq(int irq, void *data)
- switch (irq) {
- case PCF50633_IRQ_ALARM:
- rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
-+ rtc->alarm_pending = 1;
- break;
- case PCF50633_IRQ_SECOND:
- rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
-diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
-index c8f51c3..af67b4e 100644
---- a/include/linux/mfd/pcf50633/core.h
-+++ b/include/linux/mfd/pcf50633/core.h
-@@ -31,6 +31,8 @@ struct pcf50633_platform_data {
-
- int charging_restart_interval;
-
-+ int chg_ref_current_ma;
-+
- /* Callbacks */
- void (*probe_done)(struct pcf50633 *);
- void (*mbc_event_callback)(struct pcf50633 *, int);
-@@ -208,7 +210,8 @@ enum pcf50633_reg_int5 {
- };
-
- /* misc. registers */
--#define PCF50633_REG_OOCSHDWN 0x0c
-+#define PCF50633_REG_OOCSHDWN 0x0c
-+#define PCF50633_OOCSHDWN_GOSTDBY 0x01
-
- /* LED registers */
- #define PCF50633_REG_LEDOUT 0x28
---
-1.5.6.5
-