mfd: sec-core: Add support for S2MPS14
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>
Thu, 10 Jul 2014 08:20:45 +0000 (17:20 +0900)
committerChanho Park <chanho61.park@samsung.com>
Thu, 7 Aug 2014 06:17:48 +0000 (15:17 +0900)
Add support for S2MPS14 PMIC device to the MFD sec-core driver.
The S2MPS14 is similar to S2MPS11 but it has fewer regulators, two
clocks instead of three and a little different registers layout.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
drivers/mfd/sec-core.c
drivers/mfd/sec-irq.c
include/linux/mfd/samsung/core.h
include/linux/mfd/samsung/irq.h
include/linux/mfd/samsung/rtc.h
include/linux/mfd/samsung/s2mps11.h
include/linux/mfd/samsung/s2mps14.h [new file with mode: 0644]
include/linux/mfd/samsung/s5m8767.h

index 81cfe88..b281ddc 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/rtc.h>
+#include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s2mps14.h>
+#include <linux/mfd/samsung/s5m8763.h>
+#include <linux/mfd/samsung/s5m8767.h>
 #include <linux/regmap.h>
 
 static struct mfd_cell s5m8751_devs[] = {
@@ -52,13 +57,31 @@ static struct mfd_cell s5m8767_devs[] = {
                .name = "s5m8767-pmic",
        }, {
                .name = "s5m-rtc",
-       },
+               .of_compatible = "samsung,s5m8767-rtc",
+       }, {
+               .name = "s5m8767-clk",
+               .of_compatible = "samsung,s5m8767-clk",
+       }
 };
 
 static struct mfd_cell s2mps11_devs[] = {
        {
                .name = "s2mps11-pmic",
-       },
+       }, {
+               .name = "s2mps11-clk",
+       }
+};
+
+static struct mfd_cell s2mps14_devs[] = {
+       {
+               .name = "s2mps14-pmic",
+       }, {
+               .name = "s2mps14-rtc",
+               .of_compatible = "samsung,s2mps14-rtc",
+       }, {
+               .name = "s2mps14-clk",
+               .of_compatible = "samsung,s2mps14-clk",
+       }
 };
 
 #ifdef CONFIG_OF
@@ -66,45 +89,129 @@ static struct of_device_id sec_dt_match[] = {
        {       .compatible = "samsung,s5m8767-pmic",
                .data = (void *)S5M8767X,
        },
+       {       .compatible = "samsung,s2mps11-pmic",
+               .data = (void *)S2MPS11X,
+       },
+       {       .compatible = "samsung,s2mps14-pmic",
+               .data = (void *)S2MPS14X,
+       },
        {},
 };
 #endif
 
-int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest)
+int sec_reg_read(struct regmap *map, u8 reg, u8 *dest)
 {
-       return regmap_read(sec_pmic->regmap, reg, dest);
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(map, reg, &val);
+       *dest = val;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(sec_reg_read);
 
-int sec_bulk_read(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
+int sec_bulk_read(struct regmap *map, u8 reg, u8 *buf, int count)
 {
-       return regmap_bulk_read(sec_pmic->regmap, reg, buf, count);
+       return regmap_bulk_read(map, reg, buf, count);
 }
 EXPORT_SYMBOL_GPL(sec_bulk_read);
 
-int sec_reg_write(struct sec_pmic_dev *sec_pmic, u8 reg, u8 value)
+int sec_reg_write(struct regmap *map, u8 reg, u8 value)
 {
-       return regmap_write(sec_pmic->regmap, reg, value);
+       return regmap_write(map, reg, value);
 }
 EXPORT_SYMBOL_GPL(sec_reg_write);
 
-int sec_bulk_write(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
+int sec_bulk_write(struct regmap *map, u8 reg, u8 *buf, int count)
 {
-       return regmap_raw_write(sec_pmic->regmap, reg, buf, count);
+       return regmap_bulk_write(map, reg, buf, count);
 }
 EXPORT_SYMBOL_GPL(sec_bulk_write);
 
-int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask)
+int sec_reg_update(struct regmap *map, u8 reg, u8 mask, u8 val)
 {
-       return regmap_update_bits(sec_pmic->regmap, reg, mask, val);
+       return regmap_update_bits(map, reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(sec_reg_update);
 
-static struct regmap_config sec_regmap_config = {
+static bool s2mps11_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S2MPS11_REG_INT1M:
+       case S2MPS11_REG_INT2M:
+       case S2MPS11_REG_INT3M:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static bool s5m8763_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case S5M8763_REG_IRQM1:
+       case S5M8763_REG_IRQM2:
+       case S5M8763_REG_IRQM3:
+       case S5M8763_REG_IRQM4:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static const struct regmap_config sec_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static const struct regmap_config s5m_rtc_regmap_config = {
        .reg_bits = 8,
        .val_bits = 8,
+       .max_register = S5M_RTC_REG_MAX,
 };
 
+static const struct regmap_config s2mps14_rtc_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = S2MPS_RTC_REG_MAX,
+};
+
+static const struct regmap_config s2mps11_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS11_REG_L38CTRL,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s2mps14_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S2MPS14_REG_LDODSCH3,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s5m8763_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S5M8763_REG_LBCNFG2,
+       .volatile_reg = s5m8763_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
+
+static const struct regmap_config s5m8767_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = S5M8767_REG_LDO28CTRL,
+       .volatile_reg = s2mps11_volatile,
+       .cache_type = REGCACHE_FLAT,
+};
 
 #ifdef CONFIG_OF
 /*
@@ -119,6 +226,7 @@ static struct regmap_config sec_regmap_config = {
 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
                                        struct device *dev)
 {
+       struct device_node *np = dev->of_node;
        struct sec_platform_data *pd;
 
        pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
@@ -133,13 +241,16 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
         * not parsed here.
         */
 
+       if (of_property_read_bool(np, "wakeup"))
+               pd->wakeup = true;
+
        return pd;
 }
 #else
 static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
                                        struct device *dev)
 {
-       return 0;
+       return NULL;
 }
 #endif
 
@@ -160,6 +271,7 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct sec_platform_data *pdata = i2c->dev.platform_data;
+       const struct regmap_config *regmap, *regmap_rtc;
        struct sec_pmic_dev *sec_pmic;
        int ret;
 
@@ -190,21 +302,53 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                sec_pmic->pdata = pdata;
        }
 
