s3c2442: R.I.P.
[openwrt.git] / target / linux / s3c24xx / patches-2.6.30 / 056-pcf50633.patch
diff --git a/target/linux/s3c24xx/patches-2.6.30/056-pcf50633.patch b/target/linux/s3c24xx/patches-2.6.30/056-pcf50633.patch
deleted file mode 100644 (file)
index dcd8d3a..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
---- 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 w
-               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 pcf5
- }
- #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(stru
-       }
-       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_
- 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)
---- 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 p
-       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 p
-       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 p
-                               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 
- 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 *
-       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 p
-                       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
- {
-       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(
-       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(
-               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");
---- 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->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
-       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(struc
-       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
-       /* 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, vo
-       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);
---- 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
---- 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_voltag
-       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
- 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_reg
- 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)