diff options
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.patch | 487 |
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 31432151ce..0000000000 --- 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 - |