-       sec_pmic->regmap = devm_regmap_init_i2c(i2c, &sec_regmap_config);
-       if (IS_ERR(sec_pmic->regmap)) {
-               ret = PTR_ERR(sec_pmic->regmap);
+       switch (sec_pmic->device_type) {
+       case S2MPS11X:
+               regmap = &s2mps11_regmap_config;
+               regmap_rtc = NULL; /* No RTC mfd_cell for S2MPS11 */
+               break;
+       case S2MPS14X:
+               regmap = &s2mps14_regmap_config;
+               regmap_rtc = &s2mps14_rtc_regmap_config;
+               break;
+       case S5M8763X:
+               regmap = &s5m8763_regmap_config;
+               regmap_rtc = &s5m_rtc_regmap_config;
+               break;
+       case S5M8767X:
+               regmap = &s5m8767_regmap_config;
+               regmap_rtc = &s5m_rtc_regmap_config;
+               break;
+       default:
+               regmap = &sec_regmap_config;
+               regmap_rtc = &s5m_rtc_regmap_config;
+               break;
+       }
+
+       sec_pmic->regmap_pmic = devm_regmap_init_i2c(i2c, regmap);
+       if (IS_ERR(sec_pmic->regmap_pmic)) {
+               ret = PTR_ERR(sec_pmic->regmap_pmic);
                dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
                        ret);
                return ret;
        }
 
        sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
-       if (!sec_pmic->rtc) {
-               dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n");
-               return -ENODEV;
+       if (IS_ERR_OR_NULL(sec_pmic->rtc)) {
+               ret = PTR_ERR(sec_pmic->rtc);
+               dev_err(&i2c->dev, "Failed to allocate i2c : %d\n", ret);
+               return ret;
        }
        i2c_set_clientdata(sec_pmic->rtc, sec_pmic);
 
+       sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, regmap_rtc);
+       if (IS_ERR_OR_NULL(sec_pmic->regmap_rtc)) {
+               ret = PTR_ERR(sec_pmic->regmap_rtc);
+               dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n",
+                       ret);
+               return ret;
+       }
+
        if (pdata && pdata->cfg_pmic_irq)
                pdata->cfg_pmic_irq();
 
@@ -229,18 +373,23 @@ static int sec_pmic_probe(struct i2c_client *i2c,
                ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs,
                                      ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL);
                break;
+       case S2MPS14X:
+               ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs,
+                                     ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL);
+               break;
        default:
                /* If this happens the probe function is problem */
                BUG();
        }
 
-       if (ret < 0)
+       if (ret)
                goto err;
 
+       device_init_wakeup(sec_pmic->dev, pdata->wakeup);
+
        return ret;
 
 err:
-       mfd_remove_devices(sec_pmic->dev);
        sec_irq_exit(sec_pmic);
        i2c_unregister_device(sec_pmic->rtc);
        return ret;
@@ -256,6 +405,32 @@ static int sec_pmic_remove(struct i2c_client *i2c)
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int sec_pmic_suspend(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev))
+               enable_irq_wake(sec_pmic->irq);
+
+       return 0;
+}
+
+static int sec_pmic_resume(struct device *dev)
+{
+       struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
+       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+
+       if (device_may_wakeup(dev))
+               disable_irq_wake(sec_pmic->irq);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume);
+
 static const struct i2c_device_id sec_pmic_id[] = {
        { "sec_pmic", 0 },
        { }
@@ -266,6 +441,7 @@ static struct i2c_driver sec_pmic_driver = {
        .driver = {
                   .name = "sec_pmic",
                   .owner = THIS_MODULE,
+                  .pm = &sec_pmic_pm_ops,
                   .of_match_table = of_match_ptr(sec_dt_match),
        },
        .probe = sec_pmic_probe,
index 0dd84e9..2243520 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sec-irq.c
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
  *              http://www.samsung.com
  *
  *  This program is free software; you can redistribute  it and/or modify it
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/regmap.h>
+#include <linux/irqdomain.h>
 
 #include <linux/mfd/samsung/core.h>
 #include <linux/mfd/samsung/irq.h>
 #include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s2mps14.h>
 #include <linux/mfd/samsung/s5m8763.h>
 #include <linux/mfd/samsung/s5m8767.h>
 
-static struct regmap_irq s2mps11_irqs[] = {
+static const struct regmap_irq s2mps11_irqs[] = {
        [S2MPS11_IRQ_PWRONF] = {
                .reg_offset = 0,
                .mask = S2MPS11_IRQ_PWRONF_MASK,
@@ -59,13 +61,13 @@ static struct regmap_irq s2mps11_irqs[] = {
                .reg_offset = 1,
                .mask = S2MPS11_IRQ_RTC60S_MASK,
        },
-       [S2MPS11_IRQ_RTCA1] = {
+       [S2MPS11_IRQ_RTCA0] = {
                .reg_offset = 1,
-               .mask = S2MPS11_IRQ_RTCA1_MASK,
+               .mask = S2MPS11_IRQ_RTCA0_MASK,
        },
-       [S2MPS11_IRQ_RTCA2] = {
+       [S2MPS11_IRQ_RTCA1] = {
                .reg_offset = 1,
-               .mask = S2MPS11_IRQ_RTCA2_MASK,
+               .mask = S2MPS11_IRQ_RTCA1_MASK,
        },
        [S2MPS11_IRQ_SMPL] = {
                .reg_offset = 1,
@@ -89,8 +91,78 @@ static struct regmap_irq s2mps11_irqs[] = {
        },
 };
 
+static const struct regmap_irq s2mps14_irqs[] = {
+       [S2MPS14_IRQ_PWRONF] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_PWRONF_MASK,
+       },
+       [S2MPS14_IRQ_PWRONR] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_PWRONR_MASK,
+       },
+       [S2MPS14_IRQ_JIGONBF] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_JIGONBF_MASK,
+       },
+       [S2MPS14_IRQ_JIGONBR] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_JIGONBR_MASK,
+       },
+       [S2MPS14_IRQ_ACOKBF] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_ACOKBF_MASK,
+       },
+       [S2MPS14_IRQ_ACOKBR] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_ACOKBR_MASK,
+       },
+       [S2MPS14_IRQ_PWRON1S] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_PWRON1S_MASK,
+       },
+       [S2MPS14_IRQ_MRB] = {
+               .reg_offset = 0,
+               .mask = S2MPS11_IRQ_MRB_MASK,
+       },
+       [S2MPS14_IRQ_RTC60S] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTC60S_MASK,
+       },
+       [S2MPS14_IRQ_RTCA1] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTCA1_MASK,
+       },
+       [S2MPS14_IRQ_RTCA0] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTCA0_MASK,
+       },
+       [S2MPS14_IRQ_SMPL] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_SMPL_MASK,
+       },
+       [S2MPS14_IRQ_RTC1S] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_RTC1S_MASK,
+       },
+       [S2MPS14_IRQ_WTSR] = {
+               .reg_offset = 1,
+               .mask = S2MPS11_IRQ_WTSR_MASK,
+       },
+       [S2MPS14_IRQ_INT120C] = {
+               .reg_offset = 2,
+               .mask = S2MPS11_IRQ_INT120C_MASK,
+       },
+       [S2MPS14_IRQ_INT140C] = {
+               .reg_offset = 2,
+               .mask = S2MPS11_IRQ_INT140C_MASK,
+       },
+       [S2MPS14_IRQ_TSD] = {
+               .reg_offset = 2,
+               .mask = S2MPS14_IRQ_TSD_MASK,
+       },
+};
 
-static struct regmap_irq s5m8767_irqs[] = {
+static const struct regmap_irq s5m8767_irqs[] = {
        [S5M8767_IRQ_PWRR] = {
                .reg_offset = 0,
                .mask = S5M8767_IRQ_PWRR_MASK,
@@ -161,7 +233,7 @@ static struct regmap_irq s5m8767_irqs[] = {
        },
 };
 
-static struct regmap_irq s5m8763_irqs[] = {
+static const struct regmap_irq s5m8763_irqs[] = {
        [S5M8763_IRQ_DCINF] = {
                .reg_offset = 0,
                .mask = S5M8763_IRQ_DCINF_MASK,
@@ -236,7 +308,7 @@ static struct regmap_irq s5m8763_irqs[] = {
        },
 };
 
-static struct regmap_irq_chip s2mps11_irq_chip = {
+static const struct regmap_irq_chip s2mps11_irq_chip = {
        .name = "s2mps11",
        .irqs = s2mps11_irqs,
        .num_irqs = ARRAY_SIZE(s2mps11_irqs),
@@ -246,7 +318,17 @@ static struct regmap_irq_chip s2mps11_irq_chip = {
        .ack_base = S2MPS11_REG_INT1,
 };
 
-static struct regmap_irq_chip s5m8767_irq_chip = {
+static const struct regmap_irq_chip s2mps14_irq_chip = {
+       .name = "s2mps14",
+       .irqs = s2mps14_irqs,
+       .num_irqs = ARRAY_SIZE(s2mps14_irqs),
+       .num_regs = 3,
+       .status_base = S2MPS14_REG_INT1,
+       .mask_base = S2MPS14_REG_INT1M,
+       .ack_base = S2MPS14_REG_INT1,
+};
+
+static const struct regmap_irq_chip s5m8767_irq_chip = {
        .name = "s5m8767",
        .irqs = s5m8767_irqs,
        .num_irqs = ARRAY_SIZE(s5m8767_irqs),
@@ -256,7 +338,7 @@ static struct regmap_irq_chip s5m8767_irq_chip = {
        .ack_base = S5M8767_REG_INT1,
 };
 
-static struct regmap_irq_chip s5m8763_irq_chip = {
+static const struct regmap_irq_chip s5m8763_irq_chip = {
        .name = "s5m8763",
        .irqs = s5m8763_irqs,
        .num_irqs = ARRAY_SIZE(s5m8763_irqs),
@@ -266,8 +348,71 @@ static struct regmap_irq_chip s5m8763_irq_chip = {
        .ack_base = S5M8763_REG_IRQ1,
 };
 
+static irqreturn_t sec_pmic_irq_thread(int irq, void *data)
+{
+       struct sec_pmic_dev *sec_pmic = data;
+
+       handle_nested_irq(irq_create_mapping(sec_pmic->domain, 0));
+
+       return IRQ_HANDLED;
+}
+
+static void sec_pmic_irq_enable(struct irq_data *data)
+{
+}
+
+static void sec_pmic_irq_disable(struct irq_data *data)
+{
+}
+
+static int sec_pmic_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+       struct sec_pmic_dev *sec_pmic = irq_data_get_irq_chip_data(data);
+       int ret;
+
+       /*
+        * PMIC has only one hardware interrupt, so do not even bother looking
+        * at data->irq/hwirq.
+        */
+       ret = irq_set_irq_wake(sec_pmic->irq, on);
+
+       return ret;
+}
+
+static struct irq_chip sec_pmic_irq_chip = {
+       .name                   = "sec_pmic_irq",
+       .irq_disable            = sec_pmic_irq_disable,
+       .irq_enable             = sec_pmic_irq_enable,
+       .irq_set_wake           = sec_pmic_irq_set_wake,
+};
+
+static int sec_pmic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+                               irq_hw_number_t hw)
+{
+       struct sec_pmic_dev *sec_pmic = d->host_data;
+
+       irq_set_chip_data(irq, sec_pmic);
+       irq_set_chip_and_handler(irq, &sec_pmic_irq_chip, handle_edge_irq);
+       irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+       set_irq_flags(irq, IRQF_VALID);
+#else
+       irq_set_noprobe(irq);
+#endif
+       return 0;
+}
+
+static struct irq_domain_ops sec_pmic_irq_domain_ops = {
+       .map = sec_pmic_irq_domain_map,
+};
+
 int sec_irq_init(struct sec_pmic_dev *sec_pmic)
 {
+       struct sec_platform_data *pdata = sec_pmic->pdata;
+       const struct regmap_irq_chip *irq_chip;
+       unsigned int irq_nr;
+       unsigned int irqflags;
+       char *irq_name;
        int ret = 0;
        int type = sec_pmic->device_type;
 
@@ -280,22 +425,24 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
 
        switch (type) {
        case S5M8763X:
-               ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
-                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                 sec_pmic->irq_base, &s5m8763_irq_chip,
-                                 &sec_pmic->irq_data);
+               irq_chip = &s5m8763_irq_chip;
+               irq_nr = S5M8763_IRQ_NR;
+               irq_name = "s5m8763-irq";
                break;
        case S5M8767X:
-               ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
-                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                 sec_pmic->irq_base, &s5m8767_irq_chip,
-                                 &sec_pmic->irq_data);
+               irq_chip = &s5m8767_irq_chip,
+               irq_nr = S5M8767_IRQ_NR;
+               irq_name = "s5m8767-irq";
                break;
        case S2MPS11X:
-               ret = regmap_add_irq_chip(sec_pmic->regmap, sec_pmic->irq,
-                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                 sec_pmic->irq_base, &s2mps11_irq_chip,
-                                 &sec_pmic->irq_data);
+               irq_chip = &s2mps11_irq_chip,
+               irq_nr = S2MPS11_IRQ_NR;
+               irq_name = "s2mps11-irq";
+               break;
+       case S2MPS14X:
+               irq_chip = &s2mps14_irq_chip,
+               irq_nr = S2MPS14_IRQ_NR;
+               irq_name = "s2mps14-irq";
                break;
        default:
                dev_err(sec_pmic->dev, "Unknown device type %d\n",
@@ -303,15 +450,61 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
                return -EINVAL;
        }
 
-       if (ret != 0) {
-               dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
-               return ret;
+       /* default irq flags */
+       irqflags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+       if (pdata->irqflags)
+               irqflags = pdata->irqflags;
+       else
+               pdata->irqflags = irqflags;
+
+       if (irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+               sec_pmic->domain = irq_domain_add_linear(NULL, irq_nr,
+                                       &sec_pmic_irq_domain_ops, sec_pmic);
+               if (!sec_pmic->domain) {
+                       dev_err(sec_pmic->dev, "Failed to create irq domain\n");
+                       return -ENODEV;
+               }
+
+               ret = regmap_add_irq_chip(sec_pmic->regmap_pmic,
+                                 irq_create_mapping(sec_pmic->domain, 0),
+                                 irqflags, sec_pmic->irq_base, irq_chip,
+                                 &sec_pmic->irq_data);
+               if (ret != 0) {
+                       dev_err(sec_pmic->dev,
+                               "Failed to register IRQ chip: %d\n", ret);
+                       return ret;
+               }
+
+               ret = request_threaded_irq(sec_pmic->irq,
+                                  NULL, sec_pmic_irq_thread,
+                                  irqflags, irq_name, sec_pmic);
+               if (ret != 0) {
+                       dev_err(sec_pmic->dev,
+                               "Failed to request interrupt: %d\n", ret);
+                       goto err;
+               }
+       } else {
+               ret = regmap_add_irq_chip(sec_pmic->regmap_pmic,
+                                 sec_pmic->irq,
+                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                 sec_pmic->irq_base, irq_chip,
+                                 &sec_pmic->irq_data);
+               if (ret != 0) {
+                       dev_err(sec_pmic->dev,
+                               "Failed to register IRQ chip: %d\n", ret);
+                       return ret;
+               }
        }
 
        return 0;
+err:
+       regmap_del_irq_chip(irq_create_mapping(sec_pmic->domain, 0),
+                           sec_pmic->irq_data);
+
+       return ret;
 }
 
 void sec_irq_exit(struct sec_pmic_dev *sec_pmic)
 {
-       regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data);
+       /* regmap_del_irq_chip(sec_pmic->irq, sec_pmic->irq_data); */
 }
index f0f4de3..1f5f5f0 100644 (file)
@@ -21,6 +21,7 @@ enum sec_device_type {
        S5M8763X,
        S5M8767X,
        S2MPS11X,
+       S2MPS14X,
 };
 
 /**
@@ -41,7 +42,8 @@ enum sec_device_type {
 struct sec_pmic_dev {
        struct device *dev;
        struct sec_platform_data *pdata;
-       struct regmap *regmap;
+       struct regmap *regmap_pmic;
+       struct regmap *regmap_rtc;
        struct i2c_client *i2c;
        struct i2c_client *rtc;
        struct mutex iolock;
@@ -51,6 +53,7 @@ struct sec_pmic_dev {
        int irq_base;
        int irq;
        struct regmap_irq_chip_data *irq_data;
+       struct irq_domain *domain;
 
        int ono;
        u8 irq_masks_cur[NUM_IRQ_REGS];
@@ -63,11 +66,18 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic);
 void sec_irq_exit(struct sec_pmic_dev *sec_pmic);
 int sec_irq_resume(struct sec_pmic_dev *sec_pmic);
 
-extern int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest);
-extern int sec_bulk_read(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf);
-extern int sec_reg_write(struct sec_pmic_dev *sec_pmic, u8 reg, u8 value);
-extern int sec_bulk_write(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf);
-extern int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask);
+extern int sec_reg_read(struct regmap *map, u8 reg, u8 *dest);
+extern int sec_bulk_read(struct regmap *map, u8 reg, u8 *buf, int count);
+extern int sec_reg_write(struct regmap *map, u8 reg, u8 value);
+extern int sec_bulk_write(struct regmap *map, u8 reg, u8 *buf, int count);
+extern int sec_reg_update(struct regmap *map, u8 reg, u8 mask, u8 val);
+
+struct sec_wtsr_smpl {
+       bool wtsr_en;
+       bool smpl_en;
+       int wtsr_time;
+       int smpl_time;
+};
 
 struct sec_platform_data {
        struct sec_regulator_data       *regulators;
@@ -77,6 +87,7 @@ struct sec_platform_data {
 
        int                             irq_base;
        int                             (*cfg_pmic_irq)(void);
+       unsigned int                    irqflags;
 
        int                             ono;
        bool                            wakeup;
@@ -90,6 +101,8 @@ struct sec_platform_data {
        bool                            buck3_gpiodvs;
        unsigned int                    buck4_voltage[8];
        bool                            buck4_gpiodvs;
+       int                             buck9_gpio;
+       bool                            buck9_uses_gpio;
 
        int                             buck_set1;
        int                             buck_set2;
@@ -116,6 +129,8 @@ struct sec_platform_data {
        bool                            buck4_ramp_enable;
        bool                            buck6_ramp_enable;
 
+       struct sec_wtsr_smpl            *wtsr_smpl;
+
        int                             buck2_init;
        int                             buck3_init;
        int                             buck4_init;
index d43b4f9..0065f6f 100644 (file)
@@ -24,8 +24,8 @@ enum s2mps11_irq {
        S2MPS11_IRQ_MRB,
 
        S2MPS11_IRQ_RTC60S,
+       S2MPS11_IRQ_RTCA0,
        S2MPS11_IRQ_RTCA1,
-       S2MPS11_IRQ_RTCA2,
        S2MPS11_IRQ_SMPL,
        S2MPS11_IRQ_RTC1S,
        S2MPS11_IRQ_WTSR,
@@ -47,7 +47,7 @@ enum s2mps11_irq {
 
 #define S2MPS11_IRQ_RTC60S_MASK                (1 << 0)
 #define S2MPS11_IRQ_RTCA1_MASK         (1 << 1)
-#define S2MPS11_IRQ_RTCA2_MASK         (1 << 2)
+#define S2MPS11_IRQ_RTCA0_MASK         (1 << 2)
 #define S2MPS11_IRQ_SMPL_MASK          (1 << 3)
 #define S2MPS11_IRQ_RTC1S_MASK         (1 << 4)
 #define S2MPS11_IRQ_WTSR_MASK          (1 << 5)
@@ -55,6 +55,33 @@ enum s2mps11_irq {
 #define S2MPS11_IRQ_INT120C_MASK       (1 << 0)
 #define S2MPS11_IRQ_INT140C_MASK       (1 << 1)
 
+enum s2mps14_irq {
+       S2MPS14_IRQ_PWRONF,
+       S2MPS14_IRQ_PWRONR,
+       S2MPS14_IRQ_JIGONBF,
+       S2MPS14_IRQ_JIGONBR,
+       S2MPS14_IRQ_ACOKBF,
+       S2MPS14_IRQ_ACOKBR,
+       S2MPS14_IRQ_PWRON1S,
+       S2MPS14_IRQ_MRB,
+
+       S2MPS14_IRQ_RTC60S,
+       S2MPS14_IRQ_RTCA1,
+       S2MPS14_IRQ_RTCA0,
+       S2MPS14_IRQ_SMPL,
+       S2MPS14_IRQ_RTC1S,
+       S2MPS14_IRQ_WTSR,
+
+       S2MPS14_IRQ_INT120C,
+       S2MPS14_IRQ_INT140C,
+       S2MPS14_IRQ_TSD,
+
+       S2MPS14_IRQ_NR,
+};
+
+/* Masks for interrupts are the same as in s2mps11 */
+#define S2MPS14_IRQ_TSD_MASK           (1 << 2)
+
 enum s5m8767_irq {
        S5M8767_IRQ_PWRR,
        S5M8767_IRQ_PWRF,
index 71597e2..270236d 100644 (file)
@@ -1,48 +1,86 @@
-/*  rtc.h
+/* rtc.h
  *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
  *              http://www.samsung.com
  *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
  */
 
-#ifndef __LINUX_MFD_SEC_RTC_H
-#define __LINUX_MFD_SEC_RTC_H
+#ifndef __LINUX_MFD_S5M_RTC_H
+#define __LINUX_MFD_S5M_RTC_H
+
+enum s5m_rtc_reg {
+       S5M_RTC_SEC,
+       S5M_RTC_MIN,
+       S5M_RTC_HOUR,
+       S5M_RTC_WEEKDAY,
+       S5M_RTC_DATE,
+       S5M_RTC_MONTH,
+       S5M_RTC_YEAR1,
+       S5M_RTC_YEAR2,
+       S5M_ALARM0_SEC,
+       S5M_ALARM0_MIN,
+       S5M_ALARM0_HOUR,
+       S5M_ALARM0_WEEKDAY,
+       S5M_ALARM0_DATE,
+       S5M_ALARM0_MONTH,
+       S5M_ALARM0_YEAR1,
+       S5M_ALARM0_YEAR2,
+       S5M_ALARM1_SEC,
+       S5M_ALARM1_MIN,
+       S5M_ALARM1_HOUR,
+       S5M_ALARM1_WEEKDAY,
+       S5M_ALARM1_DATE,
+       S5M_ALARM1_MONTH,
+       S5M_ALARM1_YEAR1,
+       S5M_ALARM1_YEAR2,
+       S5M_ALARM0_CONF,
+       S5M_ALARM1_CONF,
+       S5M_RTC_STATUS,
+       S5M_WTSR_SMPL_CNTL,
+       S5M_RTC_UDR_CON,
+
+       S5M_RTC_REG_MAX,
+};
+
+enum s2mps_rtc_reg {
+       S2MPS_RTC_CTRL,
+       S2MPS_WTSR_SMPL_CNTL,
+       S2MPS_RTC_UDR_CON,
+       S2MPS_RSVD,
+       S2MPS_RTC_SEC,
+       S2MPS_RTC_MIN,
+       S2MPS_RTC_HOUR,
+       S2MPS_RTC_WEEKDAY,
+       S2MPS_RTC_DATE,
+       S2MPS_RTC_MONTH,
+       S2MPS_RTC_YEAR,
+       S2MPS_ALARM0_SEC,
+       S2MPS_ALARM0_MIN,
+       S2MPS_ALARM0_HOUR,
+       S2MPS_ALARM0_WEEKDAY,
+       S2MPS_ALARM0_DATE,
+       S2MPS_ALARM0_MONTH,
+       S2MPS_ALARM0_YEAR,
+       S2MPS_ALARM1_SEC,
+       S2MPS_ALARM1_MIN,
+       S2MPS_ALARM1_HOUR,
+       S2MPS_ALARM1_WEEKDAY,
+       S2MPS_ALARM1_DATE,
+       S2MPS_ALARM1_MONTH,
+       S2MPS_ALARM1_YEAR,
+       S2MPS_OFFSRC,
 
-enum sec_rtc_reg {
-       SEC_RTC_SEC,
-       SEC_RTC_MIN,
-       SEC_RTC_HOUR,
-       SEC_RTC_WEEKDAY,
-       SEC_RTC_DATE,
-       SEC_RTC_MONTH,
-       SEC_RTC_YEAR1,
-       SEC_RTC_YEAR2,
-       SEC_ALARM0_SEC,
-       SEC_ALARM0_MIN,
-       SEC_ALARM0_HOUR,
-       SEC_ALARM0_WEEKDAY,
-       SEC_ALARM0_DATE,
-       SEC_ALARM0_MONTH,
-       SEC_ALARM0_YEAR1,
-       SEC_ALARM0_YEAR2,
-       SEC_ALARM1_SEC,
-       SEC_ALARM1_MIN,
-       SEC_ALARM1_HOUR,
-       SEC_ALARM1_WEEKDAY,
-       SEC_ALARM1_DATE,
-       SEC_ALARM1_MONTH,
-       SEC_ALARM1_YEAR1,
-       SEC_ALARM1_YEAR2,
-       SEC_ALARM0_CONF,
-       SEC_ALARM1_CONF,
-       SEC_RTC_STATUS,
-       SEC_WTSR_SMPL_CNTL,
-       SEC_RTC_UDR_CON,
+       S2MPS_RTC_REG_MAX,
 };
 
 #define RTC_I2C_ADDR           (0x0C >> 1)
@@ -50,9 +88,13 @@ enum sec_rtc_reg {
 #define HOUR_12                        (1 << 7)
 #define HOUR_AMPM              (1 << 6)
 #define HOUR_PM                        (1 << 5)
-#define ALARM0_STATUS          (1 << 1)
-#define ALARM1_STATUS          (1 << 2)
-#define UPDATE_AD              (1 << 0)
+
+#define S5M_ALARM0_STATUS      (1 << 1)
+#define S5M_ALARM1_STATUS      (1 << 2)
+#define S5M_UPDATE_AD          (1 << 0)
+
+#define S2MPS_ALARM0_STATUS    (1 << 2)
+#define S2MPS_ALARM1_STATUS    (1 << 1)
 
 /* RTC Control Register */
 #define BCD_EN_SHIFT           0
@@ -60,15 +102,34 @@ enum sec_rtc_reg {
 #define MODEL24_SHIFT          1
 #define MODEL24_MASK           (1 << MODEL24_SHIFT)
 /* RTC Update Register1 */
-#define RTC_UDR_SHIFT          0
-#define RTC_UDR_MASK           (1 << RTC_UDR_SHIFT)
+#define S5M_RTC_UDR_SHIFT      0
+#define S5M_RTC_UDR_MASK       (1 << S5M_RTC_UDR_SHIFT)
+#define S2MPS_RTC_WUDR_SHIFT   4
+#define S2MPS_RTC_WUDR_MASK    (1 << S2MPS_RTC_WUDR_SHIFT)
+#define S2MPS_RTC_RUDR_SHIFT   0
+#define S2MPS_RTC_RUDR_MASK    (1 << S2MPS_RTC_RUDR_SHIFT)
 /* RTC Hour register */
 #define HOUR_PM_SHIFT          6
 #define HOUR_PM_MASK           (1 << HOUR_PM_SHIFT)
+#define RTC_TCON_SHIFT         1
+#define RTC_TCON_MASK          (1 << RTC_TCON_SHIFT)
+#define S5M_RTC_TIME_EN_SHIFT  3
+#define S5M_RTC_TIME_EN_MASK   (1 << S5M_RTC_TIME_EN_SHIFT)
+#define S5M_RTC_TEST_OSC_SHIFT 4
+#define S5M_RTC_TEST_OSC_MASK  (1 << S5M_RTC_TEST_OSC_SHIFT)
+#define S5M_RTC_UDR_T_SHIFT    6
+#define S5M_RTC_UDR_T_MASK     (3 << S5M_RTC_UDR_T_SHIFT)
+
 /* RTC Alarm Enable */
 #define ALARM_ENABLE_SHIFT     7
 #define ALARM_ENABLE_MASK      (1 << ALARM_ENABLE_SHIFT)
 
+#define SMPL_ENABLE_SHIFT      7
+#define SMPL_ENABLE_MASK       (1 << SMPL_ENABLE_SHIFT)
+
+#define WTSR_ENABLE_SHIFT      6
+#define WTSR_ENABLE_MASK       (1 << WTSR_ENABLE_SHIFT)
+
 enum {
        RTC_SEC = 0,
        RTC_MIN,
index ad2252f..34da585 100644 (file)
@@ -191,6 +191,5 @@ enum s2mps11_regulators {
 #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
 
 #define S2MPS11_PMIC_EN_SHIFT  6
-#define S2MPS11_REGULATOR_MAX (S2MPS11_REG_MAX - 3)
 
 #endif /*  __LINUX_MFD_S2MPS11_H */
diff --git a/include/linux/mfd/samsung/s2mps14.h b/include/linux/mfd/samsung/s2mps14.h
new file mode 100644 (file)
index 0000000..122b4f1
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * s2mps14.h
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __LINUX_MFD_S2MPS14_H
+#define __LINUX_MFD_S2MPS14_H
+
+/* S2MPS14 registers */
+enum s2mps14_reg {
+       S2MPS14_REG_ID,
+       S2MPS14_REG_INT1,
+       S2MPS14_REG_INT2,
+       S2MPS14_REG_INT3,
+       S2MPS14_REG_INT1M,
+       S2MPS14_REG_INT2M,
+       S2MPS14_REG_INT3M,
+       S2MPS14_REG_ST1,
+       S2MPS14_REG_ST2,
+       S2MPS14_REG_PWRONSRC,
+       S2MPS14_REG_OFFSRC,
+       S2MPS14_REG_BU_CHG,
+       S2MPS14_REG_RTCCTRL,
+       S2MPS14_REG_CTRL1,
+       S2MPS14_REG_CTRL2,
+       S2MPS14_REG_RSVD1,
+       S2MPS14_REG_RSVD2,
+       S2MPS14_REG_RSVD3,
+       S2MPS14_REG_RSVD4,
+       S2MPS14_REG_RSVD5,
+       S2MPS14_REG_RSVD6,
+       S2MPS14_REG_CTRL3,
+       S2MPS14_REG_RSVD7,
+       S2MPS14_REG_RSVD8,
+       S2MPS14_REG_WRSTBI,
+       S2MPS14_REG_B1CTRL1,
+       S2MPS14_REG_B1CTRL2,
+       S2MPS14_REG_B2CTRL1,
+       S2MPS14_REG_B2CTRL2,
+       S2MPS14_REG_B3CTRL1,
+       S2MPS14_REG_B3CTRL2,
+       S2MPS14_REG_B4CTRL1,
+       S2MPS14_REG_B4CTRL2,
+       S2MPS14_REG_B5CTRL1,
+       S2MPS14_REG_B5CTRL2,
+       S2MPS14_REG_L1CTRL,
+       S2MPS14_REG_L2CTRL,
+       S2MPS14_REG_L3CTRL,
+       S2MPS14_REG_L4CTRL,
+       S2MPS14_REG_L5CTRL,
+       S2MPS14_REG_L6CTRL,
+       S2MPS14_REG_L7CTRL,
+       S2MPS14_REG_L8CTRL,
+       S2MPS14_REG_L9CTRL,
+       S2MPS14_REG_L10CTRL,
+       S2MPS14_REG_L11CTRL,
+       S2MPS14_REG_L12CTRL,
+       S2MPS14_REG_L13CTRL,
+       S2MPS14_REG_L14CTRL,
+       S2MPS14_REG_L15CTRL,
+       S2MPS14_REG_L16CTRL,
+       S2MPS14_REG_L17CTRL,
+       S2MPS14_REG_L18CTRL,
+       S2MPS14_REG_L19CTRL,
+       S2MPS14_REG_L20CTRL,
+       S2MPS14_REG_L21CTRL,
+       S2MPS14_REG_L22CTRL,
+       S2MPS14_REG_L23CTRL,
+       S2MPS14_REG_L24CTRL,
+       S2MPS14_REG_L25CTRL,
+       S2MPS14_REG_LDODSCH1,
+       S2MPS14_REG_LDODSCH2,
+       S2MPS14_REG_LDODSCH3,
+};
+
+/* S2MPS14 regulator ids */
+enum s2mps14_regulators {
+       S2MPS14_LDO1,
+       S2MPS14_LDO2,
+       S2MPS14_LDO3,
+       S2MPS14_LDO4,
+       S2MPS14_LDO5,
+       S2MPS14_LDO6,
+       S2MPS14_LDO7,
+       S2MPS14_LDO8,
+       S2MPS14_LDO9,
+       S2MPS14_LDO10,
+       S2MPS14_LDO11,
+       S2MPS14_LDO12,
+       S2MPS14_LDO13,
+       S2MPS14_LDO14,
+       S2MPS14_LDO15,
+       S2MPS14_LDO16,
+       S2MPS14_LDO17,
+       S2MPS14_LDO18,
+       S2MPS14_LDO19,
+       S2MPS14_LDO20,
+       S2MPS14_LDO21,
+       S2MPS14_LDO22,
+       S2MPS14_LDO23,
+       S2MPS14_LDO24,
+       S2MPS14_LDO25,
+       S2MPS14_BUCK1,
+       S2MPS14_BUCK2,
+       S2MPS14_BUCK3,
+       S2MPS14_BUCK4,
+       S2MPS14_BUCK5,
+
+       S2MPS14_REG_MAX,
+};
+
+/* Regulator constraints for BUCKx */
+#define S2MPS14_BUCK1235_MIN_600MV     600000
+#define S2MPS14_BUCK4_MIN_1400MV       1400000
+#define S2MPS14_BUCK1235_STEP_6_25MV   6250
+#define S2MPS14_BUCK4_STEP_12_5MV      12500
+#define S2MPS14_BUCK1235_START_SEL     0x20
+#define S2MPS14_BUCK4_START_SEL                0x40
+/*
+ * Default ramp delay in uv/us. Datasheet says that ramp delay can be
+ * controlled however it does not specify which register is used for that.
+ * Let's assume that default value will be set.
+ */
+#define S2MPS14_BUCK_RAMP_DELAY                12500
+
+/* Regulator constraints for different types of LDOx */
+#define S2MPS14_LDO_MIN_800MV  800000
+#define S2MPS14_LDO_MIN_1800MV 1800000
+#define S2MPS14_LDO_STEP_12_5MV        12500
+#define S2MPS14_LDO_STEP_25MV  25000
+
+#define S2MPS14_LDO_VSEL_MASK  0x3F
+#define S2MPS14_BUCK_VSEL_MASK 0xFF
+#define S2MPS14_ENABLE_MASK    (0x03 << S2MPS14_ENABLE_SHIFT)
+#define S2MPS14_ENABLE_SHIFT   6
+#define S2MPS14_LDO_N_VOLTAGES (S2MPS14_LDO_VSEL_MASK + 1)
+#define S2MPS14_BUCK_N_VOLTAGES (S2MPS14_BUCK_VSEL_MASK + 1)
+
+#define S2MPS14_ENCTRL_SHIFT           6
+#define S2MPS14_ENCTRL_MASK            (0x3 << S2MPS14_ENCTRL_SHIFT)
+
+enum s2mps14_regulator_opmode {
+       S2MPS14_REGULATOR_OPMODE_OFF,
+       S2MPS14_REGULATOR_OPMODE_ON,
+       S2MPS14_REGULATOR_OPMODE_RESERVED,
+       S2MPS14_REGULATOR_OPMODE_SUSPEND,
+
+       S2MPS14_REGULATOR_OPMODE_MAX,
+};
+
+#endif /*  __LINUX_MFD_S2MPS14_H */
index 306a95f..f9dfc1a 100644 (file)
@@ -177,12 +177,29 @@ enum s5m8767_regulators {
        S5M8767_BUCK7,
        S5M8767_BUCK8,
        S5M8767_BUCK9,
-       S5M8767_AP_EN32KHZ,
-       S5M8767_CP_EN32KHZ,
 
        S5M8767_REG_MAX,
 };
 
-#define S5M8767_ENCTRL_SHIFT  6
+#define S5M8767_ENCTRL_SHIFT           6
+#define S5M8767_ENCTRL_MASK            (0x3 << S5M8767_ENCTRL_SHIFT)
+#define S5M8767_REG_LDO_SHIFT          7
+/* Use pin (PWREN, BUCKEN) for controlling this Buck or LDO */
+#define S5M8767_ENCTRL_USES_PIN                0x1
+
+/*
+ * Values for BUCK_RAMP field in DVS_RAMP register, matching raw values
+ * in mV/us.
+ */
+enum s5m8767_dvs_buck_ramp_values {
+       S5M8767_DVS_BUCK_RAMP_5         = 0x4,
+       S5M8767_DVS_BUCK_RAMP_10        = 0x9,
+       S5M8767_DVS_BUCK_RAMP_12_5      = 0xb,
+       S5M8767_DVS_BUCK_RAMP_25        = 0xd,
+       S5M8767_DVS_BUCK_RAMP_50        = 0xe,
+       S5M8767_DVS_BUCK_RAMP_100       = 0xf,
+};
+#define S5M8767_DVS_BUCK_RAMP_SHIFT    4
+#define S5M8767_DVS_BUCK_RAMP_MASK     (0xf << S5M8767_DVS_BUCK_RAMP_SHIFT)
 
 #endif /* __LINUX_MFD_S5M8767_H */