Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorMark Brown <broonie@linaro.org>
Tue, 5 Aug 2014 18:01:34 +0000 (19:01 +0100)
committerMark Brown <broonie@linaro.org>
Tue, 5 Aug 2014 18:01:34 +0000 (19:01 +0100)
43 files changed:
Documentation/devicetree/bindings/mfd/palmas.txt
Documentation/devicetree/bindings/regulator/act8865-regulator.txt
Documentation/devicetree/bindings/regulator/palmas-pmic.txt
Documentation/devicetree/bindings/regulator/tps65218.txt [new file with mode: 0644]
Documentation/power/regulator/consumer.txt
drivers/extcon/extcon-max77693.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/max77693-irq.c [deleted file]
drivers/mfd/max77693.c
drivers/mfd/palmas.c
drivers/regulator/88pm800.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/ab8500.c
drivers/regulator/act8865-regulator.c
drivers/regulator/arizona-ldo1.c
drivers/regulator/as3722-regulator.c
drivers/regulator/bcm590xx-regulator.c
drivers/regulator/core.c
drivers/regulator/da9211-regulator.c [new file with mode: 0644]
drivers/regulator/da9211-regulator.h [new file with mode: 0644]
drivers/regulator/lp872x.c
drivers/regulator/lp8755.c
drivers/regulator/ltc3589.c
drivers/regulator/max77693.c
drivers/regulator/max8952.c
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/mc13xxx.h
drivers/regulator/palmas-regulator.c
drivers/regulator/s2mps11.c
drivers/regulator/s5m8767.c
drivers/regulator/tps65090-regulator.c
drivers/regulator/tps65217-regulator.c
drivers/regulator/tps65218-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/twl-regulator.c
include/linux/mfd/max77693-private.h
include/linux/mfd/palmas.h
include/linux/regulator/ab8500.h
include/linux/regulator/act8865.h
include/linux/regulator/consumer.h
include/linux/regulator/da9211.h [new file with mode: 0644]

index e5f0f83..eda8989 100644 (file)
@@ -6,6 +6,7 @@ twl6037 (palmas)
 tps65913 (palmas)
 tps65914 (palmas)
 tps659038
+tps65917
 
 Required properties:
 - compatible : Should be from the list
@@ -16,6 +17,7 @@ Required properties:
   ti,tps65914
   ti,tps80036
   ti,tps659038
+  ti,tps65917
 and also the generic series names
   ti,palmas
 - interrupt-controller : palmas has its own internal IRQs
index bef1fbb..865614b 100644 (file)
@@ -1,13 +1,16 @@
-ACT8865 regulator
+ACT88xx regulators
 -------------------
 
 Required properties:
-- compatible: "active-semi,act8865"
+- compatible: "active-semi,act8846" or "active-semi,act8865"
 - reg: I2C slave address
 
 Any standard regulator properties can be used to configure the single regulator.
 
 The valid names for regulators are:
+       - for act8846:
+       REG1, REG2, REG3, REG4, REG5, REG6, REG7, REG8, REG9, REG10, REG11, REG12
+       - for act8865:
        DCDC_REG1, DCDC_REG2, DCDC_REG3, LDO_REG1, LDO_REG2, LDO_REG3, LDO_REG4.
 
 Example:
index 42e6b6b..725393c 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
   ti,twl6037-pmic
   ti,tps65913-pmic
   ti,tps65914-pmic
+  ti,tps65917-pmic
 and also the generic series names
   ti,palmas-pmic
 - interrupt-parent : The parent interrupt controller which is palmas.
diff --git a/Documentation/devicetree/bindings/regulator/tps65218.txt b/Documentation/devicetree/bindings/regulator/tps65218.txt
new file mode 100644 (file)
index 0000000..fccc1d2
--- /dev/null
@@ -0,0 +1,23 @@
+TPS65218 family of regulators
+
+Required properties:
+For tps65218 regulators/LDOs
+- compatible:
+  - "ti,tps65218-dcdc1" for DCDC1
+  - "ti,tps65218-dcdc2" for DCDC2
+  - "ti,tps65218-dcdc3" for DCDC3
+  - "ti,tps65218-dcdc4" for DCDC4
+  - "ti,tps65218-dcdc5" for DCDC5
+  - "ti,tps65218-dcdc6" for DCDC6
+  - "ti,tps65218-ldo1" for LDO1
+
+Optional properties:
+- Any optional property defined in bindings/regulator/regulator.txt
+
+Example:
+
+       xyz: regulator@0 {
+               compatible = "ti,tps65218-dcdc1";
+               regulator-min-microvolt  = <1000000>;
+               regulator-max-microvolt  = <3000000>;
+       };
index 55c4175..81c0e2b 100644 (file)
@@ -180,3 +180,38 @@ int regulator_unregister_notifier(struct regulator *regulator,
 
 Regulators use the kernel notifier framework to send event to their interested
 consumers.
+
+7. Regulator Direct Register Access
+===================================
+Some kinds of power management hardware or firmware are designed such that
+they need to do low-level hardware access to regulators, with no involvement
+from the kernel. Examples of such devices are:
+
+- clocksource with a voltage-controlled oscillator and control logic to change
+  the supply voltage over I2C to achieve a desired output clock rate
+- thermal management firmware that can issue an arbitrary I2C transaction to
+  perform system poweroff during overtemperature conditions
+
+To set up such a device/firmware, various parameters like I2C address of the
+regulator, addresses of various regulator registers etc. need to be configured
+to it. The regulator framework provides the following helpers for querying
+these details.
+
+Bus-specific details, like I2C addresses or transfer rates are handled by the
+regmap framework. To get the regulator's regmap (if supported), use :-
+
+struct regmap *regulator_get_regmap(struct regulator *regulator);
+
+To obtain the hardware register offset and bitmask for the regulator's voltage
+selector register, use :-
+
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+                                        unsigned *vsel_reg,
+                                        unsigned *vsel_mask);
+
+To convert a regulator framework voltage selector code (used by
+regulator_list_voltage) to a hardware-specific voltage selector that can be
+directly written to the voltage selector register, use :-
+
+int regulator_list_hardware_vsel(struct regulator *regulator,
+                                unsigned selector);
index 2c7c3e1..c7278b1 100644 (file)
@@ -255,10 +255,10 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
        case ADC_DEBOUNCE_TIME_10MS:
        case ADC_DEBOUNCE_TIME_25MS:
        case ADC_DEBOUNCE_TIME_38_62MS:
-               ret = max77693_update_reg(info->max77693->regmap_muic,
+               ret = regmap_update_bits(info->max77693->regmap_muic,
                                          MAX77693_MUIC_REG_CTRL3,
-                                         time << CONTROL3_ADCDBSET_SHIFT,
-                                         CONTROL3_ADCDBSET_MASK);
+                                         CONTROL3_ADCDBSET_MASK,
+                                         time << CONTROL3_ADCDBSET_SHIFT);
                if (ret) {
                        dev_err(info->dev, "failed to set ADC debounce time\n");
                        return ret;
@@ -286,15 +286,15 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
                u8 val, bool attached)
 {
        int ret = 0;
-       u8 ctrl1, ctrl2 = 0;
+       unsigned int ctrl1, ctrl2 = 0;
 
        if (attached)
                ctrl1 = val;
        else
                ctrl1 = CONTROL1_SW_OPEN;
 
-       ret = max77693_update_reg(info->max77693->regmap_muic,
-                       MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
+       ret = regmap_update_bits(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1);
        if (ret < 0) {
                dev_err(info->dev, "failed to update MUIC register\n");
                return ret;
@@ -305,9 +305,9 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
        else
                ctrl2 |= CONTROL2_LOWPWR_MASK;  /* LowPwr=1, CPEn=0 */
 
-       ret = max77693_update_reg(info->max77693->regmap_muic,
-                       MAX77693_MUIC_REG_CTRL2, ctrl2,
-                       CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK);
+       ret = regmap_update_bits(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_CTRL2,
+                       CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK, ctrl2);
        if (ret < 0) {
                dev_err(info->dev, "failed to update MUIC register\n");
                return ret;
@@ -969,8 +969,8 @@ static void max77693_muic_irq_work(struct work_struct *work)
                if (info->irq == muic_irqs[i].virq)
                        irq_type = muic_irqs[i].irq;
 
-       ret = max77693_bulk_read(info->max77693->regmap_muic,
-                       MAX77693_MUIC_REG_STATUS1, 2, info->status);
+       ret = regmap_bulk_read(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_STATUS1, info->status, 2);
        if (ret) {
                dev_err(info->dev, "failed to read MUIC register\n");
                mutex_unlock(&info->mutex);
@@ -1042,8 +1042,8 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
        mutex_lock(&info->mutex);
 
        /* Read STATUSx register to detect accessory */
-       ret = max77693_bulk_read(info->max77693->regmap_muic,
-                       MAX77693_MUIC_REG_STATUS1, 2, info->status);
+       ret = regmap_bulk_read(info->max77693->regmap_muic,
+                       MAX77693_MUIC_REG_STATUS1, info->status, 2);
        if (ret) {
                dev_err(info->dev, "failed to read MUIC register\n");
                mutex_unlock(&info->mutex);
@@ -1095,7 +1095,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
        int delay_jiffies;
        int ret;
        int i;
-       u8 id;
+       unsigned int id;
 
        info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info),
                                   GFP_KERNEL);
@@ -1154,7 +1154,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
                struct max77693_muic_irq *muic_irq = &muic_irqs[i];
                unsigned int virq = 0;
 
-               virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq);
+               virq = regmap_irq_get_virq(max77693->irq_data_muic,
+                                       muic_irq->irq);
                if (!virq) {
                        ret = -EINVAL;
                        goto err_irq;
@@ -1204,7 +1205,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
                enum max77693_irq_source irq_src
                                = MAX77693_IRQ_GROUP_NR;
 
-               max77693_write_reg(info->max77693->regmap_muic,
+               regmap_write(info->max77693->regmap_muic,
                                init_data[i].addr,
                                init_data[i].data);
 
@@ -1262,7 +1263,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
         max77693_muic_set_path(info, info->path_uart, true);
 
        /* Check revision number of MUIC device*/
-       ret = max77693_read_reg(info->max77693->regmap_muic,
+       ret = regmap_read(info->max77693->regmap_muic,
                        MAX77693_MUIC_REG_ID, &id);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to read revision number\n");
index 6cc4b6a..fb824f5 100644 (file)
@@ -384,6 +384,7 @@ config MFD_MAX77693
        depends on I2C=y
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        help
          Say yes here to add support for Maxim Semiconductor MAX77693.
          This is a companion Power Management IC with Flash, Haptic, Charger,
index 8afedba..8c6e7bb 100644 (file)
@@ -116,7 +116,7 @@ obj-$(CONFIG_MFD_DA9063)    += da9063.o
 
 obj-$(CONFIG_MFD_MAX14577)     += max14577.o
 obj-$(CONFIG_MFD_MAX77686)     += max77686.o max77686-irq.o
-obj-$(CONFIG_MFD_MAX77693)     += max77693.o max77693-irq.o
+obj-$(CONFIG_MFD_MAX77693)     += max77693.o
 obj-$(CONFIG_MFD_MAX8907)      += max8907.o
 max8925-objs                   := max8925-core.o max8925-i2c.o
 obj-$(CONFIG_MFD_MAX8925)      += max8925.o
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
deleted file mode 100644 (file)
index 66b58fe..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * max77693-irq.c - Interrupt controller support for MAX77693
- *
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- * SangYoung Son <hello.son@samsung.com>
- *
- * This program is not provided / owned by Maxim Integrated Products.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * This driver is based on max8997-irq.c
- */
-
-#include <linux/err.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/irqdomain.h>
-#include <linux/mfd/max77693.h>
-#include <linux/mfd/max77693-private.h>
-
-static const u8 max77693_mask_reg[] = {
-       [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK,
-       [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
-       [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK,
-       [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1,
-       [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2,
-       [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3,
-};
-
-static struct regmap *max77693_get_regmap(struct max77693_dev *max77693,
-                               enum max77693_irq_source src)
-{
-       switch (src) {
-       case LED_INT ... CHG_INT:
-               return max77693->regmap;
-       case MUIC_INT1 ... MUIC_INT3:
-               return max77693->regmap_muic;
-       default:
-               return ERR_PTR(-EINVAL);
-       }
-}
-
-struct max77693_irq_data {
-       int mask;
-       enum max77693_irq_source group;
-};
-
-#define DECLARE_IRQ(idx, _group, _mask)                \
-       [(idx)] = { .group = (_group), .mask = (_mask) }
-static const struct max77693_irq_data max77693_irqs[] = {
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN,        LED_INT, 1 << 0),
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT,       LED_INT, 1 << 1),
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN,        LED_INT, 1 << 2),
-       DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT,       LED_INT, 1 << 3),
-       DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH,         LED_INT, 1 << 4),
-
-       DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT,      TOPSYS_INT, 1 << 0),
-       DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT,      TOPSYS_INT, 1 << 1),
-       DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT,     TOPSYS_INT, 1 << 3),
-
-       DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I,             CHG_INT, 1 << 0),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I,             CHG_INT, 1 << 2),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I,             CHG_INT, 1 << 3),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I,             CHG_INT, 1 << 4),
-       DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I,           CHG_INT, 1 << 6),
-
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC,         MUIC_INT1, 1 << 0),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW,     MUIC_INT1, 1 << 1),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR,     MUIC_INT1, 1 << 2),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K,       MUIC_INT1, 1 << 3),
-
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP,      MUIC_INT2, 1 << 0),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN,  MUIC_INT2, 1 << 1),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR,      MUIC_INT2, 1 << 2),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP,       MUIC_INT2, 1 << 3),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT,      MUIC_INT2, 1 << 4),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM,       MUIC_INT2, 1 << 5),
-
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC,         MUIC_INT3, 1 << 0),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC,       MUIC_INT3, 1 << 1),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP,         MUIC_INT3, 1 << 2),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR,  MUIC_INT3, 1 << 3),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4),
-       DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET,     MUIC_INT3, 1 << 5),
-};
-
-static void max77693_irq_lock(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-
-       mutex_lock(&max77693->irqlock);
-}
-
-static void max77693_irq_sync_unlock(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-       int i;
-
-       for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
-               u8 mask_reg = max77693_mask_reg[i];
-               struct regmap *map = max77693_get_regmap(max77693, i);
-
-               if (mask_reg == MAX77693_REG_INVALID ||
-                               IS_ERR_OR_NULL(map))
-                       continue;
-               max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i];
-
-               max77693_write_reg(map, max77693_mask_reg[i],
-                               max77693->irq_masks_cur[i]);
-       }
-
-       mutex_unlock(&max77693->irqlock);
-}
-
-static const inline struct max77693_irq_data *
-irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
-{
-       struct irq_data *data = irq_get_irq_data(irq);
-       return &max77693_irqs[data->hwirq];
-}
-
-static void max77693_irq_mask(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-       const struct max77693_irq_data *irq_data =
-                               irq_to_max77693_irq(max77693, data->irq);
-
-       if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
-               return;
-
-       if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
-               max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
-       else
-               max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
-}
-
-static void max77693_irq_unmask(struct irq_data *data)
-{
-       struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
-       const struct max77693_irq_data *irq_data =
-           irq_to_max77693_irq(max77693, data->irq);
-
-       if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
-               return;
-
-       if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
-               max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
-       else
-               max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
-}
-
-static struct irq_chip max77693_irq_chip = {
-       .name                   = "max77693",
-       .irq_bus_lock           = max77693_irq_lock,
-       .irq_bus_sync_unlock    = max77693_irq_sync_unlock,
-       .irq_mask               = max77693_irq_mask,
-       .irq_unmask             = max77693_irq_unmask,
-};
-
-#define MAX77693_IRQSRC_CHG            (1 << 0)
-#define MAX77693_IRQSRC_TOP            (1 << 1)
-#define MAX77693_IRQSRC_FLASH          (1 << 2)
-#define MAX77693_IRQSRC_MUIC           (1 << 3)
-static irqreturn_t max77693_irq_thread(int irq, void *data)
-{
-       struct max77693_dev *max77693 = data;
-       u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {};
-       u8 irq_src;
-       int ret;
-       int i, cur_irq;
-
-       ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_INTSRC,
-                               &irq_src);
-       if (ret < 0) {
-               dev_err(max77693->dev, "Failed to read interrupt source: %d\n",
-                               ret);
-               return IRQ_NONE;
-       }
-
-       if (irq_src & MAX77693_IRQSRC_CHG)
-               /* CHG_INT */
-               ret = max77693_read_reg(max77693->regmap, MAX77693_CHG_REG_CHG_INT,
-                               &irq_reg[CHG_INT]);
-
-       if (irq_src & MAX77693_IRQSRC_TOP)
-               /* TOPSYS_INT */
-               ret = max77693_read_reg(max77693->regmap,
-                       MAX77693_PMIC_REG_TOPSYS_INT, &irq_reg[TOPSYS_INT]);
-
-       if (irq_src & MAX77693_IRQSRC_FLASH)
-               /* LED_INT */
-               ret = max77693_read_reg(max77693->regmap,
-                       MAX77693_LED_REG_FLASH_INT, &irq_reg[LED_INT]);
-
-       if (irq_src & MAX77693_IRQSRC_MUIC)
-               /* MUIC INT1 ~ INT3 */
-               max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
-                       MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]);
-
-       /* Apply masking */
-       for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
-               if (i >= MUIC_INT1 && i <= MUIC_INT3)
-                       irq_reg[i] &= max77693->irq_masks_cur[i];
-               else
-                       irq_reg[i] &= ~max77693->irq_masks_cur[i];
-       }
-
-       /* Report */
-       for (i = 0; i < MAX77693_IRQ_NR; i++) {
-               if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) {
-                       cur_irq = irq_find_mapping(max77693->irq_domain, i);
-                       if (cur_irq)
-                               handle_nested_irq(cur_irq);
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
-int max77693_irq_resume(struct max77693_dev *max77693)
-{
-       if (max77693->irq)
-               max77693_irq_thread(0, max77693);
-
-       return 0;
-}
-
-static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq,
-                               irq_hw_number_t hw)
-{
-       struct max77693_dev *max77693 = d->host_data;
-
-       irq_set_chip_data(irq, max77693);
-       irq_set_chip_and_handler(irq, &max77693_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 max77693_irq_domain_ops = {
-       .map = max77693_irq_domain_map,
-};
-
-int max77693_irq_init(struct max77693_dev *max77693)
-{
-       struct irq_domain *domain;
-       int i;
-       int ret = 0;
-       u8 intsrc_mask;
-
-       mutex_init(&max77693->irqlock);
-
-       /* Mask individual interrupt sources */
-       for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
-               struct regmap *map;
-               /* MUIC IRQ  0:MASK 1:NOT MASK */
-               /* Other IRQ 1:MASK 0:NOT MASK */
-               if (i >= MUIC_INT1 && i <= MUIC_INT3) {
-                       max77693->irq_masks_cur[i] = 0x00;
-                       max77693->irq_masks_cache[i] = 0x00;
-               } else {
-                       max77693->irq_masks_cur[i] = 0xff;
-                       max77693->irq_masks_cache[i] = 0xff;
-               }
-               map = max77693_get_regmap(max77693, i);
-
-               if (IS_ERR_OR_NULL(map))
-                       continue;
-               if (max77693_mask_reg[i] == MAX77693_REG_INVALID)
-                       continue;
-               if (i >= MUIC_INT1 && i <= MUIC_INT3)
-                       max77693_write_reg(map, max77693_mask_reg[i], 0x00);
-               else
-                       max77693_write_reg(map, max77693_mask_reg[i], 0xff);
-       }
-
-       domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR,
-                                       &max77693_irq_domain_ops, max77693);
-       if (!domain) {
-               dev_err(max77693->dev, "could not create irq domain\n");
-               ret = -ENODEV;
-               goto err_irq;
-       }
-       max77693->irq_domain = domain;
-
-       /* Unmask max77693 interrupt */
-       ret = max77693_read_reg(max77693->regmap,
-                       MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
-       if (ret < 0) {
-               dev_err(max77693->dev, "fail to read PMIC register\n");
-               goto err_irq;
-       }
-
-       intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
-       intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
-       intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
-       ret = max77693_write_reg(max77693->regmap,
-                       MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
-       if (ret < 0) {
-               dev_err(max77693->dev, "fail to write PMIC register\n");
-               goto err_irq;
-       }
-
-       ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
-                                  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-                                  "max77693-irq", max77693);
-       if (ret)
-               dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
-                       max77693->irq, ret);
-
-err_irq:
-       return ret;
-}
-
-void max77693_irq_exit(struct max77693_dev *max77693)
-{
-       if (max77693->irq)
-               free_irq(max77693->irq, max77693);
-}
index 7e05428..249c139 100644 (file)
@@ -49,62 +49,62 @@ static const struct mfd_cell max77693_devs[] = {
        { .name = "max77693-haptic", },
 };
 
-int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest)
-{
-       unsigned int val;
-       int ret;
-
-       ret = regmap_read(map, reg, &val);
-       *dest = val;
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_read_reg);
-
-int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf)
-{
-       int ret;
-
-       ret = regmap_bulk_read(map, reg, buf, count);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_bulk_read);
-
-int max77693_write_reg(struct regmap *map, u8 reg, u8 value)
-{
-       int ret;
-
-       ret = regmap_write(map, reg, value);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_write_reg);
-
-int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf)
-{
-       int ret;
+static const struct regmap_config max77693_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = MAX77693_PMIC_REG_END,
+};
 
-       ret = regmap_bulk_write(map, reg, buf, count);
+static const struct regmap_irq max77693_led_irqs[] = {
+       { .mask = LED_IRQ_FLED2_OPEN,  },
+       { .mask = LED_IRQ_FLED2_SHORT, },
+       { .mask = LED_IRQ_FLED1_OPEN,  },
+       { .mask = LED_IRQ_FLED1_SHORT, },
+       { .mask = LED_IRQ_MAX_FLASH,   },
+};
 
-       return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_bulk_write);
+static const struct regmap_irq_chip max77693_led_irq_chip = {
+       .name                   = "max77693-led",
+       .status_base            = MAX77693_LED_REG_FLASH_INT,
+       .mask_base              = MAX77693_LED_REG_FLASH_INT_MASK,
+       .mask_invert            = false,
+       .num_regs               = 1,
+       .irqs                   = max77693_led_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_led_irqs),
+};
 
-int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask)
-{
-       int ret;
+static const struct regmap_irq max77693_topsys_irqs[] = {
+       { .mask = TOPSYS_IRQ_T120C_INT,  },
+       { .mask = TOPSYS_IRQ_T140C_INT,  },
+       { .mask = TOPSYS_IRQ_LOWSYS_INT, },
+};
 
-       ret = regmap_update_bits(map, reg, mask, val);
+static const struct regmap_irq_chip max77693_topsys_irq_chip = {
+       .name                   = "max77693-topsys",
+       .status_base            = MAX77693_PMIC_REG_TOPSYS_INT,
+       .mask_base              = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
+       .mask_invert            = false,
+       .num_regs               = 1,
+       .irqs                   = max77693_topsys_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_topsys_irqs),
+};
 
-       return ret;
-}
-EXPORT_SYMBOL_GPL(max77693_update_reg);
+static const struct regmap_irq max77693_charger_irqs[] = {
+       { .mask = CHG_IRQ_BYP_I,   },
+       { .mask = CHG_IRQ_THM_I,   },
+       { .mask = CHG_IRQ_BAT_I,   },
+       { .mask = CHG_IRQ_CHG_I,   },
+       { .mask = CHG_IRQ_CHGIN_I, },
+};
 
-static const struct regmap_config max77693_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-       .max_register = MAX77693_PMIC_REG_END,
+static const struct regmap_irq_chip max77693_charger_irq_chip = {
+       .name                   = "max77693-charger",
+       .status_base            = MAX77693_CHG_REG_CHG_INT,
+       .mask_base              = MAX77693_CHG_REG_CHG_INT_MASK,
+       .mask_invert            = false,
+       .num_regs               = 1,
+       .irqs                   = max77693_charger_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_charger_irqs),
 };
 
 static const struct regmap_config max77693_regmap_muic_config = {
@@ -113,11 +113,42 @@ static const struct regmap_config max77693_regmap_muic_config = {
        .max_register = MAX77693_MUIC_REG_END,
 };
 
+static const struct regmap_irq max77693_muic_irqs[] = {
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC,           },
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW,       },
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR,       },
+       { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K,         },
+
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP,        },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN,    },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR,        },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP,         },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT,        },
+       { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM,         },
+
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC,           },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC,         },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP,           },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR,    },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED,   },
+       { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET,       },
+};
+
+static const struct regmap_irq_chip max77693_muic_irq_chip = {
+       .name                   = "max77693-muic",
+       .status_base            = MAX77693_MUIC_REG_INT1,
+       .mask_base              = MAX77693_MUIC_REG_INTMASK1,
+       .mask_invert            = true,
+       .num_regs               = 3,
+       .irqs                   = max77693_muic_irqs,
+       .num_irqs               = ARRAY_SIZE(max77693_muic_irqs),
+};
+
 static int max77693_i2c_probe(struct i2c_client *i2c,
                              const struct i2c_device_id *id)
 {
        struct max77693_dev *max77693;
-       u8 reg_data;
+       unsigned int reg_data;
        int ret = 0;
 
        max77693 = devm_kzalloc(&i2c->dev,
@@ -139,7 +170,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
                return ret;
        }
 
-       ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
+       ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
                                &reg_data);
        if (ret < 0) {
                dev_err(max77693->dev, "device not found on this channel\n");
@@ -176,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
                goto err_regmap_muic;
        }
 
-       ret = max77693_irq_init(max77693);
-       if (ret < 0)
-               goto err_irq;
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_led_irq_chip,
+                               &max77693->irq_data_led);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_regmap_muic;
+       }
+
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_topsys_irq_chip,
+                               &max77693->irq_data_topsys);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_irq_topsys;
+       }
+
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_charger_irq_chip,
+                               &max77693->irq_data_charger);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_irq_charger;
+       }
+
+       ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
+                               IRQF_ONESHOT | IRQF_SHARED |
+                               IRQF_TRIGGER_FALLING, 0,
+                               &max77693_muic_irq_chip,
+                               &max77693->irq_data_muic);
+       if (ret) {
+               dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
+               goto err_irq_muic;
+       }
 
        pm_runtime_set_active(max77693->dev);
 
@@ -190,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
        return ret;
 
 err_mfd:
-       max77693_irq_exit(max77693);
-err_irq:
+       mfd_remove_devices(max77693->dev);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
+err_irq_muic:
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+err_irq_charger:
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
+err_irq_topsys:
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
 err_regmap_muic:
        i2c_unregister_device(max77693->haptic);
 err_i2c_haptic:
@@ -204,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
        struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 
        mfd_remove_devices(max77693->dev);
-       max77693_irq_exit(max77693);
+
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
+       regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
+
        i2c_unregister_device(max77693->muic);
        i2c_unregister_device(max77693->haptic);
 
@@ -222,8 +300,11 @@ static int max77693_suspend(struct device *dev)
        struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
        struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 
-       if (device_may_wakeup(dev))
-               irq_set_irq_wake(max77693->irq, 1);
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(max77693->irq);
+               disable_irq(max77693->irq);
+       }
+
        return 0;
 }
 
@@ -232,9 +313,12 @@ static int max77693_resume(struct device *dev)
        struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
        struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 
-       if (device_may_wakeup(dev))
-               irq_set_irq_wake(max77693->irq, 0);
-       return max77693_irq_resume(max77693);
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(max77693->irq);
+               enable_irq(max77693->irq);
+       }
+
+       return 0;
 }
 
 static const struct dev_pm_ops max77693_pm = {
index d280d78..28cb048 100644 (file)
 #include <linux/mfd/palmas.h>
 #include <linux/of_device.h>
 
-#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 |   \
-                       PALMAS_EXT_CONTROL_ENABLE2 |    \
-                       PALMAS_EXT_CONTROL_NSLEEP)
-
-struct palmas_sleep_requestor_info {
-       int id;
-       int reg_offset;
-       int bit_pos;
-};
-
-#define EXTERNAL_REQUESTOR(_id, _offset, _pos)         \
-       [PALMAS_EXTERNAL_REQSTR_ID_##_id] = {           \
-               .id = PALMAS_EXTERNAL_REQSTR_ID_##_id,  \
-               .reg_offset = _offset,                  \
-               .bit_pos = _pos,                        \
-       }
-
-static struct palmas_sleep_requestor_info sleep_req_info[] = {
-       EXTERNAL_REQUESTOR(REGEN1, 0, 0),
-       EXTERNAL_REQUESTOR(REGEN2, 0, 1),
-       EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
-       EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
-       EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
-       EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
-       EXTERNAL_REQUESTOR(REGEN3, 0, 6),
-       EXTERNAL_REQUESTOR(SMPS12, 1, 0),
-       EXTERNAL_REQUESTOR(SMPS3, 1, 1),
-       EXTERNAL_REQUESTOR(SMPS45, 1, 2),
-       EXTERNAL_REQUESTOR(SMPS6, 1, 3),
-       EXTERNAL_REQUESTOR(SMPS7, 1, 4),
-       EXTERNAL_REQUESTOR(SMPS8, 1, 5),
-       EXTERNAL_REQUESTOR(SMPS9, 1, 6),
-       EXTERNAL_REQUESTOR(SMPS10, 1, 7),
-       EXTERNAL_REQUESTOR(LDO1, 2, 0),
-       EXTERNAL_REQUESTOR(LDO2, 2, 1),
-       EXTERNAL_REQUESTOR(LDO3, 2, 2),
-       EXTERNAL_REQUESTOR(LDO4, 2, 3),
-       EXTERNAL_REQUESTOR(LDO5, 2, 4),
-       EXTERNAL_REQUESTOR(LDO6, 2, 5),
-       EXTERNAL_REQUESTOR(LDO7, 2, 6),
-       EXTERNAL_REQUESTOR(LDO8, 2, 7),
-       EXTERNAL_REQUESTOR(LDO9, 3, 0),
-       EXTERNAL_REQUESTOR(LDOLN, 3, 1),
-       EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
-};
-
 static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
        {
                .reg_bits = 8,
@@ -92,6 +46,133 @@ static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = {
        },
 };
 
+static const struct regmap_irq tps65917_irqs[] = {
+       /* INT1 IRQs */
+       [TPS65917_RESERVED1] = {
+               .mask = TPS65917_RESERVED,
+       },
+       [TPS65917_PWRON_IRQ] = {
+               .mask = TPS65917_INT1_STATUS_PWRON,
+       },
+       [TPS65917_LONG_PRESS_KEY_IRQ] = {
+               .mask = TPS65917_INT1_STATUS_LONG_PRESS_KEY,
+       },
+       [TPS65917_RESERVED2] = {
+               .mask = TPS65917_RESERVED,
+       },
+       [TPS65917_PWRDOWN_IRQ] = {
+               .mask = TPS65917_INT1_STATUS_PWRDOWN,
+       },
+       [TPS65917_HOTDIE_IRQ] = {
+               .mask = TPS65917_INT1_STATUS_HOTDIE,
+       },
+       [TPS65917_VSYS_MON_IRQ] = {
+               .mask = TPS65917_INT1_STATUS_VSYS_MON,
+       },
+       [TPS65917_RESERVED3] = {
+               .mask = TPS65917_RESERVED,
+       },
+       /* INT2 IRQs*/
+       [TPS65917_RESERVED4] = {
+               .mask = TPS65917_RESERVED,
+               .reg_offset = 1,
+       },
+       [TPS65917_OTP_ERROR_IRQ] = {
+               .mask = TPS65917_INT2_STATUS_OTP_ERROR,
+               .reg_offset = 1,
+       },
+       [TPS65917_WDT_IRQ] = {
+               .mask = TPS65917_INT2_STATUS_WDT,
+               .reg_offset = 1,
+       },
+       [TPS65917_RESERVED5] = {
+               .mask = TPS65917_RESERVED,
+               .reg_offset = 1,
+       },
+       [TPS65917_RESET_IN_IRQ] = {
+               .mask = TPS65917_INT2_STATUS_RESET_IN,
+               .reg_offset = 1,
+       },
+       [TPS65917_FSD_IRQ] = {
+               .mask = TPS65917_INT2_STATUS_FSD,
+               .reg_offset = 1,
+       },
+       [TPS65917_SHORT_IRQ] = {
+               .mask = TPS65917_INT2_STATUS_SHORT,
+               .reg_offset = 1,
+       },
+       [TPS65917_RESERVED6] = {
+               .mask = TPS65917_RESERVED,
+               .reg_offset = 1,
+       },
+       /* INT3 IRQs */
+       [TPS65917_GPADC_AUTO_0_IRQ] = {
+               .mask = TPS65917_INT3_STATUS_GPADC_AUTO_0,
+               .reg_offset = 2,
+       },
+       [TPS65917_GPADC_AUTO_1_IRQ] = {
+               .mask = TPS65917_INT3_STATUS_GPADC_AUTO_1,
+               .reg_offset = 2,
+       },
+       [TPS65917_GPADC_EOC_SW_IRQ] = {
+               .mask = TPS65917_INT3_STATUS_GPADC_EOC_SW,
+               .reg_offset = 2,
+       },
+       [TPS65917_RESREVED6] = {
+               .mask = TPS65917_RESERVED6,
+               .reg_offset = 2,
+       },
+       [TPS65917_RESERVED7] = {
+               .mask = TPS65917_RESERVED,
+               .reg_offset = 2,
+       },
+       [TPS65917_RESERVED8] = {
+               .mask = TPS65917_RESERVED,
+               .reg_offset = 2,
+       },
+       [TPS65917_RESERVED9] = {
+               .mask = TPS65917_RESERVED,
+               .reg_offset = 2,
+       },
+       [TPS65917_VBUS_IRQ] = {
+               .mask = TPS65917_INT3_STATUS_VBUS,
+               .reg_offset = 2,
+       },
+       /* INT4 IRQs */
+       [TPS65917_GPIO_0_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_0,
+               .reg_offset = 3,
+       },
+       [TPS65917_GPIO_1_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_1,
+               .reg_offset = 3,
+       },
+       [TPS65917_GPIO_2_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_2,
+               .reg_offset = 3,
+       },
+       [TPS65917_GPIO_3_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_3,
+               .reg_offset = 3,
+       },
+       [TPS65917_GPIO_4_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_4,
+               .reg_offset = 3,
+       },
+       [TPS65917_GPIO_5_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_5,
+               .reg_offset = 3,
+       },
+       [TPS65917_GPIO_6_IRQ] = {
+               .mask = TPS65917_INT4_STATUS_GPIO_6,
+               .reg_offset = 3,
+       },
+       [TPS65917_RESERVED10] = {
+               .mask = TPS65917_RESERVED10,
+               .reg_offset = 3,
+       },
+};
+
 static const struct regmap_irq palmas_irqs[] = {
        /* INT1 IRQs */
        [PALMAS_CHARG_DET_N_VBUS_OVV_IRQ] = {
@@ -232,13 +313,26 @@ static struct regmap_irq_chip palmas_irq_chip = {
                        PALMAS_INT1_MASK),
 };
 
+static struct regmap_irq_chip tps65917_irq_chip = {
+       .name = "tps65917",
+       .irqs = tps65917_irqs,
+       .num_irqs = ARRAY_SIZE(tps65917_irqs),
+
+       .num_regs = 4,
+       .irq_reg_stride = 5,
+       .status_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE,
+                       PALMAS_INT1_STATUS),
+       .mask_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE,
+                       PALMAS_INT1_MASK),
+};
+
 int palmas_ext_control_req_config(struct palmas *palmas,
        enum palmas_external_requestor_id id,  int ext_ctrl, bool enable)
 {
+       struct palmas_pmic_driver_data *pmic_ddata = palmas->pmic_ddata;
        int preq_mask_bit = 0;
        int reg_add = 0;
-       int bit_pos;
-       int ret;
+       int bit_pos, ret;
 
        if (!(ext_ctrl & PALMAS_EXT_REQ))
                return 0;
@@ -257,8 +351,8 @@ int palmas_ext_control_req_config(struct palmas *palmas,
                preq_mask_bit = 2;
        }
 
-       bit_pos = sleep_req_info[id].bit_pos;
-       reg_add += sleep_req_info[id].reg_offset;
+       bit_pos = pmic_ddata->sleep_req_info[id].bit_pos;
+       reg_add += pmic_ddata->sleep_req_info[id].reg_offset;
        if (enable)
                ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
                                reg_add, BIT(bit_pos), BIT(bit_pos));
@@ -357,14 +451,38 @@ static void palmas_power_off(void)
 static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST;
 static unsigned int tps659038_features;
 
+struct palmas_driver_data {
+       unsigned int *features;
+       struct regmap_irq_chip *irq_chip;
+};
+
+static struct palmas_driver_data palmas_data = {
+       .features = &palmas_features,
+       .irq_chip = &palmas_irq_chip,
+};
+
+static struct palmas_driver_data tps659038_data = {
+       .features = &tps659038_features,
+       .irq_chip = &palmas_irq_chip,
+};
+
+static struct palmas_driver_data tps65917_data = {
+       .features = &tps659038_features,
+       .irq_chip = &tps65917_irq_chip,
+};
+
 static const struct of_device_id of_palmas_match_tbl[] = {
        {
                .compatible = "ti,palmas",
-               .data = &palmas_features,
+               .data = &palmas_data,
        },
        {
                .compatible = "ti,tps659038",
-               .data = &tps659038_features,
+               .data = &tps659038_data,
+       },
+       {
+               .compatible = "ti,tps65917",
+               .data = &tps65917_data,
        },
        { },
 };
@@ -375,9 +493,10 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
 {
        struct palmas *palmas;
        struct palmas_platform_data *pdata;
+       struct palmas_driver_data *driver_data;
        struct device_node *node = i2c->dev.of_node;
        int ret = 0, i;
-       unsigned int reg, addr, *features;
+       unsigned int reg, addr;
        int slave;
        const struct of_device_id *match;
 
@@ -408,8 +527,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
        if (!match)
                return -ENODATA;
 
-       features = (unsigned int *)match->data;
-       palmas->features = *features;
+       driver_data = (struct palmas_driver_data *)match->data;
+       palmas->features = *driver_data->features;
 
        for (i = 0; i < PALMAS_NUM_CLIENTS; i++) {
                if (i == 0)
@@ -463,8 +582,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
        regmap_write(palmas->regmap[slave], addr, reg);
 
        ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
-                       IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
-                       &palmas->irq_data);
+                                 IRQF_ONESHOT | pdata->irq_flags, 0,
+                                 driver_data->irq_chip, &palmas->irq_data);
        if (ret < 0)
                goto err_i2c;
 
index 7a721d6..4e6c8c6 100644 (file)
@@ -52,7 +52,6 @@
 #define PM800_BUCK1_3          (0x3F)
 #define PM800_BUCK2            (0x40)
 #define PM800_BUCK3            (0x41)
-#define PM800_BUCK3            (0x41)
 #define PM800_BUCK4            (0x42)
 #define PM800_BUCK4_1          (0x43)
 #define PM800_BUCK4_2          (0x44)
index 789eb46..2dc8289 100644 (file)
@@ -198,6 +198,16 @@ config REGULATOR_DA9210
          converter 12A DC-DC Buck controlled through an I2C
          interface.
 
+config REGULATOR_DA9211
+       tristate "Dialog Semiconductor DA9211/DA9212 regulator"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         Say y here to support for the Dialog Semiconductor DA9211/DA9212.
+         The DA9211/DA9212 is a multi-phase synchronous step down
+         converter 12A DC-DC Buck controlled through an I2C
+         interface.
+
 config REGULATOR_DBX500_PRCMU
        bool
 
@@ -457,10 +467,10 @@ config REGULATOR_S2MPA01
         via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
 
 config REGULATOR_S2MPS11
-       tristate "Samsung S2MPS11/S2MPS14 voltage regulator"
+       tristate "Samsung S2MPS11/S2MPS14/S2MPU02 voltage regulator"
        depends on MFD_SEC_CORE
        help
-        This driver supports a Samsung S2MPS11/S2MPS14 voltage output
+        This driver supports a Samsung S2MPS11/S2MPS14/S2MPU02 voltage output
         regulator via I2C bus. The chip is comprised of high efficient Buck
         converters including Dual-Phase Buck converter, Buck-Boost converter,
         various LDOs.
index d461110..aa4a6aa 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_DA9052)        += da9052-regulator.o
 obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
 obj-$(CONFIG_REGULATOR_DA9063) += da9063-regulator.o
 obj-$(CONFIG_REGULATOR_DA9210) += da9210-regulator.o
+obj-$(CONFIG_REGULATOR_DA9211) += da9211-regulator.o
 obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
 obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
 obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
index c625468..1fda14e 100644 (file)
@@ -3037,28 +3037,12 @@ static int ab8500_regulator_register(struct platform_device *pdev,
        return 0;
 }
 
-static int
-ab8500_regulator_of_probe(struct platform_device *pdev,
-                         struct device_node *np)
-{
-       struct of_regulator_match *match = abx500_regulator.match;
-       int err, i;
-
-       for (i = 0; i < abx500_regulator.info_size; i++) {
-               err = ab8500_regulator_register(
-                       pdev, match[i].init_data, i, match[i].of_node);
-               if (err)
-                       return err;
-       }
-
-       return 0;
-}
-
 static int ab8500_regulator_probe(struct platform_device *pdev)
 {
        struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
        struct device_node *np = pdev->dev.of_node;
-       int err;
+       struct of_regulator_match *match;
+       int err, i;
 
        if (!ab8500) {
                dev_err(&pdev->dev, "null mfd parent\n");
@@ -3075,24 +3059,20 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
                        "Error parsing regulator init data: %d\n", err);
                return err;
        }
-       return ab8500_regulator_of_probe(pdev, np);
-}
-
-static int ab8500_regulator_remove(struct platform_device *pdev)
-{
-       int err;
 
-       /* remove regulator debug */
-       err = ab8500_regulator_debug_exit(pdev);
-       if (err)
-               return err;
+       match = abx500_regulator.match;
+       for (i = 0; i < abx500_regulator.info_size; i++) {
+               err = ab8500_regulator_register(pdev, match[i].init_data, i,
+                                               match[i].of_node);
+               if (err)
+                       return err;
+       }
 
        return 0;
 }
 
 static struct platform_driver ab8500_regulator_driver = {
        .probe = ab8500_regulator_probe,
-       .remove = ab8500_regulator_remove,
        .driver         = {
                .name   = "ab8500-regulator",
                .owner  = THIS_MODULE,
index b92d7dd..afd06f9 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * act8865-regulator.c - Voltage regulation for the active-semi ACT8865
- * http://www.active-semi.com/sheets/ACT8865_Datasheet.pdf
+ * act8865-regulator.c - Voltage regulation for active-semi ACT88xx PMUs
+ *
+ * http://www.active-semi.com/products/power-management-units/act88xx/
  *
  * Copyright (C) 2013 Atmel Corporation
  *
 #include <linux/regulator/of_regulator.h>
 #include <linux/regmap.h>
 
+/*
+ * ACT8846 Global Register Map.
+ */
+#define        ACT8846_SYS0            0x00
+#define        ACT8846_SYS1            0x01
+#define        ACT8846_REG1_VSET       0x10
+#define        ACT8846_REG1_CTRL       0x12
+#define        ACT8846_REG2_VSET0      0x20
+#define        ACT8846_REG2_VSET1      0x21
+#define        ACT8846_REG2_CTRL       0x22
+#define        ACT8846_REG3_VSET0      0x30
+#define        ACT8846_REG3_VSET1      0x31
+#define        ACT8846_REG3_CTRL       0x32
+#define        ACT8846_REG4_VSET0      0x40
+#define        ACT8846_REG4_VSET1      0x41
+#define        ACT8846_REG4_CTRL       0x42
+#define        ACT8846_REG5_VSET       0x50
+#define        ACT8846_REG5_CTRL       0x51
+#define        ACT8846_REG6_VSET       0x58
+#define        ACT8846_REG6_CTRL       0x59
+#define        ACT8846_REG7_VSET       0x60
+#define        ACT8846_REG7_CTRL       0x61
+#define        ACT8846_REG8_VSET       0x68
+#define        ACT8846_REG8_CTRL       0x69
+#define        ACT8846_REG9_VSET       0x70
+#define        ACT8846_REG9_CTRL       0x71
+#define        ACT8846_REG10_VSET      0x80
+#define        ACT8846_REG10_CTRL      0x81
+#define        ACT8846_REG11_VSET      0x90
+#define        ACT8846_REG11_CTRL      0x91
+#define        ACT8846_REG12_VSET      0xa0
+#define        ACT8846_REG12_CTRL      0xa1
+#define        ACT8846_REG13_CTRL      0xb1
+
 /*
  * ACT8865 Global Register Map.
  */
@@ -70,7 +105,7 @@ static const struct regmap_config act8865_regmap_config = {
        .val_bits = 8,
 };
 
-static const struct regulator_linear_range act8865_volatge_ranges[] = {
+static const struct regulator_linear_range act8865_voltage_ranges[] = {
        REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
        REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
        REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
@@ -86,114 +121,70 @@ static struct regulator_ops act8865_ops = {
        .is_enabled             = regulator_is_enabled_regmap,
 };
 
-static const struct regulator_desc act8865_reg[] = {
-       {
-               .name = "DCDC_REG1",
-               .id = ACT8865_ID_DCDC1,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_DCDC1_VSET1,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_DCDC1_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "DCDC_REG2",
-               .id = ACT8865_ID_DCDC2,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_DCDC2_VSET1,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_DCDC2_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "DCDC_REG3",
-               .id = ACT8865_ID_DCDC3,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_DCDC3_VSET1,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_DCDC3_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "LDO_REG1",
-               .id = ACT8865_ID_LDO1,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_LDO1_VSET,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_LDO1_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "LDO_REG2",
-               .id = ACT8865_ID_LDO2,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_LDO2_VSET,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_LDO2_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "LDO_REG3",
-               .id = ACT8865_ID_LDO3,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_LDO3_VSET,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_LDO3_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
-       {
-               .name = "LDO_REG4",
-               .id = ACT8865_ID_LDO4,
-               .ops = &act8865_ops,
-               .type = REGULATOR_VOLTAGE,
-               .n_voltages = ACT8865_VOLTAGE_NUM,
-               .linear_ranges = act8865_volatge_ranges,
-               .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
-               .vsel_reg = ACT8865_LDO4_VSET,
-               .vsel_mask = ACT8865_VSEL_MASK,
-               .enable_reg = ACT8865_LDO4_CTRL,
-               .enable_mask = ACT8865_ENA,
-               .owner = THIS_MODULE,
-       },
+#define ACT88xx_REG(_name, _family, _id, _vsel_reg)                    \
+       [_family##_ID_##_id] = {                                        \
+               .name                   = _name,                        \
+               .id                     = _family##_ID_##_id,           \
+               .type                   = REGULATOR_VOLTAGE,            \
+               .ops                    = &act8865_ops,                 \
+               .n_voltages             = ACT8865_VOLTAGE_NUM,          \
+               .linear_ranges          = act8865_voltage_ranges,       \
+               .n_linear_ranges        = ARRAY_SIZE(act8865_voltage_ranges), \
+               .vsel_reg               = _family##_##_id##_##_vsel_reg, \
+               .vsel_mask              = ACT8865_VSEL_MASK,            \
+               .enable_reg             = _family##_##_id##_CTRL,       \
+               .enable_mask            = ACT8865_ENA,                  \
+               .owner                  = THIS_MODULE,                  \
+       }
+
+static const struct regulator_desc act8846_regulators[] = {
+       ACT88xx_REG("REG1", ACT8846, REG1, VSET),
+       ACT88xx_REG("REG2", ACT8846, REG2, VSET0),
+       ACT88xx_REG("REG3", ACT8846, REG3, VSET0),
+       ACT88xx_REG("REG4", ACT8846, REG4, VSET0),
+       ACT88xx_REG("REG5", ACT8846, REG5, VSET),
+       ACT88xx_REG("REG6", ACT8846, REG6, VSET),
+       ACT88xx_REG("REG7", ACT8846, REG7, VSET),
+       ACT88xx_REG("REG8", ACT8846, REG8, VSET),
+       ACT88xx_REG("REG9", ACT8846, REG9, VSET),
+       ACT88xx_REG("REG10", ACT8846, REG10, VSET),
+       ACT88xx_REG("REG11", ACT8846, REG11, VSET),
+       ACT88xx_REG("REG12", ACT8846, REG12, VSET),
+};
+
+static const struct regulator_desc act8865_regulators[] = {
+       ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1),
+       ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1),
+       ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1),
+       ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET),
+       ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET),
+       ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET),
+       ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET),
 };
 
 #ifdef CONFIG_OF
 static const struct of_device_id act8865_dt_ids[] = {
-       { .compatible = "active-semi,act8865" },
+       { .compatible = "active-semi,act8846", .data = (void *)ACT8846 },
+       { .compatible = "active-semi,act8865", .data = (void *)ACT8865 },
        { }
 };
 MODULE_DEVICE_TABLE(of, act8865_dt_ids);
 
+static struct of_regulator_match act8846_matches[] = {
+       [ACT8846_ID_REG1]       = { .name = "REG1" },
+       [ACT8846_ID_REG2]       = { .name = "REG2" },
+       [ACT8846_ID_REG3]       = { .name = "REG3" },
+       [ACT8846_ID_REG4]       = { .name = "REG4" },
+       [ACT8846_ID_REG5]       = { .name = "REG5" },
+       [ACT8846_ID_REG6]       = { .name = "REG6" },
+       [ACT8846_ID_REG7]       = { .name = "REG7" },
+       [ACT8846_ID_REG8]       = { .name = "REG8" },
+       [ACT8846_ID_REG9]       = { .name = "REG9" },
+       [ACT8846_ID_REG10]      = { .name = "REG10" },
+       [ACT8846_ID_REG11]      = { .name = "REG11" },
+       [ACT8846_ID_REG12]      = { .name = "REG12" },
+};
+
 static struct of_regulator_match act8865_matches[] = {
        [ACT8865_ID_DCDC1]      = { .name = "DCDC_REG1"},
        [ACT8865_ID_DCDC2]      = { .name = "DCDC_REG2"},
@@ -206,11 +197,13 @@ static struct of_regulator_match act8865_matches[] = {
 
 static int act8865_pdata_from_dt(struct device *dev,
                                 struct device_node **of_node,
-                                struct act8865_platform_data *pdata)
+                                struct act8865_platform_data *pdata,
+                                unsigned long type)
 {
-       int matched, i;
+       int matched, i, num_matches;
        struct device_node *np;
        struct act8865_regulator_data *regulator;
+       struct of_regulator_match *matches;
 
        np = of_get_child_by_name(dev->of_node, "regulators");
        if (!np) {
@@ -218,26 +211,39 @@ static int act8865_pdata_from_dt(struct device *dev,
                return -EINVAL;
        }
 
-       matched = of_regulator_match(dev, np,
-                               act8865_matches, ARRAY_SIZE(act8865_matches));
+       switch (type) {
+       case ACT8846:
+               matches = act8846_matches;
+               num_matches = ARRAY_SIZE(act8846_matches);
+               break;
+       case ACT8865:
+               matches = act8865_matches;
+               num_matches = ARRAY_SIZE(act8865_matches);
+               break;
+       default:
+               dev_err(dev, "invalid device id %lu\n", type);
+               return -EINVAL;
+       }
+
+       matched = of_regulator_match(dev, np, matches, num_matches);
        of_node_put(np);
        if (matched <= 0)
                return matched;
 
        pdata->regulators = devm_kzalloc(dev,
-                               sizeof(struct act8865_regulator_data) *
-                               ARRAY_SIZE(act8865_matches), GFP_KERNEL);
+                                        sizeof(struct act8865_regulator_data) *
+                                        num_matches, GFP_KERNEL);
        if (!pdata->regulators)
                return -ENOMEM;
 
-       pdata->num_regulators = matched;
+       pdata->num_regulators = num_matches;
        regulator = pdata->regulators;
 
-       for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) {
+       for (i = 0; i < num_matches; i++) {
                regulator->id = i;
-               regulator->name = act8865_matches[i].name;
-               regulator->platform_data = act8865_matches[i].init_data;
-               of_node[i] = act8865_matches[i].of_node;
+               regulator->name = matches[i].name;
+               regulator->platform_data = matches[i].init_data;
+               of_node[i] = matches[i].of_node;
                regulator++;
        }
 
@@ -246,42 +252,84 @@ static int act8865_pdata_from_dt(struct device *dev,
 #else
 static inline int act8865_pdata_from_dt(struct device *dev,
                                        struct device_node **of_node,
-                                       struct act8865_platform_data *pdata)
+                                       struct act8865_platform_data *pdata,
+                                       unsigned long type)
 {
        return 0;
 }
 #endif
 
+static struct regulator_init_data
+*act8865_get_init_data(int id, struct act8865_platform_data *pdata)
+{
+       int i;
+
+       if (!pdata)
+               return NULL;
+
+       for (i = 0; i < pdata->num_regulators; i++) {
+               if (pdata->regulators[i].id == id)
+                       return pdata->regulators[i].platform_data;
+       }
+
+       return NULL;
+}
+
 static int act8865_pmic_probe(struct i2c_client *client,
-                          const struct i2c_device_id *i2c_id)
+                             const struct i2c_device_id *i2c_id)
 {
-       struct regulator_dev *rdev;
+       static const struct regulator_desc *regulators;
+       struct act8865_platform_data pdata_of, *pdata;
        struct device *dev = &client->dev;
-       struct act8865_platform_data *pdata = dev_get_platdata(dev);
-       struct regulator_config config = { };
+       struct device_node **of_node;
+       int i, ret, num_regulators;
        struct act8865 *act8865;
-       struct device_node *of_node[ACT8865_REG_NUM];
-       int i, id;
-       int ret = -EINVAL;
-       int error;
+       unsigned long type;
+
+       pdata = dev_get_platdata(dev);
 
        if (dev->of_node && !pdata) {
                const struct of_device_id *id;
-               struct act8865_platform_data pdata_of;
 
                id = of_match_device(of_match_ptr(act8865_dt_ids), dev);
                if (!id)
                        return -ENODEV;
 
-               ret = act8865_pdata_from_dt(dev, of_node, &pdata_of);
+               type = (unsigned long) id->data;
+       } else {
+               type = i2c_id->driver_data;
+       }
+
+       switch (type) {
+       case ACT8846:
+               regulators = act8846_regulators;
+               num_regulators = ARRAY_SIZE(act8846_regulators);
+               break;
+       case ACT8865:
+               regulators = act8865_regulators;
+               num_regulators = ARRAY_SIZE(act8865_regulators);
+               break;
+       default:
+               dev_err(dev, "invalid device id %lu\n", type);
+               return -EINVAL;
+       }
+
+       of_node = devm_kzalloc(dev, sizeof(struct device_node *) *
+                              num_regulators, GFP_KERNEL);
+       if (!of_node)
+               return -ENOMEM;
+
+       if (dev->of_node && !pdata) {
+               ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, type);
                if (ret < 0)
                        return ret;
 
                pdata = &pdata_of;
        }
 
-       if (pdata->num_regulators > ACT8865_REG_NUM) {
-               dev_err(dev, "Too many regulators found!\n");
+       if (pdata->num_regulators > num_regulators) {
+               dev_err(dev, "too many regulators: %d\n",
+                       pdata->num_regulators);
                return -EINVAL;
        }
 
@@ -291,39 +339,40 @@ static int act8865_pmic_probe(struct i2c_client *client,
 
        act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config);
        if (IS_ERR(act8865->regmap)) {
-               error = PTR_ERR(act8865->regmap);
+               ret = PTR_ERR(act8865->regmap);
                dev_err(&client->dev, "Failed to allocate register map: %d\n",
-                       error);
-               return error;
+                       ret);
+               return ret;
        }
 
        /* Finally register devices */
-       for (i = 0; i < ACT8865_REG_NUM; i++) {
-
-               id = pdata->regulators[i].id;
+       for (i = 0; i < num_regulators; i++) {
+               const struct regulator_desc *desc = &regulators[i];
+               struct regulator_config config = { };
+               struct regulator_dev *rdev;
 
                config.dev = dev;
-               config.init_data = pdata->regulators[i].platform_data;
+               config.init_data = act8865_get_init_data(desc->id, pdata);
                config.of_node = of_node[i];
                config.driver_data = act8865;
                config.regmap = act8865->regmap;
 
-               rdev = devm_regulator_register(&client->dev, &act8865_reg[i],
-                                              &config);
+               rdev = devm_regulator_register(&client->dev, desc, &config);
                if (IS_ERR(rdev)) {
-                       dev_err(dev, "failed to register %s\n",
-                               act8865_reg[id].name);
+                       dev_err(dev, "failed to register %s\n", desc->name);
                        return PTR_ERR(rdev);
                }
        }
 
        i2c_set_clientdata(client, act8865);
+       devm_kfree(dev, of_node);
 
        return 0;
 }
 
 static const struct i2c_device_id act8865_ids[] = {
-       { "act8865", 0 },
+       { .name = "act8846", .driver_data = ACT8846 },
+       { .name = "act8865", .driver_data = ACT8865 },
        { },
 };
 MODULE_DEVICE_TABLE(i2c, act8865_ids);
@@ -339,6 +388,6 @@ static struct i2c_driver act8865_pmic_driver = {
 
 module_i2c_driver(act8865_pmic_driver);
 
-MODULE_DESCRIPTION("active-semi act8865 voltage regulator driver");
+MODULE_DESCRIPTION("active-semi act88xx voltage regulator driver");
 MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
 MODULE_LICENSE("GPL v2");
index 04f262a..4c9db58 100644 (file)
@@ -143,8 +143,6 @@ static struct regulator_ops arizona_ldo1_ops = {
        .map_voltage = regulator_map_voltage_linear,
        .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage_sel = regulator_set_voltage_sel_regmap,
-       .get_bypass = regulator_get_bypass_regmap,
-       .set_bypass = regulator_set_bypass_regmap,
 };
 
 static const struct regulator_desc arizona_ldo1 = {
index ad9e0c9..b68f05f 100644 (file)
@@ -219,7 +219,7 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
        {
                .regulator_id = AS3722_REGULATOR_ID_LDO3,
                .name = "as3722-ldo3",
-               .name = "vin-ldo3-4",
+               .sname = "vin-ldo3-4",
                .vsel_reg = AS3722_LDO3_VOLTAGE_REG,
                .vsel_mask = AS3722_LDO3_VSEL_MASK,
                .enable_reg = AS3722_LDOCONTROL0_REG,
@@ -231,7 +231,7 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
        {
                .regulator_id = AS3722_REGULATOR_ID_LDO4,
                .name = "as3722-ldo4",
-               .name = "vin-ldo3-4",
+               .sname = "vin-ldo3-4",
                .vsel_reg = AS3722_LDO4_VOLTAGE_REG,
                .vsel_mask = AS3722_LDO_VSEL_MASK,
                .enable_reg = AS3722_LDOCONTROL0_REG,
index 58ece59..5d1fd6f 100644 (file)
@@ -331,10 +331,8 @@ static struct bcm590xx_board *bcm590xx_parse_dt_reg_data(
        }
 
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               dev_err(&pdev->dev, "failed to allocate regulator board data\n");
+       if (!data)
                return NULL;
-       }
 
        np = of_node_get(np);
        regulators = of_get_child_by_name(np, "regulators");
@@ -379,10 +377,8 @@ static int bcm590xx_probe(struct platform_device *pdev)
                                              &bcm590xx_reg_matches);
 
        pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL);
-       if (!pmu) {
-               dev_err(&pdev->dev, "Memory allocation failed for pmu\n");
+       if (!pmu)
                return -ENOMEM;
-       }
 
        pmu->mfd = bcm590xx;
 
@@ -390,17 +386,13 @@ static int bcm590xx_probe(struct platform_device *pdev)
 
        pmu->desc = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS *
                        sizeof(struct regulator_desc), GFP_KERNEL);
-       if (!pmu->desc) {
-               dev_err(&pdev->dev, "Memory alloc fails for desc\n");
+       if (!pmu->desc)
                return -ENOMEM;
-       }
 
        pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS *
                        sizeof(struct bcm590xx_info *), GFP_KERNEL);
-       if (!pmu->info) {
-               dev_err(&pdev->dev, "Memory alloc fails for info\n");
+       if (!pmu->info)
                return -ENOMEM;
-       }
 
        info = bcm590xx_regs;
 
index 4c1f999..a3c3785 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
@@ -77,7 +78,7 @@ struct regulator_map {
  */
 struct regulator_enable_gpio {
        struct list_head list;
-       int gpio;
+       struct gpio_desc *gpiod;
        u32 enable_count;       /* a number of enabled shared GPIO */
        u32 request_count;      /* a number of requested shared GPIO */
        unsigned int ena_gpio_invert:1;
@@ -846,7 +847,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
            rdev->constraints->min_uV == rdev->constraints->max_uV) {
                int current_uV = _regulator_get_voltage(rdev);
                if (current_uV < 0) {
-                       rdev_err(rdev, "failed to get the current voltage\n");
+                       rdev_err(rdev,
+                                "failed to get the current voltage(%d)\n",
+                                current_uV);
                        return current_uV;
                }
                if (current_uV < rdev->constraints->min_uV ||
@@ -856,8 +859,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
                                rdev->constraints->max_uV);
                        if (ret < 0) {
                                rdev_err(rdev,
-                                       "failed to apply %duV constraint\n",
-                                       rdev->constraints->min_uV);
+                                       "failed to apply %duV constraint(%d)\n",
+                                       rdev->constraints->min_uV, ret);
                                return ret;
                        }
                }
@@ -1660,10 +1663,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
                                const struct regulator_config *config)
 {
        struct regulator_enable_gpio *pin;
+       struct gpio_desc *gpiod;
        int ret;
 
+       gpiod = gpio_to_desc(config->ena_gpio);
+
        list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
-               if (pin->gpio == config->ena_gpio) {
+               if (pin->gpiod == gpiod) {
                        rdev_dbg(rdev, "GPIO %d is already used\n",
                                config->ena_gpio);
                        goto update_ena_gpio_to_rdev;
@@ -1682,7 +1688,7 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
                return -ENOMEM;
        }
 
-       pin->gpio = config->ena_gpio;
+       pin->gpiod = gpiod;
        pin->ena_gpio_invert = config->ena_gpio_invert;
        list_add(&pin->list, &regulator_ena_gpio_list);
 
@@ -1701,10 +1707,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
 
        /* Free the GPIO only in case of no use */
        list_for_each_entry_safe(pin, n, &regulator_ena_gpio_list, list) {
-               if (pin->gpio == rdev->ena_pin->gpio) {
+               if (pin->gpiod == rdev->ena_pin->gpiod) {
                        if (pin->request_count <= 1) {
                                pin->request_count = 0;
-                               gpio_free(pin->gpio);
+                               gpiod_put(pin->gpiod);
                                list_del(&pin->list);
                                kfree(pin);
                        } else {
@@ -1732,8 +1738,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
        if (enable) {
                /* Enable GPIO at initial use */
                if (pin->enable_count == 0)
-                       gpio_set_value_cansleep(pin->gpio,
-                                               !pin->ena_gpio_invert);
+                       gpiod_set_value_cansleep(pin->gpiod,
+                                                !pin->ena_gpio_invert);
 
                pin->enable_count++;
        } else {
@@ -1744,8 +1750,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable)
 
                /* Disable GPIO if not used */
                if (pin->enable_count <= 1) {
-                       gpio_set_value_cansleep(pin->gpio,
-                                               pin->ena_gpio_invert);
+                       gpiod_set_value_cansleep(pin->gpiod,
+                                                pin->ena_gpio_invert);
                        pin->enable_count = 0;
                }
        }
@@ -2180,7 +2186,13 @@ int regulator_count_voltages(struct regulator *regulator)
 {
        struct regulator_dev    *rdev = regulator->rdev;
 
-       return rdev->desc->n_voltages ? : -EINVAL;
+       if (rdev->desc->n_voltages)
+               return rdev->desc->n_voltages;
+
+       if (!rdev->supply)
+               return -EINVAL;
+
+       return regulator_count_voltages(rdev->supply);
 }
 EXPORT_SYMBOL_GPL(regulator_count_voltages);
 
@@ -2203,12 +2215,17 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
        if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector)
                return rdev->desc->fixed_uV;
 
-       if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+       if (ops->list_voltage) {
+               if (selector >= rdev->desc->n_voltages)
+                       return -EINVAL;
+               mutex_lock(&rdev->mutex);
+               ret = ops->list_voltage(rdev, selector);
+               mutex_unlock(&rdev->mutex);
+       } else if (rdev->supply) {
+               ret = regulator_list_voltage(rdev->supply, selector);
+       } else {
                return -EINVAL;
-
-       mutex_lock(&rdev->mutex);
-       ret = ops->list_voltage(rdev, selector);
-       mutex_unlock(&rdev->mutex);
+       }
 
        if (ret > 0) {
                if (ret < rdev->constraints->min_uV)
@@ -2221,6 +2238,77 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
 }
 EXPORT_SYMBOL_GPL(regulator_list_voltage);
 
+/**
+ * regulator_get_regmap - get the regulator's register map
+ * @regulator: regulator source
+ *
+ * Returns the register map for the given regulator, or an ERR_PTR value
+ * if the regulator doesn't use regmap.
+ */
+struct regmap *regulator_get_regmap(struct regulator *regulator)
+{
+       struct regmap *map = regulator->rdev->regmap;
+
+       return map ? map : ERR_PTR(-EOPNOTSUPP);
+}
+
+/**
+ * regulator_get_hardware_vsel_register - get the HW voltage selector register
+ * @regulator: regulator source
+ * @vsel_reg: voltage selector register, output parameter
+ * @vsel_mask: mask for voltage selector bitfield, output parameter
+ *
+ * Returns the hardware register offset and bitmask used for setting the
+ * regulator voltage. This might be useful when configuring voltage-scaling
+ * hardware or firmware that can make I2C requests behind the kernel's back,
+ * for example.
+ *
+ * On success, the output parameters @vsel_reg and @vsel_mask are filled in
+ * and 0 is returned, otherwise a negative errno is returned.
+ */
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+                                        unsigned *vsel_reg,
+                                        unsigned *vsel_mask)
+{
+       struct regulator_dev    *rdev = regulator->rdev;
+       struct regulator_ops    *ops = rdev->desc->ops;
+
+       if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+               return -EOPNOTSUPP;
+
+        *vsel_reg = rdev->desc->vsel_reg;
+        *vsel_mask = rdev->desc->vsel_mask;
+
+        return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register);
+
+/**
+ * regulator_list_hardware_vsel - get the HW-specific register value for a selector
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ *
+ * Converts the selector to a hardware-specific voltage selector that can be
+ * directly written to the regulator registers. The address of the voltage
+ * register can be determined by calling @regulator_get_hardware_vsel_register.
+ *
+ * On error a negative errno is returned.
+ */
+int regulator_list_hardware_vsel(struct regulator *regulator,
+                                unsigned selector)
+{
+       struct regulator_dev    *rdev = regulator->rdev;
+       struct regulator_ops    *ops = rdev->desc->ops;
+
+       if (selector >= rdev->desc->n_voltages)
+               return -EINVAL;
+       if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+               return -EOPNOTSUPP;
+
+       return selector;
+}
+EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel);
+
 /**
  * regulator_get_linear_step - return the voltage step size between VSEL values
  * @regulator: regulator source
@@ -2618,6 +2706,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
                ret = rdev->desc->ops->list_voltage(rdev, 0);
        } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) {
                ret = rdev->desc->fixed_uV;
+       } else if (rdev->supply) {
+               ret = regulator_get_voltage(rdev->supply);
        } else {
                return -EINVAL;
        }
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
new file mode 100644 (file)
index 0000000..1482ada
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * da9211-regulator.c - Regulator device driver for DA9211
+ * Copyright (C) 2014  Dialog Semiconductor Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/da9211.h>
+#include "da9211-regulator.h"
+
+#define DA9211_BUCK_MODE_SLEEP 1
+#define DA9211_BUCK_MODE_SYNC  2
+#define DA9211_BUCK_MODE_AUTO  3
+
+/* DA9211 REGULATOR IDs */
+#define DA9211_ID_BUCKA        0
+#define DA9211_ID_BUCKB        1
+
+struct da9211 {
+       struct device *dev;
+       struct regmap *regmap;
+       struct da9211_pdata *pdata;
+       struct regulator_dev *rdev[DA9211_MAX_REGULATORS];
+       int num_regulator;
+       int chip_irq;
+};
+
+static const struct regmap_range_cfg da9211_regmap_range[] = {
+       {
+               .selector_reg = DA9211_REG_PAGE_CON,
+               .selector_mask  = DA9211_REG_PAGE_MASK,
+               .selector_shift = DA9211_REG_PAGE_SHIFT,
+               .window_start = 0,
+               .window_len = 256,
+               .range_min = 0,
+               .range_max = 2*256,
+       },
+};
+
+static const struct regmap_config da9211_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .max_register = 2 * 256,
+       .ranges = da9211_regmap_range,
+       .num_ranges = ARRAY_SIZE(da9211_regmap_range),
+};
+
+/* Default limits measured in millivolts and milliamps */
+#define DA9211_MIN_MV          300
+#define DA9211_MAX_MV          1570
+#define DA9211_STEP_MV         10
+
+/* Current limits for buck (uA) indices corresponds with register values */
+static const int da9211_current_limits[] = {
+       2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000,
+       3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000
+};
+
+static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev)
+{
+       int id = rdev_get_id(rdev);
+       struct da9211 *chip = rdev_get_drvdata(rdev);
+       unsigned int data;
+       int ret, mode = 0;
+
+       ret = regmap_read(chip->regmap, DA9211_REG_BUCKA_CONF+id, &data);
+       if (ret < 0)
+               return ret;
+
+       switch (data & 0x03) {
+       case DA9211_BUCK_MODE_SYNC:
+               mode = REGULATOR_MODE_FAST;
+               break;
+       case DA9211_BUCK_MODE_AUTO:
+               mode = REGULATOR_MODE_NORMAL;
+               break;
+       case DA9211_BUCK_MODE_SLEEP:
+               mode = REGULATOR_MODE_STANDBY;
+               break;
+       }
+
+       return mode;
+}
+
+static int da9211_buck_set_mode(struct regulator_dev *rdev,
+                                       unsigned int mode)
+{
+       int id = rdev_get_id(rdev);
+       struct da9211 *chip = rdev_get_drvdata(rdev);
+       int val = 0;
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               val = DA9211_BUCK_MODE_SYNC;
+               break;
+       case REGULATOR_MODE_NORMAL:
+               val = DA9211_BUCK_MODE_AUTO;
+               break;
+       case REGULATOR_MODE_STANDBY:
+               val = DA9211_BUCK_MODE_SLEEP;
+               break;
+       }
+
+       return regmap_update_bits(chip->regmap, DA9211_REG_BUCKA_CONF+id,
+                                       0x03, val);
+}
+
+static int da9211_set_current_limit(struct regulator_dev *rdev, int min,
+                                   int max)
+{
+       int id = rdev_get_id(rdev);
+       struct da9211 *chip = rdev_get_drvdata(rdev);
+       int i;
+
+       /* search for closest to maximum */
+       for (i = ARRAY_SIZE(da9211_current_limits)-1; i >= 0; i--) {
+               if (min <= da9211_current_limits[i] &&
+                   max >= da9211_current_limits[i]) {
+                               return regmap_update_bits(chip->regmap,
+                                       DA9211_REG_BUCK_ILIM,
+                                       (0x0F << id*4), (i << id*4));
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int da9211_get_current_limit(struct regulator_dev *rdev)
+{
+       int id = rdev_get_id(rdev);
+       struct da9211 *chip = rdev_get_drvdata(rdev);
+       unsigned int data;
+       int ret;
+
+       ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data);
+       if (ret < 0)
+               return ret;
+
+       /* select one of 16 values: 0000 (2000mA) to 1111 (5000mA) */
+       data = (data >> id*4) & 0x0F;
+       return da9211_current_limits[data];
+}
+
+static struct regulator_ops da9211_buck_ops = {
+       .get_mode = da9211_buck_get_mode,
+       .set_mode = da9211_buck_set_mode,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .list_voltage = regulator_list_voltage_linear,
+       .set_current_limit = da9211_set_current_limit,
+       .get_current_limit = da9211_get_current_limit,
+};
+
+#define DA9211_BUCK(_id) \
+{\
+       .name = #_id,\
+       .ops = &da9211_buck_ops,\
+       .type = REGULATOR_VOLTAGE,\
+       .id = DA9211_ID_##_id,\
+       .n_voltages = (DA9211_MAX_MV - DA9211_MIN_MV) / DA9211_STEP_MV + 1,\
+       .min_uV = (DA9211_MIN_MV * 1000),\
+       .uV_step = (DA9211_STEP_MV * 1000),\
+       .enable_reg = DA9211_REG_BUCKA_CONT + DA9211_ID_##_id,\
+       .enable_mask = DA9211_BUCKA_EN,\
+       .vsel_reg = DA9211_REG_VBUCKA_A + DA9211_ID_##_id * 2,\
+       .vsel_mask = DA9211_VBUCK_MASK,\
+       .owner = THIS_MODULE,\
+}
+
+static struct regulator_desc da9211_regulators[] = {
+       DA9211_BUCK(BUCKA),
+       DA9211_BUCK(BUCKB),
+};
+
+static irqreturn_t da9211_irq_handler(int irq, void *data)
+{
+       struct da9211 *chip = data;
+       int reg_val, err, ret = IRQ_NONE;
+
+       err = regmap_read(chip->regmap, DA9211_REG_EVENT_B, &reg_val);
+       if (err < 0)
+               goto error_i2c;
+
+       if (reg_val & DA9211_E_OV_CURR_A) {
+               regulator_notifier_call_chain(chip->rdev[0],
+                       REGULATOR_EVENT_OVER_CURRENT,
+                       rdev_get_drvdata(chip->rdev[0]));
+
+               err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
+                       DA9211_E_OV_CURR_A);
+               if (err < 0)
+                       goto error_i2c;
+
+               ret = IRQ_HANDLED;
+       }
+
+       if (reg_val & DA9211_E_OV_CURR_B) {
+               regulator_notifier_call_chain(chip->rdev[1],
+                       REGULATOR_EVENT_OVER_CURRENT,
+                       rdev_get_drvdata(chip->rdev[1]));
+
+               err = regmap_write(chip->regmap, DA9211_REG_EVENT_B,
+                       DA9211_E_OV_CURR_B);
+               if (err < 0)
+                       goto error_i2c;
+
+               ret = IRQ_HANDLED;
+       }
+
+       return ret;
+
+error_i2c:
+       dev_err(chip->dev, "I2C error : %d\n", err);
+       return IRQ_NONE;
+}
+
+static int da9211_regulator_init(struct da9211 *chip)
+{
+       struct regulator_config config = { };
+       int i, ret;
+       unsigned int data;
+
+       ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data);
+       if (ret < 0) {
+               dev_err(chip->dev, "Failed to read CONTROL_E reg: %d\n", ret);
+               return ret;
+       }
+
+       data &= DA9211_SLAVE_SEL;
+       /* If configuration for 1/2 bucks is different between platform data
+        * and the register, driver should exit.
+        */
+       if ((chip->pdata->num_buck == 2 && data == 0x40)
+               || (chip->pdata->num_buck == 1 && data == 0x00)) {
+               if (data == 0)
+                       chip->num_regulator = 1;
+               else
+                       chip->num_regulator = 2;
+       } else {
+               dev_err(chip->dev, "Configuration is mismatched\n");
+               return -EINVAL;
+       }
+
+       for (i = 0; i < chip->num_regulator; i++) {
+               if (chip->pdata)
+                       config.init_data =
+                               &(chip->pdata->init_data[i]);
+
+               config.dev = chip->dev;
+               config.driver_data = chip;
+               config.regmap = chip->regmap;
+
+               chip->rdev[i] = devm_regulator_register(chip->dev,
+                       &da9211_regulators[i], &config);
+               if (IS_ERR(chip->rdev[i])) {
+                       dev_err(chip->dev,
+                               "Failed to register DA9211 regulator\n");
+                       return PTR_ERR(chip->rdev[i]);
+               }
+
+               if (chip->chip_irq != 0) {
+                       ret = regmap_update_bits(chip->regmap,
+                               DA9211_REG_MASK_B, DA9211_M_OV_CURR_A << i, 1);
+                       if (ret < 0) {
+                               dev_err(chip->dev,
+                                       "Failed to update mask reg: %d\n", ret);
+                               return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+/*
+ * I2C driver interface functions
+ */
+static int da9211_i2c_probe(struct i2c_client *i2c,
+               const struct i2c_device_id *id)
+{
+       struct da9211 *chip;
+       int error, ret;
+
+       chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL);
+
+       chip->dev = &i2c->dev;
+       chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config);
+       if (IS_ERR(chip->regmap)) {
+               error = PTR_ERR(chip->regmap);
+               dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+                       error);
+               return error;
+       }
+
+       i2c_set_clientdata(i2c, chip);
+
+       chip->pdata = i2c->dev.platform_data;
+       if (!chip->pdata) {
+               dev_err(&i2c->dev, "No platform init data supplied\n");
+               return -ENODEV;
+       }
+
+       chip->chip_irq = i2c->irq;
+
+       if (chip->chip_irq != 0) {
+               ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL,
+                                       da9211_irq_handler,
+                                       IRQF_TRIGGER_LOW|IRQF_ONESHOT,
+                                       "da9211", chip);
+               if (ret != 0) {
+                       dev_err(chip->dev, "Failed to request IRQ: %d\n",
+                               chip->chip_irq);
+                       return ret;
+               }
+       } else {
+               dev_warn(chip->dev, "No IRQ configured\n");
+       }
+
+       ret = da9211_regulator_init(chip);
+
+       if (ret < 0)
+               dev_err(&i2c->dev, "Failed to initialize regulator: %d\n", ret);
+
+       return ret;
+}
+
+static const struct i2c_device_id da9211_i2c_id[] = {
+       {"da9211", 0},
+       {},
+};
+
+MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
+
+static struct i2c_driver da9211_regulator_driver = {
+       .driver = {
+               .name = "da9211",
+               .owner = THIS_MODULE,
+       },
+       .probe = da9211_i2c_probe,
+       .id_table = da9211_i2c_id,
+};
+
+module_i2c_driver(da9211_regulator_driver);
+
+MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
+MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h
new file mode 100644 (file)
index 0000000..88b1769
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * da9211-regulator.h - Regulator definitions for DA9211
+ * Copyright (C) 2014  Dialog Semiconductor Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ */
+
+#ifndef __DA9211_REGISTERS_H__
+#define __DA9211_REGISTERS_H__
+
+/* Page selection */
+#define        DA9211_REG_PAGE_CON                     0x00
+
+/* System Control and Event Registers */
+#define        DA9211_REG_STATUS_A                     0x50
+#define        DA9211_REG_STATUS_B                     0x51
+#define        DA9211_REG_EVENT_A                      0x52
+#define        DA9211_REG_EVENT_B                      0x53
+#define        DA9211_REG_MASK_A                       0x54
+#define        DA9211_REG_MASK_B                       0x55
+#define        DA9211_REG_CONTROL_A            0x56
+
+/* GPIO Control Registers */
+#define        DA9211_REG_GPIO_0_1                     0x58
+#define        DA9211_REG_GPIO_2_3                     0x59
+#define        DA9211_REG_GPIO_4                       0x5A
+
+/* Regulator Registers */
+#define        DA9211_REG_BUCKA_CONT                   0x5D
+#define        DA9211_REG_BUCKB_CONT                   0x5E
+#define        DA9211_REG_BUCK_ILIM                    0xD0
+#define        DA9211_REG_BUCKA_CONF                   0xD1
+#define        DA9211_REG_BUCKB_CONF                   0xD2
+#define        DA9211_REG_BUCK_CONF                    0xD3
+#define        DA9211_REG_VBACKA_MAX                   0xD5
+#define        DA9211_REG_VBACKB_MAX                   0xD6
+#define        DA9211_REG_VBUCKA_A                             0xD7
+#define        DA9211_REG_VBUCKA_B                             0xD8
+#define        DA9211_REG_VBUCKB_A                             0xD9
+#define        DA9211_REG_VBUCKB_B                             0xDA
+
+/* I2C Interface Settings */
+#define DA9211_REG_INTERFACE                   0x105
+
+/* BUCK Phase Selection*/
+#define DA9211_REG_CONFIG_E                    0x147
+
+/*
+ * Registers bits
+ */
+/* DA9211_REG_PAGE_CON (addr=0x00) */
+#define        DA9211_REG_PAGE_SHIFT                   1
+#define        DA9211_REG_PAGE_MASK                    0x02
+/* On I2C registers 0x00 - 0xFF */
+#define        DA9211_REG_PAGE0                        0
+/* On I2C registers 0x100 - 0x1FF */
+#define        DA9211_REG_PAGE2                        2
+#define        DA9211_PAGE_WRITE_MODE                  0x00
+#define        DA9211_REPEAT_WRITE_MODE                0x40
+#define        DA9211_PAGE_REVERT                      0x80
+
+/* DA9211_REG_STATUS_A (addr=0x50) */
+#define        DA9211_GPI0                             0x01
+#define        DA9211_GPI1                             0x02
+#define        DA9211_GPI2                             0x04
+#define        DA9211_GPI3                             0x08
+#define        DA9211_GPI4                             0x10
+
+/* DA9211_REG_EVENT_A (addr=0x52) */
+#define        DA9211_E_GPI0                           0x01
+#define        DA9211_E_GPI1                           0x02
+#define        DA9211_E_GPI2                           0x04
+#define        DA9211_E_GPI3                           0x08
+#define        DA9211_E_GPI4                           0x10
+#define        DA9211_E_UVLO_IO                        0x40
+
+/* DA9211_REG_EVENT_B (addr=0x53) */
+#define        DA9211_E_PWRGOOD_A                      0x01
+#define        DA9211_E_PWRGOOD_B                      0x02
+#define        DA9211_E_TEMP_WARN                      0x04
+#define        DA9211_E_TEMP_CRIT                      0x08
+#define        DA9211_E_OV_CURR_A                      0x10
+#define        DA9211_E_OV_CURR_B                      0x20
+
+/* DA9211_REG_MASK_A (addr=0x54) */
+#define        DA9211_M_GPI0                           0x01
+#define        DA9211_M_GPI1                           0x02
+#define        DA9211_M_GPI2                           0x04
+#define        DA9211_M_GPI3                           0x08
+#define        DA9211_M_GPI4                           0x10
+#define        DA9211_M_UVLO_IO                        0x40
+
+/* DA9211_REG_MASK_B (addr=0x55) */
+#define        DA9211_M_PWRGOOD_A                      0x01
+#define        DA9211_M_PWRGOOD_B                      0x02
+#define        DA9211_M_TEMP_WARN                      0x04
+#define        DA9211_M_TEMP_CRIT                      0x08
+#define        DA9211_M_OV_CURR_A                      0x10
+#define        DA9211_M_OV_CURR_B                      0x20
+
+/* DA9211_REG_CONTROL_A (addr=0x56) */
+#define        DA9211_DEBOUNCING_SHIFT         0
+#define        DA9211_DEBOUNCING_MASK          0x07
+#define        DA9211_SLEW_RATE_SHIFT          3
+#define        DA9211_SLEW_RATE_A_MASK         0x18
+#define        DA9211_SLEW_RATE_B_SHIFT        5
+#define        DA9211_SLEW_RATE_B_MASK         0x60
+#define        DA9211_V_LOCK                           0x80
+
+/* DA9211_REG_GPIO_0_1 (addr=0x58) */
+#define        DA9211_GPIO0_PIN_SHIFT          0
+#define        DA9211_GPIO0_PIN_MASK           0x03
+#define        DA9211_GPIO0_PIN_GPI            0x00
+#define        DA9211_GPIO0_PIN_GPO_OD         0x02
+#define        DA9211_GPIO0_PIN_GPO            0x03
+#define        DA9211_GPIO0_TYPE                       0x04
+#define        DA9211_GPIO0_TYPE_GPI           0x00
+#define        DA9211_GPIO0_TYPE_GPO           0x04
+#define        DA9211_GPIO0_MODE                       0x08
+#define        DA9211_GPIO1_PIN_SHIFT          4
+#define        DA9211_GPIO1_PIN_MASK           0x30
+#define        DA9211_GPIO1_PIN_GPI            0x00
+#define        DA9211_GPIO1_PIN_VERROR         0x10
+#define        DA9211_GPIO1_PIN_GPO_OD         0x20
+#define        DA9211_GPIO1_PIN_GPO            0x30
+#define        DA9211_GPIO1_TYPE_SHIFT         0x40
+#define        DA9211_GPIO1_TYPE_GPI           0x00
+#define        DA9211_GPIO1_TYPE_GPO           0x40
+#define        DA9211_GPIO1_MODE                       0x80
+
+/* DA9211_REG_GPIO_2_3 (addr=0x59) */
+#define        DA9211_GPIO2_PIN_SHIFT          0
+#define        DA9211_GPIO2_PIN_MASK           0x03
+#define        DA9211_GPIO2_PIN_GPI            0x00
+#define        DA9211_GPIO5_PIN_BUCK_CLK       0x10
+#define        DA9211_GPIO2_PIN_GPO_OD         0x02
+#define        DA9211_GPIO2_PIN_GPO            0x03
+#define        DA9211_GPIO2_TYPE                       0x04
+#define        DA9211_GPIO2_TYPE_GPI           0x00
+#define        DA9211_GPIO2_TYPE_GPO           0x04
+#define        DA9211_GPIO2_MODE                       0x08
+#define        DA9211_GPIO3_PIN_SHIFT          4
+#define        DA9211_GPIO3_PIN_MASK           0x30
+#define        DA9211_GPIO3_PIN_GPI            0x00
+#define        DA9211_GPIO3_PIN_IERROR         0x10
+#define        DA9211_GPIO3_PIN_GPO_OD         0x20
+#define        DA9211_GPIO3_PIN_GPO            0x30
+#define        DA9211_GPIO3_TYPE_SHIFT         0x40
+#define        DA9211_GPIO3_TYPE_GPI           0x00
+#define        DA9211_GPIO3_TYPE_GPO           0x40
+#define        DA9211_GPIO3_MODE                       0x80
+
+/* DA9211_REG_GPIO_4 (addr=0x5A) */
+#define        DA9211_GPIO4_PIN_SHIFT          0
+#define        DA9211_GPIO4_PIN_MASK           0x03
+#define        DA9211_GPIO4_PIN_GPI            0x00
+#define        DA9211_GPIO4_PIN_GPO_OD         0x02
+#define        DA9211_GPIO4_PIN_GPO            0x03
+#define        DA9211_GPIO4_TYPE                       0x04
+#define        DA9211_GPIO4_TYPE_GPI           0x00
+#define        DA9211_GPIO4_TYPE_GPO           0x04
+#define        DA9211_GPIO4_MODE                       0x08
+
+/* DA9211_REG_BUCKA_CONT (addr=0x5D) */
+#define        DA9211_BUCKA_EN                         0x01
+#define        DA9211_BUCKA_GPI_SHIFT          1
+#define DA9211_BUCKA_GPI_MASK          0x06
+#define        DA9211_BUCKA_GPI_OFF            0x00
+#define        DA9211_BUCKA_GPI_GPIO0          0x02
+#define        DA9211_BUCKA_GPI_GPIO1          0x04
+#define        DA9211_BUCKA_GPI_GPIO3          0x06
+#define        DA9211_BUCKA_PD_DIS                     0x08
+#define        DA9211_VBUCKA_SEL                       0x10
+#define        DA9211_VBUCKA_SEL_A                     0x00
+#define        DA9211_VBUCKA_SEL_B                     0x10
+#define        DA9211_VBUCKA_GPI_SHIFT         5
+#define        DA9211_VBUCKA_GPI_MASK          0x60
+#define        DA9211_VBUCKA_GPI_OFF           0x00
+#define        DA9211_VBUCKA_GPI_GPIO1         0x20
+#define        DA9211_VBUCKA_GPI_GPIO2         0x40
+#define        DA9211_VBUCKA_GPI_GPIO4         0x60
+
+/* DA9211_REG_BUCKB_CONT (addr=0x5E) */
+#define        DA9211_BUCKB_EN                         0x01
+#define        DA9211_BUCKB_GPI_SHIFT          1
+#define DA9211_BUCKB_GPI_MASK          0x06
+#define        DA9211_BUCKB_GPI_OFF            0x00
+#define        DA9211_BUCKB_GPI_GPIO0          0x02
+#define        DA9211_BUCKB_GPI_GPIO1          0x04
+#define        DA9211_BUCKB_GPI_GPIO3          0x06
+#define        DA9211_BUCKB_PD_DIS                     0x08
+#define        DA9211_VBUCKB_SEL                       0x10
+#define        DA9211_VBUCKB_SEL_A                     0x00
+#define        DA9211_VBUCKB_SEL_B                     0x10
+#define        DA9211_VBUCKB_GPI_SHIFT         5
+#define        DA9211_VBUCKB_GPI_MASK          0x60
+#define        DA9211_VBUCKB_GPI_OFF           0x00
+#define        DA9211_VBUCKB_GPI_GPIO1         0x20
+#define        DA9211_VBUCKB_GPI_GPIO2         0x40
+#define        DA9211_VBUCKB_GPI_GPIO4         0x60
+
+/* DA9211_REG_BUCK_ILIM (addr=0xD0) */
+#define DA9211_BUCKA_ILIM_SHIFT                        0
+#define DA9211_BUCKA_ILIM_MASK                 0x0F
+#define DA9211_BUCKB_ILIM_SHIFT                        4
+#define DA9211_BUCKB_ILIM_MASK                 0xF0
+
+/* DA9211_REG_BUCKA_CONF (addr=0xD1) */
+#define DA9211_BUCKA_MODE_SHIFT                        0
+#define DA9211_BUCKA_MODE_MASK                 0x03
+#define        DA9211_BUCKA_MODE_MANUAL                0x00
+#define        DA9211_BUCKA_MODE_SLEEP                 0x01
+#define        DA9211_BUCKA_MODE_SYNC                  0x02
+#define        DA9211_BUCKA_MODE_AUTO                  0x03
+#define DA9211_BUCKA_UP_CTRL_SHIFT             2
+#define DA9211_BUCKA_UP_CTRL_MASK              0x1C
+#define DA9211_BUCKA_DOWN_CTRL_SHIFT   5
+#define DA9211_BUCKA_DOWN_CTRL_MASK            0xE0
+
+/* DA9211_REG_BUCKB_CONF (addr=0xD2) */
+#define DA9211_BUCKB_MODE_SHIFT                        0
+#define DA9211_BUCKB_MODE_MASK                 0x03
+#define        DA9211_BUCKB_MODE_MANUAL                0x00
+#define        DA9211_BUCKB_MODE_SLEEP                 0x01
+#define        DA9211_BUCKB_MODE_SYNC                  0x02
+#define        DA9211_BUCKB_MODE_AUTO                  0x03
+#define DA9211_BUCKB_UP_CTRL_SHIFT             2
+#define DA9211_BUCKB_UP_CTRL_MASK              0x1C
+#define DA9211_BUCKB_DOWN_CTRL_SHIFT   5
+#define DA9211_BUCKB_DOWN_CTRL_MASK            0xE0
+
+/* DA9211_REG_BUCK_CONF (addr=0xD3) */
+#define DA9211_PHASE_SEL_A_SHIFT               0
+#define DA9211_PHASE_SEL_A_MASK                        0x03
+#define DA9211_PHASE_SEL_B_SHIFT               2
+#define DA9211_PHASE_SEL_B_MASK                        0x04
+#define DA9211_PH_SH_EN_A_SHIFT                        3
+#define DA9211_PH_SH_EN_A_MASK                 0x08
+#define DA9211_PH_SH_EN_B_SHIFT                        4
+#define DA9211_PH_SH_EN_B_MASK                 0x10
+
+/* DA9211_REG_VBUCKA_MAX (addr=0xD5) */
+#define DA9211_VBUCKA_BASE_SHIFT               0
+#define DA9211_VBUCKA_BASE_MASK                        0x7F
+
+/* DA9211_REG_VBUCKB_MAX (addr=0xD6) */
+#define DA9211_VBUCKB_BASE_SHIFT               0
+#define DA9211_VBUCKB_BASE_MASK                        0x7F
+
+/* DA9211_REG_VBUCKA/B_A/B (addr=0xD7/0xD8/0xD9/0xDA) */
+#define DA9211_VBUCK_SHIFT                     0
+#define DA9211_VBUCK_MASK                      0x7F
+#define DA9211_VBUCK_BIAS                      0
+#define DA9211_BUCK_SL                         0x80
+
+/* DA9211_REG_INTERFACE (addr=0x105) */
+#define DA9211_IF_BASE_ADDR_SHIFT              4
+#define DA9211_IF_BASE_ADDR_MASK               0xF0
+
+/* DA9211_REG_CONFIG_E (addr=0x147) */
+#define DA9211_SLAVE_SEL                       0x40
+
+#endif /* __DA9211_REGISTERS_H__ */
index 2e022aa..021d64d 100644 (file)
@@ -845,7 +845,6 @@ static struct lp872x_platform_data
        struct device_node *np = dev->of_node;
        struct lp872x_platform_data *pdata;
        struct of_regulator_match *match;
-       struct regulator_init_data *d;
        int num_matches;
        int count;
        int i;
@@ -892,14 +891,6 @@ static struct lp872x_platform_data
                pdata->regulator_data[i].id =
                                (enum lp872x_regulator_id)match[i].driver_data;
                pdata->regulator_data[i].init_data = match[i].init_data;
-
-               /* Operation mode configuration for buck/buck1/buck2 */
-               if (strncmp(match[i].name, "buck", 4))
-                       continue;
-
-               d = pdata->regulator_data[i].init_data;
-               d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE;
-               d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
        }
 out:
        return pdata;
index 785a25e..4a415d4 100644 (file)
@@ -339,22 +339,18 @@ static int lp8755_regulator_init(struct lp8755_chip *pchip)
                rconfig.init_data = pdata->buck_data[buck_num];
                rconfig.of_node = pchip->dev->of_node;
                pchip->rdev[buck_num] =
-                   regulator_register(&lp8755_regulators[buck_num], &rconfig);
+                   devm_regulator_register(pchip->dev,
+                                   &lp8755_regulators[buck_num], &rconfig);
                if (IS_ERR(pchip->rdev[buck_num])) {
                        ret = PTR_ERR(pchip->rdev[buck_num]);
                        pchip->rdev[buck_num] = NULL;
                        dev_err(pchip->dev, "regulator init failed: buck %d\n",
                                buck_num);
-                       goto err_buck;
+                       return ret;
                }
        }
 
        return 0;
-
-err_buck:
-       for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
-               regulator_unregister(pchip->rdev[icnt]);
-       return ret;
 }
 
 static irqreturn_t lp8755_irq_handler(int irq, void *data)
@@ -490,23 +486,19 @@ static int lp8755_probe(struct i2c_client *client,
        ret = lp8755_regulator_init(pchip);
        if (ret < 0) {
                dev_err(&client->dev, "fail to initialize regulators\n");
-               goto err_regulator;
+               goto err;
        }
 
        pchip->irq = client->irq;
        ret = lp8755_int_config(pchip);
        if (ret < 0) {
                dev_err(&client->dev, "fail to irq config\n");
-               goto err_irq;
+               goto err;
        }
 
        return ret;
 
-err_irq:
-       for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++)
-               regulator_unregister(pchip->rdev[icnt]);
-
-err_regulator:
+err:
        /* output disable */
        for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
                lp8755_write(pchip, icnt, 0x00);
@@ -519,9 +511,6 @@ static int lp8755_remove(struct i2c_client *client)
        int icnt;
        struct lp8755_chip *pchip = i2c_get_clientdata(client);
 
-       for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++)
-               regulator_unregister(pchip->rdev[icnt]);
-
        for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++)
                lp8755_write(pchip, icnt, 0x00);
 
index c810518..c756955 100644 (file)
@@ -377,7 +377,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg)
        return false;
 }
 
-struct reg_default ltc3589_reg_defaults[] = {
+static struct reg_default ltc3589_reg_defaults[] = {
        { LTC3589_SCR1,   0x00 },
        { LTC3589_OVEN,   0x00 },
        { LTC3589_SCR2,   0x00 },
index 653a58b..c67ff05 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/mfd/max77693.h>
 #include <linux/mfd/max77693-private.h>
 #include <linux/regulator/of_regulator.h>
+#include <linux/regmap.h>
 
 #define CHGIN_ILIM_STEP_20mA                   20000
 
@@ -39,9 +40,9 @@
 static int max77693_chg_is_enabled(struct regulator_dev *rdev)
 {
        int ret;
-       u8 val;
+       unsigned int val;
 
-       ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val);
+       ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
        if (ret)
                return ret;
 
@@ -57,12 +58,11 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
 {
        unsigned int chg_min_uA = rdev->constraints->min_uA;
        unsigned int chg_max_uA = rdev->constraints->max_uA;
-       u8 reg, sel;
+       unsigned int reg, sel;
        unsigned int val;
        int ret;
 
-       ret = max77693_read_reg(rdev->regmap,
-                               MAX77693_CHG_REG_CHG_CNFG_09, &reg);
+       ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, &reg);
        if (ret < 0)
                return ret;
 
@@ -96,7 +96,7 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
        /* the first four codes for charger current are all 60mA */
        sel += 3;
 
-       return max77693_write_reg(rdev->regmap,
+       return regmap_write(rdev->regmap,
                                MAX77693_CHG_REG_CHG_CNFG_09, sel);
 }
 /* end of CHARGER regulator ops */
index c2792f0..f7f9efc 100644 (file)
@@ -229,7 +229,6 @@ static int max8952_pmic_probe(struct i2c_client *client,
                config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
 
        rdev = devm_regulator_register(&client->dev, &regulator, &config);
-
        if (IS_ERR(rdev)) {
                ret = PTR_ERR(rdev);
                dev_err(&client->dev, "regulator init failed (%d)\n", ret);
@@ -241,21 +240,19 @@ static int max8952_pmic_probe(struct i2c_client *client,
 
        if (gpio_is_valid(pdata->gpio_vid0) &&
                        gpio_is_valid(pdata->gpio_vid1)) {
-               if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
-                       gpio_direction_output(pdata->gpio_vid0,
-                                       (pdata->default_mode) & 0x1);
-               else
+               unsigned long gpio_flags;
+
+               gpio_flags = max8952->vid0 ?
+                            GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+               if (devm_gpio_request_one(&client->dev, pdata->gpio_vid0,
+                                         gpio_flags, "MAX8952 VID0"))
                        err = 1;
 
-               if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
-                       gpio_direction_output(pdata->gpio_vid1,
-                               (pdata->default_mode >> 1) & 0x1);
-               else {
-                       if (!err)
-                               gpio_free(pdata->gpio_vid0);
+               gpio_flags = max8952->vid1 ?
+                            GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+               if (devm_gpio_request_one(&client->dev, pdata->gpio_vid1,
+                                         gpio_flags, "MAX8952 VID1"))
                        err = 2;
-               }
-
        } else
                err = 3;
 
@@ -314,16 +311,6 @@ static int max8952_pmic_probe(struct i2c_client *client,
        return 0;
 }
 
-static int max8952_pmic_remove(struct i2c_client *client)
-{
-       struct max8952_data *max8952 = i2c_get_clientdata(client);
-       struct max8952_platform_data *pdata = max8952->pdata;
-
-       gpio_free(pdata->gpio_vid0);
-       gpio_free(pdata->gpio_vid1);
-       return 0;
-}
-
 static const struct i2c_device_id max8952_ids[] = {
        { "max8952", 0 },
        { },
@@ -332,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, max8952_ids);
 
 static struct i2c_driver max8952_pmic_driver = {
        .probe          = max8952_pmic_probe,
-       .remove         = max8952_pmic_remove,
        .driver         = {
                .name   = "max8952",
                .of_match_table = of_match_ptr(max8952_dt_match),
index 05b9717..afba024 100644 (file)
@@ -33,17 +33,12 @@ static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
        int id = rdev_get_id(rdev);
-       int ret;
 
        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 
-       mc13xxx_lock(priv->mc13xxx);
-       ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
-                       mc13xxx_regulators[id].enable_bit,
-                       mc13xxx_regulators[id].enable_bit);
-       mc13xxx_unlock(priv->mc13xxx);
-
-       return ret;
+       return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
+                              mc13xxx_regulators[id].enable_bit,
+                              mc13xxx_regulators[id].enable_bit);
 }
 
 static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
@@ -51,16 +46,11 @@ static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
        int id = rdev_get_id(rdev);
-       int ret;
 
        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 
-       mc13xxx_lock(priv->mc13xxx);
-       ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
-                       mc13xxx_regulators[id].enable_bit, 0);
-       mc13xxx_unlock(priv->mc13xxx);
-
-       return ret;
+       return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
+                              mc13xxx_regulators[id].enable_bit, 0);
 }
 
 static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
@@ -70,10 +60,7 @@ static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
        int ret, id = rdev_get_id(rdev);
        unsigned int val;
 
-       mc13xxx_lock(priv->mc13xxx);
        ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
-       mc13xxx_unlock(priv->mc13xxx);
-
        if (ret)
                return ret;
 
@@ -86,15 +73,10 @@ static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev,
        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
        int id = rdev_get_id(rdev);
-       int ret;
 
-       mc13xxx_lock(priv->mc13xxx);
-       ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
-                       mc13xxx_regulators[id].vsel_mask,
-                       selector << mc13xxx_regulators[id].vsel_shift);
-       mc13xxx_unlock(priv->mc13xxx);
-
-       return ret;
+       return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
+                              mc13xxx_regulators[id].vsel_mask,
+                              selector << mc13xxx_regulators[id].vsel_shift);
 }
 
 static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
@@ -106,11 +88,8 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
 
        dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
 
-       mc13xxx_lock(priv->mc13xxx);
        ret = mc13xxx_reg_read(priv->mc13xxx,
                                mc13xxx_regulators[id].vsel_reg, &val);
-       mc13xxx_unlock(priv->mc13xxx);
-
        if (ret)
                return ret;
 
index 06c8903..2ab9bfd 100644 (file)
@@ -21,7 +21,6 @@ struct mc13xxx_regulator {
        int vsel_reg;
        int vsel_shift;
        int vsel_mask;
-       int hi_bit;
 };
 
 struct mc13xxx_regulator_priv {
index 93b4ad8..a7ce34d 100644 (file)
 #include <linux/of_platform.h>
 #include <linux/regulator/of_regulator.h>
 
-struct regs_info {
-       char    *name;
-       char    *sname;
-       u8      vsel_addr;
-       u8      ctrl_addr;
-       u8      tstep_addr;
-       int     sleep_id;
-};
-
 static const struct regulator_linear_range smps_low_ranges[] = {
        REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
        REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0),
@@ -50,7 +41,7 @@ static const struct regulator_linear_range smps_high_ranges[] = {
        REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0),
 };
 
-static const struct regs_info palmas_regs_info[] = {
+static struct palmas_regs_info palmas_generic_regs_info[] = {
        {
                .name           = "SMPS12",
                .sname          = "smps1-in",
@@ -236,6 +227,153 @@ static const struct regs_info palmas_regs_info[] = {
        },
 };
 
+static struct palmas_regs_info tps65917_regs_info[] = {
+       {
+               .name           = "SMPS1",
+               .sname          = "smps1-in",
+               .vsel_addr      = TPS65917_SMPS1_VOLTAGE,
+               .ctrl_addr      = TPS65917_SMPS1_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_SMPS1,
+       },
+       {
+               .name           = "SMPS2",
+               .sname          = "smps2-in",
+               .vsel_addr      = TPS65917_SMPS2_VOLTAGE,
+               .ctrl_addr      = TPS65917_SMPS2_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_SMPS2,
+       },
+       {
+               .name           = "SMPS3",
+               .sname          = "smps3-in",
+               .vsel_addr      = TPS65917_SMPS3_VOLTAGE,
+               .ctrl_addr      = TPS65917_SMPS3_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_SMPS3,
+       },
+       {
+               .name           = "SMPS4",
+               .sname          = "smps4-in",
+               .vsel_addr      = TPS65917_SMPS4_VOLTAGE,
+               .ctrl_addr      = TPS65917_SMPS4_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_SMPS4,
+       },
+       {
+               .name           = "SMPS5",
+               .sname          = "smps5-in",
+               .vsel_addr      = TPS65917_SMPS5_VOLTAGE,
+               .ctrl_addr      = TPS65917_SMPS5_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_SMPS5,
+       },
+       {
+               .name           = "LDO1",
+               .sname          = "ldo1-in",
+               .vsel_addr      = TPS65917_LDO1_VOLTAGE,
+               .ctrl_addr      = TPS65917_LDO1_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_LDO1,
+       },
+       {
+               .name           = "LDO2",
+               .sname          = "ldo2-in",
+               .vsel_addr      = TPS65917_LDO2_VOLTAGE,
+               .ctrl_addr      = TPS65917_LDO2_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_LDO2,
+       },
+       {
+               .name           = "LDO3",
+               .sname          = "ldo3-in",
+               .vsel_addr      = TPS65917_LDO3_VOLTAGE,
+               .ctrl_addr      = TPS65917_LDO3_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_LDO3,
+       },
+       {
+               .name           = "LDO4",
+               .sname          = "ldo4-in",
+               .vsel_addr      = TPS65917_LDO4_VOLTAGE,
+               .ctrl_addr      = TPS65917_LDO4_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_LDO4,
+       },
+       {
+               .name           = "LDO5",
+               .sname          = "ldo5-in",
+               .vsel_addr      = TPS65917_LDO5_VOLTAGE,
+               .ctrl_addr      = TPS65917_LDO5_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_LDO5,
+       },
+       {
+               .name           = "REGEN1",
+               .ctrl_addr      = TPS65917_REGEN1_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_REGEN1,
+       },
+       {
+               .name           = "REGEN2",
+               .ctrl_addr      = TPS65917_REGEN2_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_REGEN2,
+       },
+       {
+               .name           = "REGEN3",
+               .ctrl_addr      = TPS65917_REGEN3_CTRL,
+               .sleep_id       = TPS65917_EXTERNAL_REQSTR_ID_REGEN3,
+       },
+};
+
+#define EXTERNAL_REQUESTOR(_id, _offset, _pos)         \
+       [PALMAS_EXTERNAL_REQSTR_ID_##_id] = {           \
+               .id = PALMAS_EXTERNAL_REQSTR_ID_##_id,  \
+               .reg_offset = _offset,                  \
+               .bit_pos = _pos,                        \
+       }
+
+static struct palmas_sleep_requestor_info palma_sleep_req_info[] = {
+       EXTERNAL_REQUESTOR(REGEN1, 0, 0),
+       EXTERNAL_REQUESTOR(REGEN2, 0, 1),
+       EXTERNAL_REQUESTOR(SYSEN1, 0, 2),
+       EXTERNAL_REQUESTOR(SYSEN2, 0, 3),
+       EXTERNAL_REQUESTOR(CLK32KG, 0, 4),
+       EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5),
+       EXTERNAL_REQUESTOR(REGEN3, 0, 6),
+       EXTERNAL_REQUESTOR(SMPS12, 1, 0),
+       EXTERNAL_REQUESTOR(SMPS3, 1, 1),
+       EXTERNAL_REQUESTOR(SMPS45, 1, 2),
+       EXTERNAL_REQUESTOR(SMPS6, 1, 3),
+       EXTERNAL_REQUESTOR(SMPS7, 1, 4),
+       EXTERNAL_REQUESTOR(SMPS8, 1, 5),
+       EXTERNAL_REQUESTOR(SMPS9, 1, 6),
+       EXTERNAL_REQUESTOR(SMPS10, 1, 7),
+       EXTERNAL_REQUESTOR(LDO1, 2, 0),
+       EXTERNAL_REQUESTOR(LDO2, 2, 1),
+       EXTERNAL_REQUESTOR(LDO3, 2, 2),
+       EXTERNAL_REQUESTOR(LDO4, 2, 3),
+       EXTERNAL_REQUESTOR(LDO5, 2, 4),
+       EXTERNAL_REQUESTOR(LDO6, 2, 5),
+       EXTERNAL_REQUESTOR(LDO7, 2, 6),
+       EXTERNAL_REQUESTOR(LDO8, 2, 7),
+       EXTERNAL_REQUESTOR(LDO9, 3, 0),
+       EXTERNAL_REQUESTOR(LDOLN, 3, 1),
+       EXTERNAL_REQUESTOR(LDOUSB, 3, 2),
+};
+
+#define EXTERNAL_REQUESTOR_TPS65917(_id, _offset, _pos)                \
+       [TPS65917_EXTERNAL_REQSTR_ID_##_id] = {         \
+               .id = TPS65917_EXTERNAL_REQSTR_ID_##_id,        \
+               .reg_offset = _offset,                  \
+               .bit_pos = _pos,                        \
+       }
+
+static struct palmas_sleep_requestor_info tps65917_sleep_req_info[] = {
+       EXTERNAL_REQUESTOR_TPS65917(REGEN1, 0, 0),
+       EXTERNAL_REQUESTOR_TPS65917(REGEN2, 0, 1),
+       EXTERNAL_REQUESTOR_TPS65917(REGEN3, 0, 6),
+       EXTERNAL_REQUESTOR_TPS65917(SMPS1, 1, 0),
+       EXTERNAL_REQUESTOR_TPS65917(SMPS2, 1, 1),
+       EXTERNAL_REQUESTOR_TPS65917(SMPS3, 1, 2),
+       EXTERNAL_REQUESTOR_TPS65917(SMPS4, 1, 3),
+       EXTERNAL_REQUESTOR_TPS65917(SMPS5, 1, 4),
+       EXTERNAL_REQUESTOR_TPS65917(LDO1, 2, 0),
+       EXTERNAL_REQUESTOR_TPS65917(LDO2, 2, 1),
+       EXTERNAL_REQUESTOR_TPS65917(LDO3, 2, 2),
+       EXTERNAL_REQUESTOR_TPS65917(LDO4, 2, 3),
+       EXTERNAL_REQUESTOR_TPS65917(LDO5, 2, 4),
+};
+
 static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500};
 
 #define SMPS_CTRL_MODE_OFF             0x00
@@ -296,12 +434,15 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg,
 
 static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
 {
-       struct palmas_pmic *pmic = rdev_get_drvdata(dev);
        int id = rdev_get_id(dev);
+       struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+       struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
        unsigned int reg;
        bool rail_enable = true;
 
-       palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
+       palmas_smps_read(pmic->palmas, rinfo->ctrl_addr, &reg);
+
        reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
 
        if (reg == SMPS_CTRL_MODE_OFF)
@@ -323,8 +464,7 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
 
        pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
        if (rail_enable)
-               palmas_smps_write(pmic->palmas,
-                       palmas_regs_info[id].ctrl_addr, reg);
+               palmas_smps_write(pmic->palmas, rinfo->ctrl_addr, reg);
 
        /* Switch the enable value to ensure this is used for enable */
        pmic->desc[id].enable_val = pmic->current_reg_mode[id];
@@ -355,10 +495,11 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
 static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev,
                 int ramp_delay)
 {
-       struct palmas_pmic *pmic = rdev_get_drvdata(rdev);
        int id = rdev_get_id(rdev);
+       struct palmas_pmic *pmic = rdev_get_drvdata(rdev);
+       struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
        unsigned int reg = 0;
-       unsigned int addr = palmas_regs_info[id].tstep_addr;
        int ret;
 
        /* SMPS3 and SMPS7 do not have tstep_addr setting */
@@ -377,7 +518,7 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev,
        else
                reg = 1;
 
-       ret = palmas_smps_write(pmic->palmas, addr, reg);
+       ret = palmas_smps_write(pmic->palmas, rinfo->tstep_addr, reg);
        if (ret < 0) {
                dev_err(pmic->palmas->dev, "TSTEP write failed: %d\n", ret);
                return ret;
@@ -424,13 +565,37 @@ static struct regulator_ops palmas_ops_smps10 = {
        .get_bypass             = regulator_get_bypass_regmap,
 };
 
+static struct regulator_ops tps65917_ops_smps = {
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .set_mode               = palmas_set_mode_smps,
+       .get_mode               = palmas_get_mode_smps,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops tps65917_ops_ext_control_smps = {
+       .set_mode               = palmas_set_mode_smps,
+       .get_mode               = palmas_get_mode_smps,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+};
+
 static int palmas_is_enabled_ldo(struct regulator_dev *dev)
 {
-       struct palmas_pmic *pmic = rdev_get_drvdata(dev);
        int id = rdev_get_id(dev);
+       struct palmas_pmic *pmic = rdev_get_drvdata(dev);
+       struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
        unsigned int reg;
 
-       palmas_ldo_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
+       palmas_ldo_read(pmic->palmas, rinfo->ctrl_addr, &reg);
 
        reg &= PALMAS_LDO1_CTRL_STATUS;
 
@@ -463,14 +628,26 @@ static struct regulator_ops palmas_ops_extreg = {
 static struct regulator_ops palmas_ops_ext_control_extreg = {
 };
 
+static struct regulator_ops tps65917_ops_ldo = {
+       .is_enabled             = palmas_is_enabled_ldo,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .list_voltage           = regulator_list_voltage_linear,
+       .map_voltage            = regulator_map_voltage_linear,
+       .set_voltage_time_sel   = regulator_set_voltage_time_sel,
+};
+
 static int palmas_regulator_config_external(struct palmas *palmas, int id,
                struct palmas_reg_init *reg_init)
 {
-       int sleep_id = palmas_regs_info[id].sleep_id;
+       struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
        int ret;
 
-       ret = palmas_ext_control_req_config(palmas, sleep_id,
-                                       reg_init->roof_floor, true);
+       ret = palmas_ext_control_req_config(palmas, rinfo->sleep_id,
+                                           reg_init->roof_floor, true);
        if (ret < 0)
                dev_err(palmas->dev,
                        "Ext control config for regulator %d failed %d\n",
@@ -488,10 +665,10 @@ static int palmas_smps_init(struct palmas *palmas, int id,
                struct palmas_reg_init *reg_init)
 {
        unsigned int reg;
-       unsigned int addr;
        int ret;
-
-       addr = palmas_regs_info[id].ctrl_addr;
+       struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
+       unsigned int addr = rinfo->ctrl_addr;
 
        ret = palmas_smps_read(palmas, addr, &reg);
        if (ret)
@@ -526,12 +703,11 @@ static int palmas_smps_init(struct palmas *palmas, int id,
        if (ret)
                return ret;
 
-       if (palmas_regs_info[id].vsel_addr && reg_init->vsel) {
-               addr = palmas_regs_info[id].vsel_addr;
+       if (rinfo->vsel_addr && reg_init->vsel) {
 
                reg = reg_init->vsel;
 
-               ret = palmas_smps_write(palmas, addr, reg);
+               ret = palmas_smps_write(palmas, rinfo->vsel_addr, reg);
                if (ret)
                        return ret;
        }
@@ -539,7 +715,6 @@ static int palmas_smps_init(struct palmas *palmas, int id,
        if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) &&
                        (id != PALMAS_REG_SMPS10_OUT2)) {
                /* Enable externally controlled regulator */
-               addr = palmas_regs_info[id].ctrl_addr;
                ret = palmas_smps_read(palmas, addr, &reg);
                if (ret < 0)
                        return ret;
@@ -561,8 +736,10 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
        unsigned int reg;
        unsigned int addr;
        int ret;
+       struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
 
-       addr = palmas_regs_info[id].ctrl_addr;
+       addr = rinfo->ctrl_addr;
 
        ret = palmas_ldo_read(palmas, addr, &reg);
        if (ret)
@@ -584,7 +761,6 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
 
        if (reg_init->roof_floor) {
                /* Enable externally controlled regulator */
-               addr = palmas_regs_info[id].ctrl_addr;
                ret = palmas_update_bits(palmas, PALMAS_LDO_BASE,
                                addr, PALMAS_LDO1_CTRL_MODE_ACTIVE,
                                PALMAS_LDO1_CTRL_MODE_ACTIVE);
@@ -605,8 +781,10 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
        unsigned int addr;
        int ret;
        unsigned int val = 0;
+       struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id];
 
-       addr = palmas_regs_info[id].ctrl_addr;
+       addr = rinfo->ctrl_addr;
 
        if (reg_init->mode_sleep)
                val = PALMAS_REGEN1_CTRL_MODE_SLEEP;
@@ -621,7 +799,6 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
 
        if (reg_init->roof_floor) {
                /* Enable externally controlled regulator */
-               addr = palmas_regs_info[id].ctrl_addr;
                ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
                                addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE,
                                PALMAS_REGEN1_CTRL_MODE_ACTIVE);
@@ -641,8 +818,11 @@ static void palmas_enable_ldo8_track(struct palmas *palmas)
        unsigned int reg;
        unsigned int addr;
        int ret;
+       struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata;
+       struct palmas_regs_info *rinfo;
 
-       addr = palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr;
+       rinfo = &ddata->palmas_regs_info[PALMAS_REG_LDO8];
+       addr = rinfo->ctrl_addr;
 
        ret = palmas_ldo_read(palmas, addr, &reg);
        if (ret) {
@@ -661,7 +841,7 @@ static void palmas_enable_ldo8_track(struct palmas *palmas)
         * output is defined by the LDO8_VOLTAGE.VSEL register divided by two,
         * and can be set from 0.45 to 1.65 V.
         */
-       addr = palmas_regs_info[PALMAS_REG_LDO8].vsel_addr;
+       addr = rinfo->vsel_addr;
        ret = palmas_ldo_read(palmas, addr, &reg);
        if (ret) {
                dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n");
@@ -676,169 +856,230 @@ static void palmas_enable_ldo8_track(struct palmas *palmas)
        return;
 }
 
-static struct of_regulator_match palmas_matches[] = {
-       { .name = "smps12", },
-       { .name = "smps123", },
-       { .name = "smps3", },
-       { .name = "smps45", },
-       { .name = "smps457", },
-       { .name = "smps6", },
-       { .name = "smps7", },
-       { .name = "smps8", },
-       { .name = "smps9", },
-       { .name = "smps10_out2", },
-       { .name = "smps10_out1", },
-       { .name = "ldo1", },
-       { .name = "ldo2", },
-       { .name = "ldo3", },
-       { .name = "ldo4", },
-       { .name = "ldo5", },
-       { .name = "ldo6", },
-       { .name = "ldo7", },
-       { .name = "ldo8", },
-       { .name = "ldo9", },
-       { .name = "ldoln", },
-       { .name = "ldousb", },
-       { .name = "regen1", },
-       { .name = "regen2", },
-       { .name = "regen3", },
-       { .name = "sysen1", },
-       { .name = "sysen2", },
-};
-
-static void palmas_dt_to_pdata(struct device *dev,
-               struct device_node *node,
-               struct palmas_pmic_platform_data *pdata)
+static int palmas_ldo_registration(struct palmas_pmic *pmic,
+                                  struct palmas_pmic_driver_data *ddata,
+                                  struct palmas_pmic_platform_data *pdata,
+                                  const char *pdev_name,
+                                  struct regulator_config config)
 {
-       struct device_node *regulators;
-       u32 prop;
-       int idx, ret;
+       int id, ret;
+       struct regulator_dev *rdev;
+       struct palmas_reg_init *reg_init;
+       struct palmas_regs_info *rinfo;
+       struct regulator_desc *desc;
 
-       node = of_node_get(node);
-       regulators = of_get_child_by_name(node, "regulators");
-       if (!regulators) {
-               dev_info(dev, "regulator node not found\n");
-               return;
-       }
+       for (id = ddata->ldo_begin; id < ddata->max_reg; id++) {
+               if (pdata && pdata->reg_init[id])
+                       reg_init = pdata->reg_init[id];
+               else
+                       reg_init = NULL;
 
-       ret = of_regulator_match(dev, regulators, palmas_matches,
-                       PALMAS_NUM_REGS);
-       of_node_put(regulators);
-       if (ret < 0) {
-               dev_err(dev, "Error parsing regulator init data: %d\n", ret);
-               return;
-       }
+               rinfo = &ddata->palmas_regs_info[id];
+               /* Miss out regulators which are not available due
+                * to alternate functions.
+                */
 
-       for (idx = 0; idx < PALMAS_NUM_REGS; idx++) {
-               if (!palmas_matches[idx].init_data ||
-                               !palmas_matches[idx].of_node)
-                       continue;
+               /* Register the regulators */
+               desc = &pmic->desc[id];
+               desc->name = rinfo->name;
+               desc->id = id;
+               desc->type = REGULATOR_VOLTAGE;
+               desc->owner = THIS_MODULE;
 
-               pdata->reg_data[idx] = palmas_matches[idx].init_data;
+               if (id < PALMAS_REG_REGEN1) {
+                       desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES;
+                       if (reg_init && reg_init->roof_floor)
+                               desc->ops = &palmas_ops_ext_control_ldo;
+                       else
+                               desc->ops = &palmas_ops_ldo;
+                       desc->min_uV = 900000;
+                       desc->uV_step = 50000;
+                       desc->linear_min_sel = 1;
+                       desc->enable_time = 500;
+                       desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+                                                           rinfo->vsel_addr);
+                       desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
+                       desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+                                                             rinfo->ctrl_addr);
+                       desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
 
-               pdata->reg_init[idx] = devm_kzalloc(dev,
-                               sizeof(struct palmas_reg_init), GFP_KERNEL);
+                       /* Check if LDO8 is in tracking mode or not */
+                       if (pdata && (id == PALMAS_REG_LDO8) &&
+                           pdata->enable_ldo8_tracking) {
+                               palmas_enable_ldo8_track(pmic->palmas);
+                               desc->min_uV = 450000;
+                               desc->uV_step = 25000;
+                       }
 
-               pdata->reg_init[idx]->warm_reset =
-                       of_property_read_bool(palmas_matches[idx].of_node,
-                                            "ti,warm-reset");
+                       /* LOD6 in vibrator mode will have enable time 2000us */
+                       if (pdata && pdata->ldo6_vibrator &&
+                           (id == PALMAS_REG_LDO6))
+                               desc->enable_time = 2000;
+               } else {
+                       desc->n_voltages = 1;
+                       if (reg_init && reg_init->roof_floor)
+                               desc->ops = &palmas_ops_ext_control_extreg;
+                       else
+                               desc->ops = &palmas_ops_extreg;
+                       desc->enable_reg =
+                                       PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
+                                                          rinfo->ctrl_addr);
+                       desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+               }
 
-               ret = of_property_read_u32(palmas_matches[idx].of_node,
-                                             "ti,roof-floor", &prop);
-               /* EINVAL: Property not found */
-               if (ret != -EINVAL) {
-                       int econtrol;
+               if (pdata)
+                       config.init_data = pdata->reg_data[id];
+               else
+                       config.init_data = NULL;
 
-                       /* use default value, when no value is specified */
-                       econtrol = PALMAS_EXT_CONTROL_NSLEEP;
-                       if (!ret) {
-                               switch (prop) {
-                               case 1:
-                                       econtrol = PALMAS_EXT_CONTROL_ENABLE1;
-                                       break;
-                               case 2:
-                                       econtrol = PALMAS_EXT_CONTROL_ENABLE2;
-                                       break;
-                               case 3:
-                                       econtrol = PALMAS_EXT_CONTROL_NSLEEP;
-                                       break;
-                               default:
-                                       WARN_ON(1);
-                                       dev_warn(dev,
-                                       "%s: Invalid roof-floor option: %u\n",
-                                            palmas_matches[idx].name, prop);
-                                       break;
-                               }
-                       }
-                       pdata->reg_init[idx]->roof_floor = econtrol;
-               }
+               desc->supply_name = rinfo->sname;
+               config.of_node = ddata->palmas_matches[id].of_node;
 
-               ret = of_property_read_u32(palmas_matches[idx].of_node,
-                               "ti,mode-sleep", &prop);
-               if (!ret)
-                       pdata->reg_init[idx]->mode_sleep = prop;
+               rdev = devm_regulator_register(pmic->dev, desc, &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(pmic->dev,
+                               "failed to register %s regulator\n",
+                               pdev_name);
+                       return PTR_ERR(rdev);
+               }
 
-               ret = of_property_read_bool(palmas_matches[idx].of_node,
-                                           "ti,smps-range");
-               if (ret)
-                       pdata->reg_init[idx]->vsel =
-                               PALMAS_SMPS12_VOLTAGE_RANGE;
+               /* Save regulator for cleanup */
+               pmic->rdev[id] = rdev;
 
-               if (idx == PALMAS_REG_LDO8)
-                       pdata->enable_ldo8_tracking = of_property_read_bool(
-                                               palmas_matches[idx].of_node,
-                                               "ti,enable-ldo8-tracking");
+               /* Initialise sleep/init values from platform data */
+               if (pdata) {
+                       reg_init = pdata->reg_init[id];
+                       if (reg_init) {
+                               if (id <= ddata->ldo_end)
+                                       ret = palmas_ldo_init(pmic->palmas, id,
+                                                             reg_init);
+                               else
+                                       ret = palmas_extreg_init(pmic->palmas,
+                                                                id, reg_init);
+                               if (ret)
+                                       return ret;
+                       }
+               }
        }
 
-       pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
+       return 0;
 }
 
-
-static int palmas_regulators_probe(struct platform_device *pdev)
+static int tps65917_ldo_registration(struct palmas_pmic *pmic,
+                                    struct palmas_pmic_driver_data *ddata,
+                                    struct palmas_pmic_platform_data *pdata,
+                                    const char *pdev_name,
+                                    struct regulator_config config)
 {
-       struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
-       struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev);
-       struct device_node *node = pdev->dev.of_node;
+       int id, ret;
        struct regulator_dev *rdev;
-       struct regulator_config config = { };
-       struct palmas_pmic *pmic;
        struct palmas_reg_init *reg_init;
-       int id = 0, ret;
-       unsigned int addr, reg;
+       struct palmas_regs_info *rinfo;
+       struct regulator_desc *desc;
 
-       if (node && !pdata) {
-               pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       for (id = ddata->ldo_begin; id < ddata->max_reg; id++) {
+               if (pdata && pdata->reg_init[id])
+                       reg_init = pdata->reg_init[id];
+               else
+                       reg_init = NULL;
 
-               if (!pdata)
-                       return -ENOMEM;
+               /* Miss out regulators which are not available due
+                * to alternate functions.
+                */
+               rinfo = &ddata->palmas_regs_info[id];
 
-               palmas_dt_to_pdata(&pdev->dev, node, pdata);
-       }
+               /* Register the regulators */
+               desc = &pmic->desc[id];
+               desc->name = rinfo->name;
+               desc->id = id;
+               desc->type = REGULATOR_VOLTAGE;
+               desc->owner = THIS_MODULE;
+
+               if (id < TPS65917_REG_REGEN1) {
+                       desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES;
+                       if (reg_init && reg_init->roof_floor)
+                               desc->ops = &palmas_ops_ext_control_ldo;
+                       else
+                               desc->ops = &tps65917_ops_ldo;
+                       desc->min_uV = 900000;
+                       desc->uV_step = 50000;
+                       desc->linear_min_sel = 1;
+                       desc->enable_time = 500;
+                       desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+                                                           rinfo->vsel_addr);
+                       desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
+                       desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+                                                             rinfo->ctrl_addr);
+                       desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
+                       /*
+                        * To be confirmed. Discussion on going with PMIC Team.
+                        * It is of the order of ~60mV/uS.
+                        */
+                       desc->ramp_delay = 2500;
+               } else {
+                       desc->n_voltages = 1;
+                       if (reg_init && reg_init->roof_floor)
+                               desc->ops = &palmas_ops_ext_control_extreg;
+                       else
+                               desc->ops = &palmas_ops_extreg;
+                       desc->enable_reg =
+                                       PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
+                                                          rinfo->ctrl_addr);
+                       desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+               }
 
-       pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
-       if (!pmic)
-               return -ENOMEM;
+               if (pdata)
+                       config.init_data = pdata->reg_data[id];
+               else
+                       config.init_data = NULL;
 
-       pmic->dev = &pdev->dev;
-       pmic->palmas = palmas;
-       palmas->pmic = pmic;
-       platform_set_drvdata(pdev, pmic);
+               desc->supply_name = rinfo->sname;
+               config.of_node = ddata->palmas_matches[id].of_node;
 
-       ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
-       if (ret)
-               return ret;
+               rdev = devm_regulator_register(pmic->dev, desc, &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(pmic->dev,
+                               "failed to register %s regulator\n",
+                               pdev_name);
+                       return PTR_ERR(rdev);
+               }
 
-       if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
-               pmic->smps123 = 1;
+               /* Save regulator for cleanup */
+               pmic->rdev[id] = rdev;
 
-       if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN)
-               pmic->smps457 = 1;
+               /* Initialise sleep/init values from platform data */
+               if (pdata) {
+                       reg_init = pdata->reg_init[id];
+                       if (reg_init) {
+                               if (id < TPS65917_REG_REGEN1)
+                                       ret = palmas_ldo_init(pmic->palmas,
+                                                             id, reg_init);
+                               else
+                                       ret = palmas_extreg_init(pmic->palmas,
+                                                                id, reg_init);
+                               if (ret)
+                                       return ret;
+                       }
+               }
+       }
 
-       config.regmap = palmas->regmap[REGULATOR_SLAVE];
-       config.dev = &pdev->dev;
-       config.driver_data = pmic;
+       return 0;
+}
 
-       for (id = 0; id < PALMAS_REG_LDO1; id++) {
+static int palmas_smps_registration(struct palmas_pmic *pmic,
+                                   struct palmas_pmic_driver_data *ddata,
+                                   struct palmas_pmic_platform_data *pdata,
+                                   const char *pdev_name,
+                                   struct regulator_config config)
+{
+       int id, ret;
+       unsigned int addr, reg;
+       struct regulator_dev *rdev;
+       struct palmas_reg_init *reg_init;
+       struct palmas_regs_info *rinfo;
+       struct regulator_desc *desc;
+
+       for (id = ddata->smps_start; id <= ddata->smps_end; id++) {
                bool ramp_delay_support = false;
 
                /*
@@ -872,30 +1113,31 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                        break;
                case PALMAS_REG_SMPS10_OUT1:
                case PALMAS_REG_SMPS10_OUT2:
-                       if (!PALMAS_PMIC_HAS(palmas, SMPS10_BOOST))
+                       if (!PALMAS_PMIC_HAS(pmic->palmas, SMPS10_BOOST))
                                continue;
                }
+               rinfo = &ddata->palmas_regs_info[id];
+               desc = &pmic->desc[id];
 
                if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8))
                        ramp_delay_support = true;
 
                if (ramp_delay_support) {
-                       addr = palmas_regs_info[id].tstep_addr;
+                       addr = rinfo->tstep_addr;
                        ret = palmas_smps_read(pmic->palmas, addr, &reg);
                        if (ret < 0) {
-                               dev_err(&pdev->dev,
+                               dev_err(pmic->dev,
                                        "reading TSTEP reg failed: %d\n", ret);
                                return ret;
                        }
-                       pmic->desc[id].ramp_delay =
-                                       palmas_smps_ramp_delay[reg & 0x3];
-                       pmic->ramp_delay[id] = pmic->desc[id].ramp_delay;
+                       desc->ramp_delay = palmas_smps_ramp_delay[reg & 0x3];
+                       pmic->ramp_delay[id] = desc->ramp_delay;
                }
 
                /* Initialise sleep/init values from platform data */
                if (pdata && pdata->reg_init[id]) {
                        reg_init = pdata->reg_init[id];
-                       ret = palmas_smps_init(palmas, id, reg_init);
+                       ret = palmas_smps_init(pmic->palmas, id, reg_init);
                        if (ret)
                                return ret;
                } else {
@@ -903,31 +1145,28 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                }
 
                /* Register the regulators */
-               pmic->desc[id].name = palmas_regs_info[id].name;
-               pmic->desc[id].id = id;
+               desc->name = rinfo->name;
+               desc->id = id;
 
                switch (id) {
                case PALMAS_REG_SMPS10_OUT1:
                case PALMAS_REG_SMPS10_OUT2:
-                       pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
-                       pmic->desc[id].ops = &palmas_ops_smps10;
-                       pmic->desc[id].vsel_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                                       PALMAS_SMPS10_CTRL);
-                       pmic->desc[id].vsel_mask = SMPS10_VSEL;
-                       pmic->desc[id].enable_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                                       PALMAS_SMPS10_CTRL);
+                       desc->n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
+                       desc->ops = &palmas_ops_smps10;
+                       desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                           PALMAS_SMPS10_CTRL);
+                       desc->vsel_mask = SMPS10_VSEL;
+                       desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                           PALMAS_SMPS10_CTRL);
                        if (id == PALMAS_REG_SMPS10_OUT1)
-                               pmic->desc[id].enable_mask = SMPS10_SWITCH_EN;
+                               desc->enable_mask = SMPS10_SWITCH_EN;
                        else
-                               pmic->desc[id].enable_mask = SMPS10_BOOST_EN;
-                       pmic->desc[id].bypass_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                                       PALMAS_SMPS10_CTRL);
-                       pmic->desc[id].bypass_mask = SMPS10_BYPASS_EN;
-                       pmic->desc[id].min_uV = 3750000;
-                       pmic->desc[id].uV_step = 1250000;
+                               desc->enable_mask = SMPS10_BOOST_EN;
+                       desc->bypass_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                           PALMAS_SMPS10_CTRL);
+                       desc->bypass_mask = SMPS10_BYPASS_EN;
+                       desc->min_uV = 3750000;
+                       desc->uV_step = 1250000;
                        break;
                default:
                        /*
@@ -936,8 +1175,8 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                         * otherwise we error in probe with unsupportable
                         * ranges. Read the current smps mode for later use.
                         */
-                       addr = palmas_regs_info[id].vsel_addr;
-                       pmic->desc[id].n_linear_ranges = 3;
+                       addr = rinfo->vsel_addr;
+                       desc->n_linear_ranges = 3;
 
                        ret = palmas_smps_read(pmic->palmas, addr, &reg);
                        if (ret)
@@ -945,56 +1184,50 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                        if (reg & PALMAS_SMPS12_VOLTAGE_RANGE)
                                pmic->range[id] = 1;
                        if (pmic->range[id])
-                               pmic->desc[id].linear_ranges = smps_high_ranges;
+                               desc->linear_ranges = smps_high_ranges;
                        else
-                               pmic->desc[id].linear_ranges = smps_low_ranges;
+                               desc->linear_ranges = smps_low_ranges;
 
                        if (reg_init && reg_init->roof_floor)
-                               pmic->desc[id].ops =
-                                               &palmas_ops_ext_control_smps;
+                               desc->ops = &palmas_ops_ext_control_smps;
                        else
-                               pmic->desc[id].ops = &palmas_ops_smps;
-                       pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
-                       pmic->desc[id].vsel_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                               palmas_regs_info[id].vsel_addr);
-                       pmic->desc[id].vsel_mask =
-                                       PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
+                               desc->ops = &palmas_ops_smps;
+                       desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
+                       desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                           rinfo->vsel_addr);
+                       desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
 
                        /* Read the smps mode for later use. */
-                       addr = palmas_regs_info[id].ctrl_addr;
+                       addr = rinfo->ctrl_addr;
                        ret = palmas_smps_read(pmic->palmas, addr, &reg);
                        if (ret)
                                return ret;
                        pmic->current_reg_mode[id] = reg &
                                        PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
 
-                       pmic->desc[id].enable_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
-                                               palmas_regs_info[id].ctrl_addr);
-                       pmic->desc[id].enable_mask =
-                                       PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+                       desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                             rinfo->ctrl_addr);
+                       desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
                        /* set_mode overrides this value */
-                       pmic->desc[id].enable_val = SMPS_CTRL_MODE_ON;
+                       desc->enable_val = SMPS_CTRL_MODE_ON;
                }
 
-               pmic->desc[id].type = REGULATOR_VOLTAGE;
-               pmic->desc[id].owner = THIS_MODULE;
+               desc->type = REGULATOR_VOLTAGE;
+               desc->owner = THIS_MODULE;
 
                if (pdata)
                        config.init_data = pdata->reg_data[id];
                else
                        config.init_data = NULL;
 
-               pmic->desc[id].supply_name = palmas_regs_info[id].sname;
-               config.of_node = palmas_matches[id].of_node;
+               desc->supply_name = rinfo->sname;
+               config.of_node = ddata->palmas_matches[id].of_node;
 
-               rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id],
-                                              &config);
+               rdev = devm_regulator_register(pmic->dev, desc, &config);
                if (IS_ERR(rdev)) {
-                       dev_err(&pdev->dev,
+                       dev_err(pmic->dev,
                                "failed to register %s regulator\n",
-                               pdev->name);
+                               pdev_name);
                        return PTR_ERR(rdev);
                }
 
@@ -1002,123 +1235,378 @@ static int palmas_regulators_probe(struct platform_device *pdev)
                pmic->rdev[id] = rdev;
        }
 
-       /* Start this loop from the id left from previous loop */
-       for (; id < PALMAS_NUM_REGS; id++) {
-               if (pdata && pdata->reg_init[id])
+       return 0;
+}
+
+static int tps65917_smps_registration(struct palmas_pmic *pmic,
+                                     struct palmas_pmic_driver_data *ddata,
+                                     struct palmas_pmic_platform_data *pdata,
+                                     const char *pdev_name,
+                                     struct regulator_config config)
+{
+       int id, ret;
+       unsigned int addr, reg;
+       struct regulator_dev *rdev;
+       struct palmas_reg_init *reg_init;
+       struct palmas_regs_info *rinfo;
+       struct regulator_desc *desc;
+
+       for (id = ddata->smps_start; id <= ddata->smps_end; id++) {
+               /*
+                * Miss out regulators which are not available due
+                * to slaving configurations.
+                */
+               desc = &pmic->desc[id];
+               desc->n_linear_ranges = 3;
+               if ((id == TPS65917_REG_SMPS2) && pmic->smps12)
+                       continue;
+
+               /* Initialise sleep/init values from platform data */
+               if (pdata && pdata->reg_init[id]) {
                        reg_init = pdata->reg_init[id];
-               else
+                       ret = palmas_smps_init(pmic->palmas, id, reg_init);
+                       if (ret)
+                               return ret;
+               } else {
                        reg_init = NULL;
+               }
+               rinfo = &ddata->palmas_regs_info[id];
 
-               /* Miss out regulators which are not available due
-                * to alternate functions.
+               /* Register the regulators */
+               desc->name = rinfo->name;
+               desc->id = id;
+
+               /*
+                * Read and store the RANGE bit for later use
+                * This must be done before regulator is probed,
+                * otherwise we error in probe with unsupportable
+                * ranges. Read the current smps mode for later use.
                 */
+               addr = rinfo->vsel_addr;
 
-               /* Register the regulators */
-               pmic->desc[id].name = palmas_regs_info[id].name;
-               pmic->desc[id].id = id;
-               pmic->desc[id].type = REGULATOR_VOLTAGE;
-               pmic->desc[id].owner = THIS_MODULE;
+               ret = palmas_smps_read(pmic->palmas, addr, &reg);
+               if (ret)
+                       return ret;
+               if (reg & TPS65917_SMPS1_VOLTAGE_RANGE)
+                       pmic->range[id] = 1;
 
-               if (id < PALMAS_REG_REGEN1) {
-                       pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
-                       if (reg_init && reg_init->roof_floor)
-                               pmic->desc[id].ops =
-                                       &palmas_ops_ext_control_ldo;
-                       else
-                               pmic->desc[id].ops = &palmas_ops_ldo;
-                       pmic->desc[id].min_uV = 900000;
-                       pmic->desc[id].uV_step = 50000;
-                       pmic->desc[id].linear_min_sel = 1;
-                       pmic->desc[id].enable_time = 500;
-                       pmic->desc[id].vsel_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
-                                               palmas_regs_info[id].vsel_addr);
-                       pmic->desc[id].vsel_mask =
-                                       PALMAS_LDO1_VOLTAGE_VSEL_MASK;
-                       pmic->desc[id].enable_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
-                                               palmas_regs_info[id].ctrl_addr);
-                       pmic->desc[id].enable_mask =
-                                       PALMAS_LDO1_CTRL_MODE_ACTIVE;
+               if (pmic->range[id])
+                       desc->linear_ranges = smps_high_ranges;
+               else
+                       desc->linear_ranges = smps_low_ranges;
 
-                       /* Check if LDO8 is in tracking mode or not */
-                       if (pdata && (id == PALMAS_REG_LDO8) &&
-                                       pdata->enable_ldo8_tracking) {
-                               palmas_enable_ldo8_track(palmas);
-                               pmic->desc[id].min_uV = 450000;
-                               pmic->desc[id].uV_step = 25000;
-                       }
+               if (reg_init && reg_init->roof_floor)
+                       desc->ops = &tps65917_ops_ext_control_smps;
+               else
+                       desc->ops = &tps65917_ops_smps;
+               desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
+               desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                   rinfo->vsel_addr);
+               desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
+               desc->ramp_delay = 2500;
+
+               /* Read the smps mode for later use. */
+               addr = rinfo->ctrl_addr;
+               ret = palmas_smps_read(pmic->palmas, addr, &reg);
+               if (ret)
+                       return ret;
+               pmic->current_reg_mode[id] = reg &
+                               PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+               desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+                                                     rinfo->ctrl_addr);
+               desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+               /* set_mode overrides this value */
+               desc->enable_val = SMPS_CTRL_MODE_ON;
 
-                       /* LOD6 in vibrator mode will have enable time 2000us */
-                       if (pdata && pdata->ldo6_vibrator &&
-                               (id == PALMAS_REG_LDO6))
-                               pmic->desc[id].enable_time = 2000;
-               } else {
-                       pmic->desc[id].n_voltages = 1;
-                       if (reg_init && reg_init->roof_floor)
-                               pmic->desc[id].ops =
-                                       &palmas_ops_ext_control_extreg;
-                       else
-                               pmic->desc[id].ops = &palmas_ops_extreg;
-                       pmic->desc[id].enable_reg =
-                                       PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
-                                               palmas_regs_info[id].ctrl_addr);
-                       pmic->desc[id].enable_mask =
-                                       PALMAS_REGEN1_CTRL_MODE_ACTIVE;
-               }
+               desc->type = REGULATOR_VOLTAGE;
+               desc->owner = THIS_MODULE;
 
                if (pdata)
                        config.init_data = pdata->reg_data[id];
                else
                        config.init_data = NULL;
 
-               pmic->desc[id].supply_name = palmas_regs_info[id].sname;
-               config.of_node = palmas_matches[id].of_node;
+               desc->supply_name = rinfo->sname;
+               config.of_node = ddata->palmas_matches[id].of_node;
 
-               rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id],
-                                              &config);
+               rdev = devm_regulator_register(pmic->dev, desc, &config);
                if (IS_ERR(rdev)) {
-                       dev_err(&pdev->dev,
+                       dev_err(pmic->dev,
                                "failed to register %s regulator\n",
-                               pdev->name);
+                               pdev_name);
                        return PTR_ERR(rdev);
                }
 
                /* Save regulator for cleanup */
                pmic->rdev[id] = rdev;
+       }
 
-               /* Initialise sleep/init values from platform data */
-               if (pdata) {
-                       reg_init = pdata->reg_init[id];
-                       if (reg_init) {
-                               if (id < PALMAS_REG_REGEN1)
-                                       ret = palmas_ldo_init(palmas,
-                                                       id, reg_init);
-                               else
-                                       ret = palmas_extreg_init(palmas,
-                                                       id, reg_init);
-                               if (ret)
-                                       return ret;
+       return 0;
+}
+
+static struct of_regulator_match palmas_matches[] = {
+       { .name = "smps12", },
+       { .name = "smps123", },
+       { .name = "smps3", },
+       { .name = "smps45", },
+       { .name = "smps457", },
+       { .name = "smps6", },
+       { .name = "smps7", },
+       { .name = "smps8", },
+       { .name = "smps9", },
+       { .name = "smps10_out2", },
+       { .name = "smps10_out1", },
+       { .name = "ldo1", },
+       { .name = "ldo2", },
+       { .name = "ldo3", },
+       { .name = "ldo4", },
+       { .name = "ldo5", },
+       { .name = "ldo6", },
+       { .name = "ldo7", },
+       { .name = "ldo8", },
+       { .name = "ldo9", },
+       { .name = "ldoln", },
+       { .name = "ldousb", },
+       { .name = "regen1", },
+       { .name = "regen2", },
+       { .name = "regen3", },
+       { .name = "sysen1", },
+       { .name = "sysen2", },
+};
+
+static struct of_regulator_match tps65917_matches[] = {
+       { .name = "smps1", },
+       { .name = "smps2", },
+       { .name = "smps3", },
+       { .name = "smps4", },
+       { .name = "smps5", },
+       { .name = "ldo1", },
+       { .name = "ldo2", },
+       { .name = "ldo3", },
+       { .name = "ldo4", },
+       { .name = "ldo5", },
+       { .name = "regen1", },
+       { .name = "regen2", },
+       { .name = "regen3", },
+       { .name = "sysen1", },
+       { .name = "sysen2", },
+};
+
+static struct palmas_pmic_driver_data palmas_ddata = {
+       .smps_start = PALMAS_REG_SMPS12,
+       .smps_end = PALMAS_REG_SMPS10_OUT1,
+       .ldo_begin = PALMAS_REG_LDO1,
+       .ldo_end = PALMAS_REG_LDOUSB,
+       .max_reg = PALMAS_NUM_REGS,
+       .palmas_regs_info = palmas_generic_regs_info,
+       .palmas_matches = palmas_matches,
+       .sleep_req_info = palma_sleep_req_info,
+       .smps_register = palmas_smps_registration,
+       .ldo_register = palmas_ldo_registration,
+};
+
+static struct palmas_pmic_driver_data tps65917_ddata = {
+       .smps_start = TPS65917_REG_SMPS1,
+       .smps_end = TPS65917_REG_SMPS5,
+       .ldo_begin = TPS65917_REG_LDO1,
+       .ldo_end = TPS65917_REG_LDO5,
+       .max_reg = TPS65917_NUM_REGS,
+       .palmas_regs_info = tps65917_regs_info,
+       .palmas_matches = tps65917_matches,
+       .sleep_req_info = tps65917_sleep_req_info,
+       .smps_register = tps65917_smps_registration,
+       .ldo_register = tps65917_ldo_registration,
+};
+
+static void palmas_dt_to_pdata(struct device *dev,
+                              struct device_node *node,
+                              struct palmas_pmic_platform_data *pdata,
+                              struct palmas_pmic_driver_data *ddata)
+{
+       struct device_node *regulators;
+       u32 prop;
+       int idx, ret;
+
+       node = of_node_get(node);
+       regulators = of_get_child_by_name(node, "regulators");
+       if (!regulators) {
+               dev_info(dev, "regulator node not found\n");
+               return;
+       }
+
+       ret = of_regulator_match(dev, regulators, ddata->palmas_matches,
+                                ddata->max_reg);
+       of_node_put(regulators);
+       if (ret < 0) {
+               dev_err(dev, "Error parsing regulator init data: %d\n", ret);
+               return;
+       }
+
+       for (idx = 0; idx < ddata->max_reg; idx++) {
+               if (!ddata->palmas_matches[idx].init_data ||
+                   !ddata->palmas_matches[idx].of_node)
+                       continue;
+
+               pdata->reg_data[idx] = ddata->palmas_matches[idx].init_data;
+
+               pdata->reg_init[idx] = devm_kzalloc(dev,
+                               sizeof(struct palmas_reg_init), GFP_KERNEL);
+
+               pdata->reg_init[idx]->warm_reset =
+                       of_property_read_bool(ddata->palmas_matches[idx].of_node,
+                                             "ti,warm-reset");
+
+               ret = of_property_read_u32(ddata->palmas_matches[idx].of_node,
+                                          "ti,roof-floor", &prop);
+               /* EINVAL: Property not found */
+               if (ret != -EINVAL) {
+                       int econtrol;
+
+                       /* use default value, when no value is specified */
+                       econtrol = PALMAS_EXT_CONTROL_NSLEEP;
+                       if (!ret) {
+                               switch (prop) {
+                               case 1:
+                                       econtrol = PALMAS_EXT_CONTROL_ENABLE1;
+                                       break;
+                               case 2:
+                                       econtrol = PALMAS_EXT_CONTROL_ENABLE2;
+                                       break;
+                               case 3:
+                                       econtrol = PALMAS_EXT_CONTROL_NSLEEP;
+                                       break;
+                               default:
+                                       WARN_ON(1);
+                                       dev_warn(dev,
+                                                "%s: Invalid roof-floor option: %u\n",
+                                            palmas_matches[idx].name, prop);
+                                       break;
+                               }
                        }
+                       pdata->reg_init[idx]->roof_floor = econtrol;
                }
-       }
 
+               ret = of_property_read_u32(ddata->palmas_matches[idx].of_node,
+                                          "ti,mode-sleep", &prop);
+               if (!ret)
+                       pdata->reg_init[idx]->mode_sleep = prop;
 
-       return 0;
+               ret = of_property_read_bool(ddata->palmas_matches[idx].of_node,
+                                           "ti,smps-range");
+               if (ret)
+                       pdata->reg_init[idx]->vsel =
+                               PALMAS_SMPS12_VOLTAGE_RANGE;
+
+               if (idx == PALMAS_REG_LDO8)
+                       pdata->enable_ldo8_tracking = of_property_read_bool(
+                                               ddata->palmas_matches[idx].of_node,
+                                               "ti,enable-ldo8-tracking");
+       }
+
+       pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
 }
 
-static const struct of_device_id of_palmas_match_tbl[] = {
-       { .compatible = "ti,palmas-pmic", },
-       { .compatible = "ti,twl6035-pmic", },
-       { .compatible = "ti,twl6036-pmic", },
-       { .compatible = "ti,twl6037-pmic", },
-       { .compatible = "ti,tps65913-pmic", },
-       { .compatible = "ti,tps65914-pmic", },
-       { .compatible = "ti,tps80036-pmic", },
-       { .compatible = "ti,tps659038-pmic", },
+static struct of_device_id of_palmas_match_tbl[] = {
+       {
+               .compatible = "ti,palmas-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,twl6035-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,twl6036-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,twl6037-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,tps65913-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,tps65914-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,tps80036-pmic",
+               .data = &palmas_ddata,
+       },
+       {
+               .compatible = "ti,tps659038-pmic",
+               .data = &palmas_ddata,
+       },
+        {
+               .compatible = "ti,tps65917-pmic",
+               .data = &tps65917_ddata,
+       },
        { /* end */ }
 };
 
+static int palmas_regulators_probe(struct platform_device *pdev)
+{
+       struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
+       struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       struct device_node *node = pdev->dev.of_node;
+       struct palmas_pmic_driver_data *driver_data;
+       struct regulator_config config = { };
+       struct palmas_pmic *pmic;
+       const char *pdev_name;
+       const struct of_device_id *match;
+       int ret = 0;
+       unsigned int reg;
+
+       match = of_match_device(of_match_ptr(of_palmas_match_tbl), &pdev->dev);
+
+       if (!match)
+               return -ENODATA;
+
+       driver_data = (struct palmas_pmic_driver_data *)match->data;
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
+       if (!pmic)
+               return -ENOMEM;
+
+       pmic->dev = &pdev->dev;
+       pmic->palmas = palmas;
+       palmas->pmic = pmic;
+       platform_set_drvdata(pdev, pmic);
+       pmic->palmas->pmic_ddata = driver_data;
+
+       palmas_dt_to_pdata(&pdev->dev, node, pdata, driver_data);
+
+       ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
+       if (ret)
+               return ret;
+
+       if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
+               pmic->smps123 = 1;
+
+       if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN)
+               pmic->smps457 = 1;
+
+       config.regmap = palmas->regmap[REGULATOR_SLAVE];
+       config.dev = &pdev->dev;
+       config.driver_data = pmic;
+       pdev_name = pdev->name;
+
+       ret = driver_data->smps_register(pmic, driver_data, pdata, pdev_name,
+                                        config);
+       if (ret)
+               return ret;
+
+       ret = driver_data->ldo_register(pmic, driver_data, pdata, pdev_name,
+                                       config);
+
+       return ret;
+}
+
 static struct platform_driver palmas_driver = {
        .driver = {
                .name = "palmas-pmic",
index 02e2fb2..2b7e9e2 100644 (file)
@@ -766,5 +766,5 @@ module_exit(s2mps11_pmic_exit);
 
 /* Module information */
 MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
-MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14 Regulator Driver");
+MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPU02 Regulator Driver");
 MODULE_LICENSE("GPL");
index c79af94..0ab5cbe 100644 (file)
@@ -686,7 +686,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
        struct sec_platform_data *pdata = iodev->pdata;
        struct regulator_config config = { };
        struct s5m8767_info *s5m8767;
-       int i, ret, size, buck_init;
+       int i, ret, buck_init;
 
        if (!pdata) {
                dev_err(pdev->dev.parent, "Platform data not supplied\n");
@@ -725,8 +725,6 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
        if (!s5m8767)
                return -ENOMEM;
 
-       size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2);
-
        s5m8767->dev = &pdev->dev;
        s5m8767->iodev = iodev;
        s5m8767->num_regulators = pdata->num_regulators;
index 2064b3f..d5df1e9 100644 (file)
@@ -192,12 +192,14 @@ static struct regulator_ops tps65090_fet_control_ops = {
 static struct regulator_ops tps65090_ldo_ops = {
 };
 
-#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _ops)        \
+#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \
 {                                                      \
        .name = "TPS65090_RAILS"#_id,                   \
        .supply_name = _sname,                          \
        .id = TPS65090_REGULATOR_##_id,                 \
+       .n_voltages = _nvolt,                           \
        .ops = &_ops,                                   \
+       .fixed_uV = _volt,                              \
        .enable_reg = _en_reg,                          \
        .enable_val = _en_bits,                         \
        .enable_mask = _en_bits,                        \
@@ -205,40 +207,46 @@ static struct regulator_ops tps65090_ldo_ops = {
        .owner = THIS_MODULE,                           \
 }
 
+#define tps65090_REG_FIXEDV(_id, _sname, en_reg, _en_bits, _volt, _ops) \
+       tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 1, _volt, _ops)
+
+#define tps65090_REG_SWITCH(_id, _sname, en_reg, _en_bits, _ops) \
+       tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 0, 0, _ops)
+
 static struct regulator_desc tps65090_regulator_desc[] = {
-       tps65090_REG_DESC(DCDC1, "vsys1",   0x0C, BIT(CTRL_EN_BIT),
-                         tps65090_reg_control_ops),
-       tps65090_REG_DESC(DCDC2, "vsys2",   0x0D, BIT(CTRL_EN_BIT),
-                         tps65090_reg_control_ops),
-       tps65090_REG_DESC(DCDC3, "vsys3",   0x0E, BIT(CTRL_EN_BIT),
-                         tps65090_reg_control_ops),
-
-       tps65090_REG_DESC(FET1,  "infet1",  0x0F,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-       tps65090_REG_DESC(FET2,  "infet2",  0x10,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-       tps65090_REG_DESC(FET3,  "infet3",  0x11,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-       tps65090_REG_DESC(FET4,  "infet4",  0x12,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-       tps65090_REG_DESC(FET5,  "infet5",  0x13,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-       tps65090_REG_DESC(FET6,  "infet6",  0x14,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-       tps65090_REG_DESC(FET7,  "infet7",  0x15,
-                         BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
-                         tps65090_fet_control_ops),
-
-       tps65090_REG_DESC(LDO1,  "vsys-l1", 0, 0,
-                         tps65090_ldo_ops),
-       tps65090_REG_DESC(LDO2,  "vsys-l2", 0, 0,
-                         tps65090_ldo_ops),
+       tps65090_REG_FIXEDV(DCDC1, "vsys1",   0x0C, BIT(CTRL_EN_BIT), 5000000,
+                           tps65090_reg_control_ops),
+       tps65090_REG_FIXEDV(DCDC2, "vsys2",   0x0D, BIT(CTRL_EN_BIT), 3300000,
+                           tps65090_reg_control_ops),
+       tps65090_REG_SWITCH(DCDC3, "vsys3",   0x0E, BIT(CTRL_EN_BIT),
+                           tps65090_reg_control_ops),
+
+       tps65090_REG_SWITCH(FET1,  "infet1",  0x0F,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+       tps65090_REG_SWITCH(FET2,  "infet2",  0x10,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+       tps65090_REG_SWITCH(FET3,  "infet3",  0x11,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+       tps65090_REG_SWITCH(FET4,  "infet4",  0x12,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+       tps65090_REG_SWITCH(FET5,  "infet5",  0x13,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+       tps65090_REG_SWITCH(FET6,  "infet6",  0x14,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+       tps65090_REG_SWITCH(FET7,  "infet7",  0x15,
+                           BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT),
+                           tps65090_fet_control_ops),
+
+       tps65090_REG_FIXEDV(LDO1,  "vsys-l1", 0, 0, 5000000,
+                           tps65090_ldo_ops),
+       tps65090_REG_FIXEDV(LDO2,  "vsys-l2", 0, 0, 3300000,
+                           tps65090_ldo_ops),
 };
 
 static inline bool is_dcdc(int id)
index f7ed20a..d58db72 100644 (file)
@@ -68,7 +68,7 @@ static const struct regulator_linear_range tps65217_uv2_ranges[] = {
 static int tps65217_pmic_enable(struct regulator_dev *dev)
 {
        struct tps65217 *tps = rdev_get_drvdata(dev);
-       unsigned int rid = rdev_get_id(dev);
+       int rid = rdev_get_id(dev);
 
        if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
                return -EINVAL;
@@ -82,7 +82,7 @@ static int tps65217_pmic_enable(struct regulator_dev *dev)
 static int tps65217_pmic_disable(struct regulator_dev *dev)
 {
        struct tps65217 *tps = rdev_get_drvdata(dev);
-       unsigned int rid = rdev_get_id(dev);
+       int rid = rdev_get_id(dev);
 
        if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
                return -EINVAL;
index 9effe48..f0a4028 100644 (file)
@@ -29,8 +29,8 @@
 
 enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 };
 
-#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \
-                           _lr, _nlr, _delay)                  \
+#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, \
+                           _lr, _nlr, _delay, _fuv)            \
        {                                                       \
                .name                   = _name,                \
                .id                     = _id,                  \
@@ -42,14 +42,15 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 };
                .vsel_mask              = _vm,                  \
                .enable_reg             = _er,                  \
                .enable_mask            = _em,                  \
-               .volt_table             = _t,                   \
+               .volt_table             = NULL,                 \
                .linear_ranges          = _lr,                  \
                .n_linear_ranges        = _nlr,                 \
                .ramp_delay             = _delay,               \
+               .fixed_uV               = _fuv                  \
        }                                                       \
 
 #define TPS65218_INFO(_id, _nm, _min, _max)    \
-       {                                               \
+       [_id] = {                                       \
                .id             = _id,                  \
                .name           = _nm,                  \
                .min_uV         = _min,                 \
@@ -68,17 +69,17 @@ static const struct regulator_linear_range ldo1_dcdc3_ranges[] = {
 
 static const struct regulator_linear_range dcdc4_ranges[] = {
        REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000),
-       REGULATOR_LINEAR_RANGE(1550000, 0x10, 0x34, 50000),
+       REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000),
 };
 
 static struct tps_info tps65218_pmic_regs[] = {
-       TPS65218_INFO(0, "DCDC1", 850000, 167500),
-       TPS65218_INFO(1, "DCDC2", 850000, 1675000),
-       TPS65218_INFO(2, "DCDC3", 900000, 3400000),
-       TPS65218_INFO(3, "DCDC4", 1175000, 3400000),
-       TPS65218_INFO(4, "DCDC5", 1000000, 1000000),
-       TPS65218_INFO(5, "DCDC6", 1800000, 1800000),
-       TPS65218_INFO(6, "LDO1", 900000, 3400000),
+       TPS65218_INFO(DCDC1, "DCDC1", 850000, 167500),
+       TPS65218_INFO(DCDC2, "DCDC2", 850000, 1675000),
+       TPS65218_INFO(DCDC3, "DCDC3", 900000, 3400000),
+       TPS65218_INFO(DCDC4, "DCDC4", 1175000, 3400000),
+       TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000),
+       TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000),
+       TPS65218_INFO(LDO1, "LDO1", 900000, 3400000),
 };
 
 #define TPS65218_OF_MATCH(comp, label) \
@@ -127,7 +128,7 @@ static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev,
 static int tps65218_pmic_enable(struct regulator_dev *dev)
 {
        struct tps65218 *tps = rdev_get_drvdata(dev);
-       unsigned int rid = rdev_get_id(dev);
+       int rid = rdev_get_id(dev);
 
        if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
                return -EINVAL;
@@ -141,7 +142,7 @@ static int tps65218_pmic_enable(struct regulator_dev *dev)
 static int tps65218_pmic_disable(struct regulator_dev *dev)
 {
        struct tps65218 *tps = rdev_get_drvdata(dev);
-       unsigned int rid = rdev_get_id(dev);
+       int rid = rdev_get_id(dev);
 
        if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
                return -EINVAL;
@@ -185,34 +186,33 @@ static const struct regulator_desc regulators[] = {
        TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64,
                           TPS65218_REG_CONTROL_DCDC1,
                           TPS65218_CONTROL_DCDC1_MASK,
-                          TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL,
-                          dcdc1_dcdc2_ranges, 2, 4000),
+                          TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN,
+                          dcdc1_dcdc2_ranges, 2, 4000, 0),
        TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64,
                           TPS65218_REG_CONTROL_DCDC2,
                           TPS65218_CONTROL_DCDC2_MASK,
-                          TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL,
-                          dcdc1_dcdc2_ranges, 2, 4000),
+                          TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN,
+                          dcdc1_dcdc2_ranges, 2, 4000, 0),
        TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops,
                           64, TPS65218_REG_CONTROL_DCDC3,
                           TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1,
-                          TPS65218_ENABLE1_DC3_EN, NULL,
-                          ldo1_dcdc3_ranges, 2, 0),
+                          TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0, 0),
        TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops,
                           53, TPS65218_REG_CONTROL_DCDC4,
                           TPS65218_CONTROL_DCDC4_MASK,
-                          TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL,
-                          dcdc4_ranges, 2, 0),
+                          TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN,
+                          dcdc4_ranges, 2, 0, 0),
        TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops,
                           1, -1, -1, TPS65218_REG_ENABLE1,
-                          TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0, 0),
+                          TPS65218_ENABLE1_DC5_EN, NULL, 0, 0, 1000000),
        TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops,
                           1, -1, -1, TPS65218_REG_ENABLE1,
-                          TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0),
+                          TPS65218_ENABLE1_DC6_EN, NULL, 0, 0, 1800000),
        TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64,
                           TPS65218_REG_CONTROL_LDO1,
                           TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
-                          TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges,
-                          2, 0),
+                          TPS65218_ENABLE2_LDO1_EN, ldo1_dcdc3_ranges,
+                          2, 0, 0),
 };
 
 static int tps65218_regulator_probe(struct platform_device *pdev)
index 0a3bb3a..ccbb9f1 100644 (file)
@@ -74,6 +74,16 @@ static struct regulator_ops tps6586x_rw_regulator_ops = {
        .disable = regulator_disable_regmap,
 };
 
+static struct regulator_ops tps6586x_rw_linear_regulator_ops = {
+       .list_voltage = regulator_list_voltage_linear,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+};
+
 static struct regulator_ops tps6586x_ro_regulator_ops = {
        .list_voltage = regulator_list_voltage_table,
        .map_voltage = regulator_map_voltage_ascend,
@@ -91,48 +101,11 @@ static const unsigned int tps6586x_ldo0_voltages[] = {
        1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
 };
 
-static const unsigned int tps6586x_ldo4_voltages[] = {
-       1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000,
-       1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000,
-       2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000,
-       2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000,
-};
-
-#define tps658623_sm2_voltages tps6586x_ldo4_voltages
-
 static const unsigned int tps6586x_ldo_voltages[] = {
        1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000,
 };
 
-static const unsigned int tps6586x_sm2_voltages[] = {
-       3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000,
-       3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000,
-       3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000,
-       4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000,
-};
-
-static int tps658640_sm2_voltages[] = {
-       2150000, 2200000, 2250000, 2300000, 2350000, 2400000, 2450000, 2500000,
-       2550000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, 2900000,
-       2950000, 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000,
-       3350000, 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000,
-};
-
-static const unsigned int tps658643_sm2_voltages[] = {
-       1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000,
-       1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000,
-       1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000, 1600000,
-       1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000, 1800000,
-};
-
-static const unsigned int tps6586x_dvm_voltages[] = {
-        725000,  750000,  775000,  800000,  825000,  850000,  875000,  900000,
-        925000,  950000,  975000, 1000000, 1025000, 1050000, 1075000, 1100000,
-       1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
-       1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
-};
-
-static int tps658640_rtc_voltages[] = {
+static const unsigned int tps658640_rtc_voltages[] = {
        2500000, 2850000, 3100000, 3300000,
 };
 
@@ -159,6 +132,31 @@ static int tps658640_rtc_voltages[] = {
        .enable_reg[1]  = TPS6586X_SUPPLY##ereg1,                       \
        .enable_bit[1]  = (ebit1),
 
+#define TPS6586X_REGULATOR_LINEAR(_id, _ops, _pin_name, n_volt, min_uv,        \
+                                 uv_step, vreg, shift, nbits, ereg0,   \
+                                 ebit0, ereg1, ebit1, goreg, gobit)    \
+       .desc   = {                                                     \
+               .supply_name = _pin_name,                               \
+               .name   = "REG-" #_id,                                  \
+               .ops    = &tps6586x_## _ops ## _regulator_ops,          \
+               .type   = REGULATOR_VOLTAGE,                            \
+               .id     = TPS6586X_ID_##_id,                            \
+               .n_voltages = n_volt,                                   \
+               .min_uV = min_uv,                                       \
+               .uV_step = uv_step,                                     \
+               .owner  = THIS_MODULE,                                  \
+               .enable_reg = TPS6586X_SUPPLY##ereg0,                   \
+               .enable_mask = 1 << (ebit0),                            \
+               .vsel_reg = TPS6586X_##vreg,                            \
+               .vsel_mask = ((1 << (nbits)) - 1) << (shift),           \
+               .apply_reg = (goreg),                           \
+               .apply_bit = (gobit),                           \
+       },                                                              \
+       .enable_reg[0]  = TPS6586X_SUPPLY##ereg0,                       \
+       .enable_bit[0]  = (ebit0),                                      \
+       .enable_reg[1]  = TPS6586X_SUPPLY##ereg1,                       \
+       .enable_bit[1]  = (ebit1),
+
 #define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits,           \
                     ereg0, ebit0, ereg1, ebit1)                        \
 {                                                                      \
@@ -166,6 +164,14 @@ static int tps658640_rtc_voltages[] = {
                           ereg0, ebit0, ereg1, ebit1, 0, 0)            \
 }
 
+#define TPS6586X_LDO_LINEAR(_id, _pname, n_volt, min_uv, uv_step, vreg,        \
+                           shift, nbits, ereg0, ebit0, ereg1, ebit1)   \
+{                                                                      \
+       TPS6586X_REGULATOR_LINEAR(_id, rw_linear, _pname, n_volt,       \
+                                 min_uv, uv_step, vreg, shift, nbits,  \
+                                 ereg0, ebit0, ereg1, ebit1, 0, 0)     \
+}
+
 #define TPS6586X_FIXED_LDO(_id, _pname, vdata, vreg, shift, nbits,     \
                          ereg0, ebit0, ereg1, ebit1)                   \
 {                                                                      \
@@ -173,11 +179,13 @@ static int tps658640_rtc_voltages[] = {
                           ereg0, ebit0, ereg1, ebit1, 0, 0)            \
 }
 
-#define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits,           \
-                    ereg0, ebit0, ereg1, ebit1, goreg, gobit)          \
+#define TPS6586X_DVM(_id, _pname, n_volt, min_uv, uv_step, vreg, shift,        \
+                    nbits, ereg0, ebit0, ereg1, ebit1, goreg, gobit)   \
 {                                                                      \
-       TPS6586X_REGULATOR(_id, rw, _pname, vdata, vreg, shift, nbits,  \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)    \
+       TPS6586X_REGULATOR_LINEAR(_id, rw_linear, _pname, n_volt,       \
+                                 min_uv, uv_step, vreg, shift, nbits,  \
+                                 ereg0, ebit0, ereg1, ebit1, goreg,    \
+                                 gobit)                                \
 }
 
 #define TPS6586X_SYS_REGULATOR()                                       \
@@ -210,24 +218,23 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
                                        ENE, 7),
        TPS6586X_LDO(LDO_RTC, "REG-SYS", tps6586x_ldo, SUPPLYV4, 3, 3, V4, 7,
                                        V4, 7),
-       TPS6586X_LDO(LDO_1, "vinldo01", tps6586x_dvm, SUPPLYV1, 0, 5, ENC, 1,
-                                       END, 1),
-       TPS6586X_LDO(SM_2, "vin-sm2", tps6586x_sm2, SUPPLYV2, 0, 5, ENC, 7,
-                                       END, 7),
-
-       TPS6586X_DVM(LDO_2, "vinldo23", tps6586x_dvm, LDO2BV1, 0, 5, ENA, 3,
-                                       ENB, 3, TPS6586X_VCC2, BIT(6)),
-       TPS6586X_DVM(LDO_4, "vinldo4", tps6586x_ldo4, LDO4V1, 0, 5, ENC, 3,
-                                       END, 3, TPS6586X_VCC1, BIT(6)),
-       TPS6586X_DVM(SM_0, "vin-sm0", tps6586x_dvm, SM0V1, 0, 5, ENA, 1,
-                                       ENB, 1, TPS6586X_VCC1, BIT(2)),
-       TPS6586X_DVM(SM_1, "vin-sm1", tps6586x_dvm, SM1V1, 0, 5, ENA, 0,
-                                       ENB, 0, TPS6586X_VCC1, BIT(0)),
+       TPS6586X_LDO_LINEAR(LDO_1, "vinldo01", 32, 725000, 25000, SUPPLYV1,
+                           0, 5, ENC, 1, END, 1),
+       TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 3000000, 50000, SUPPLYV2,
+                           0, 5, ENC, 7, END, 7),
+       TPS6586X_DVM(LDO_2, "vinldo23", 32, 725000, 25000, LDO2BV1, 0, 5,
+                    ENA, 3, ENB, 3, TPS6586X_VCC2, BIT(6)),
+       TPS6586X_DVM(LDO_4, "vinldo4", 32, 1700000, 25000, LDO4V1, 0, 5,
+                    ENC, 3, END, 3, TPS6586X_VCC1, BIT(6)),
+       TPS6586X_DVM(SM_0, "vin-sm0", 32, 725000, 25000, SM0V1, 0, 5,
+                    ENA, 1, ENB, 1, TPS6586X_VCC1, BIT(2)),
+       TPS6586X_DVM(SM_1, "vin-sm1", 32, 725000, 25000, SM1V1, 0, 5,
+                    ENA, 0, ENB, 0, TPS6586X_VCC1, BIT(0)),
 };
 
 static struct tps6586x_regulator tps658623_regulator[] = {
-       TPS6586X_LDO(SM_2, "vin-sm2", tps658623_sm2, SUPPLYV2, 0, 5, ENC, 7,
-                                       END, 7),
+       TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 1700000, 25000, SUPPLYV2,
+                           0, 5, ENC, 7, END, 7),
 };
 
 static struct tps6586x_regulator tps658640_regulator[] = {
@@ -243,16 +250,16 @@ static struct tps6586x_regulator tps658640_regulator[] = {
                                        ENC, 6, END, 6),
        TPS6586X_LDO(LDO_9, "vinldo9", tps6586x_ldo0, SUPPLYV6, 3, 3,
                                        ENE, 7, ENE, 7),
-       TPS6586X_LDO(SM_2, "vin-sm2", tps658640_sm2, SUPPLYV2, 0, 5,
-                                       ENC, 7, END, 7),
+       TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 2150000, 50000, SUPPLYV2,
+                           0, 5, ENC, 7, END, 7),
 
        TPS6586X_FIXED_LDO(LDO_RTC, "REG-SYS", tps658640_rtc, SUPPLYV4, 3, 2,
                                        V4, 7, V4, 7),
 };
 
 static struct tps6586x_regulator tps658643_regulator[] = {
-       TPS6586X_LDO(SM_2, "vin-sm2", tps658643_sm2, SUPPLYV2, 0, 5, ENC, 7,
-                                       END, 7),
+       TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 1025000, 25000, SUPPLYV2,
+                           0, 5, ENC, 7, END, 7),
 };
 
 /*
index fed28ab..0b4f866 100644 (file)
@@ -1128,7 +1128,7 @@ static int twlreg_probe(struct platform_device *pdev)
        if (!initdata)
                return -EINVAL;
 
-       info = kmemdup(template, sizeof(*info), GFP_KERNEL);
+       info = devm_kmemdup(&pdev->dev, template, sizeof(*info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
 
@@ -1192,7 +1192,6 @@ static int twlreg_probe(struct platform_device *pdev)
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "can't register %s, %ld\n",
                                info->desc.name, PTR_ERR(rdev));
-               kfree(info);
                return PTR_ERR(rdev);
        }
        platform_set_drvdata(pdev, rdev);
@@ -1212,20 +1211,10 @@ static int twlreg_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int twlreg_remove(struct platform_device *pdev)
-{
-       struct regulator_dev *rdev = platform_get_drvdata(pdev);
-       struct twlreg_info *info = rdev->reg_data;
-
-       kfree(info);
-       return 0;
-}
-
 MODULE_ALIAS("platform:twl_reg");
 
 static struct platform_driver twlreg_driver = {
        .probe          = twlreg_probe,
-       .remove         = twlreg_remove,
        /* NOTE: short name, to work around driver model truncation of
         * "twl_regulator.12" (and friends) to "twl_regulator.1".
         */
index 3e050b9..c466ff3 100644 (file)
@@ -262,6 +262,41 @@ enum max77693_irq_source {
        MAX77693_IRQ_GROUP_NR,
 };
 
+#define LED_IRQ_FLED2_OPEN             BIT(0)
+#define LED_IRQ_FLED2_SHORT            BIT(1)
+#define LED_IRQ_FLED1_OPEN             BIT(2)
+#define LED_IRQ_FLED1_SHORT            BIT(3)
+#define LED_IRQ_MAX_FLASH              BIT(4)
+
+#define TOPSYS_IRQ_T120C_INT           BIT(0)
+#define TOPSYS_IRQ_T140C_INT           BIT(1)
+#define TOPSYS_IRQ_LOWSYS_INT          BIT(3)
+
+#define CHG_IRQ_BYP_I                  BIT(0)
+#define CHG_IRQ_THM_I                  BIT(2)
+#define CHG_IRQ_BAT_I                  BIT(3)
+#define CHG_IRQ_CHG_I                  BIT(4)
+#define CHG_IRQ_CHGIN_I                        BIT(6)
+
+#define MUIC_IRQ_INT1_ADC              BIT(0)
+#define MUIC_IRQ_INT1_ADC_LOW          BIT(1)
+#define MUIC_IRQ_INT1_ADC_ERR          BIT(2)
+#define MUIC_IRQ_INT1_ADC1K            BIT(3)
+
+#define MUIC_IRQ_INT2_CHGTYP           BIT(0)
+#define MUIC_IRQ_INT2_CHGDETREUN       BIT(1)
+#define MUIC_IRQ_INT2_DCDTMR           BIT(2)
+#define MUIC_IRQ_INT2_DXOVP            BIT(3)
+#define MUIC_IRQ_INT2_VBVOLT           BIT(4)
+#define MUIC_IRQ_INT2_VIDRM            BIT(5)
+
+#define MUIC_IRQ_INT3_EOC              BIT(0)
+#define MUIC_IRQ_INT3_CGMBC            BIT(1)
+#define MUIC_IRQ_INT3_OVP              BIT(2)
+#define MUIC_IRQ_INT3_MBCCHG_ERR       BIT(3)
+#define MUIC_IRQ_INT3_CHG_ENABLED      BIT(4)
+#define MUIC_IRQ_INT3_BAT_DET          BIT(5)
+
 enum max77693_irq {
        /* PMIC - FLASH */
        MAX77693_LED_IRQ_FLED2_OPEN,
@@ -282,6 +317,10 @@ enum max77693_irq {
        MAX77693_CHG_IRQ_CHG_I,
        MAX77693_CHG_IRQ_CHGIN_I,
 
+       MAX77693_IRQ_NR,
+};
+
+enum max77693_irq_muic {
        /* MUIC INT1 */
        MAX77693_MUIC_IRQ_INT1_ADC,
        MAX77693_MUIC_IRQ_INT1_ADC_LOW,
@@ -304,7 +343,7 @@ enum max77693_irq {
        MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,
        MAX77693_MUIC_IRQ_INT3_BAT_DET,
 
-       MAX77693_IRQ_NR,
+       MAX77693_MUIC_IRQ_NR,
 };
 
 struct max77693_dev {
@@ -319,7 +358,10 @@ struct max77693_dev {
        struct regmap *regmap_muic;
        struct regmap *regmap_haptic;
 
-       struct irq_domain *irq_domain;
+       struct regmap_irq_chip_data *irq_data_led;
+       struct regmap_irq_chip_data *irq_data_topsys;
+       struct regmap_irq_chip_data *irq_data_charger;
+       struct regmap_irq_chip_data *irq_data_muic;
 
        int irq;
        int irq_gpio;
@@ -332,14 +374,6 @@ enum max77693_types {
        TYPE_MAX77693,
 };
 
-extern int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest);
-extern int max77693_bulk_read(struct regmap *map, u8 reg, int count,
-                               u8 *buf);
-extern int max77693_write_reg(struct regmap *map, u8 reg, u8 value);
-extern int max77693_bulk_write(struct regmap *map, u8 reg, int count,
-                               u8 *buf);
-extern int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask);
-
 extern int max77693_irq_init(struct max77693_dev *max77686);
 extern void max77693_irq_exit(struct max77693_dev *max77686);
 extern int max77693_irq_resume(struct max77693_dev *max77686);
index 3420e09..fb0390a 100644 (file)
@@ -30,6 +30,8 @@
 #define PALMAS_CHIP_ID                 0xC035
 #define PALMAS_CHIP_CHARGER_ID         0xC036
 
+#define TPS65917_RESERVED              -1
+
 #define is_palmas(a)   (((a) == PALMAS_CHIP_OLD_ID) || \
                        ((a) == PALMAS_CHIP_ID))
 #define is_palmas_charger(a) ((a) == PALMAS_CHIP_CHARGER_ID)
@@ -51,6 +53,8 @@ struct palmas_pmic;
 struct palmas_gpadc;
 struct palmas_resource;
 struct palmas_usb;
+struct palmas_pmic_driver_data;
+struct palmas_pmic_platform_data;
 
 enum palmas_usb_state {
        PALMAS_USB_STATE_DISCONNECT,
@@ -74,6 +78,8 @@ struct palmas {
        struct mutex irq_lock;
        struct regmap_irq_chip_data *irq_data;
 
+       struct palmas_pmic_driver_data *pmic_ddata;
+
        /* Child Devices */
        struct palmas_pmic *pmic;
        struct palmas_gpadc *gpadc;
@@ -86,6 +92,46 @@ struct palmas {
        u8 pwm_muxed;
 };
 
+#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 |   \
+                       PALMAS_EXT_CONTROL_ENABLE2 |    \
+                       PALMAS_EXT_CONTROL_NSLEEP)
+
+struct palmas_sleep_requestor_info {
+       int id;
+       int reg_offset;
+       int bit_pos;
+};
+
+struct palmas_regs_info {
+       char    *name;
+       char    *sname;
+       u8      vsel_addr;
+       u8      ctrl_addr;
+       u8      tstep_addr;
+       int     sleep_id;
+};
+
+struct palmas_pmic_driver_data {
+       int smps_start;
+       int smps_end;
+       int ldo_begin;
+       int ldo_end;
+       int max_reg;
+       struct palmas_regs_info *palmas_regs_info;
+       struct of_regulator_match *palmas_matches;
+       struct palmas_sleep_requestor_info *sleep_req_info;
+       int (*smps_register)(struct palmas_pmic *pmic,
+                            struct palmas_pmic_driver_data *ddata,
+                            struct palmas_pmic_platform_data *pdata,
+                            const char *pdev_name,
+                            struct regulator_config config);
+       int (*ldo_register)(struct palmas_pmic *pmic,
+                           struct palmas_pmic_driver_data *ddata,
+                           struct palmas_pmic_platform_data *pdata,
+                           const char *pdev_name,
+                           struct regulator_config config);
+};
+
 struct palmas_gpadc_platform_data {
        /* Channel 3 current source is only enabled during conversion */
        int ch3_current;
@@ -184,6 +230,27 @@ enum palmas_regulators {
        PALMAS_NUM_REGS,
 };
 
+enum tps65917_regulators {
+       /* SMPS regulators */
+       TPS65917_REG_SMPS1,
+       TPS65917_REG_SMPS2,
+       TPS65917_REG_SMPS3,
+       TPS65917_REG_SMPS4,
+       TPS65917_REG_SMPS5,
+       /* LDO regulators */
+       TPS65917_REG_LDO1,
+       TPS65917_REG_LDO2,
+       TPS65917_REG_LDO3,
+       TPS65917_REG_LDO4,
+       TPS65917_REG_LDO5,
+       TPS65917_REG_REGEN1,
+       TPS65917_REG_REGEN2,
+       TPS65917_REG_REGEN3,
+
+       /* Total number of regulators */
+       TPS65917_NUM_REGS,
+};
+
 /* External controll signal name */
 enum {
        PALMAS_EXT_CONTROL_ENABLE1      = 0x1,
@@ -228,6 +295,24 @@ enum palmas_external_requestor_id {
        PALMAS_EXTERNAL_REQSTR_ID_MAX,
 };
 
+enum tps65917_external_requestor_id {
+       TPS65917_EXTERNAL_REQSTR_ID_REGEN1,
+       TPS65917_EXTERNAL_REQSTR_ID_REGEN2,
+       TPS65917_EXTERNAL_REQSTR_ID_REGEN3,
+       TPS65917_EXTERNAL_REQSTR_ID_SMPS1,
+       TPS65917_EXTERNAL_REQSTR_ID_SMPS2,
+       TPS65917_EXTERNAL_REQSTR_ID_SMPS3,
+       TPS65917_EXTERNAL_REQSTR_ID_SMPS4,
+       TPS65917_EXTERNAL_REQSTR_ID_SMPS5,
+       TPS65917_EXTERNAL_REQSTR_ID_LDO1,
+       TPS65917_EXTERNAL_REQSTR_ID_LDO2,
+       TPS65917_EXTERNAL_REQSTR_ID_LDO3,
+       TPS65917_EXTERNAL_REQSTR_ID_LDO4,
+       TPS65917_EXTERNAL_REQSTR_ID_LDO5,
+       /* Last entry */
+       TPS65917_EXTERNAL_REQSTR_ID_MAX,
+};
+
 struct palmas_pmic_platform_data {
        /* An array of pointers to regulator init data indexed by regulator
         * ID
@@ -349,6 +434,48 @@ struct palmas_gpadc_result {
 
 #define PALMAS_MAX_CHANNELS 16
 
+/* Define the tps65917 IRQ numbers */
+enum tps65917_irqs {
+       /* INT1 registers */
+       TPS65917_RESERVED1,
+       TPS65917_PWRON_IRQ,
+       TPS65917_LONG_PRESS_KEY_IRQ,
+       TPS65917_RESERVED2,
+       TPS65917_PWRDOWN_IRQ,
+       TPS65917_HOTDIE_IRQ,
+       TPS65917_VSYS_MON_IRQ,
+       TPS65917_RESERVED3,
+       /* INT2 registers */
+       TPS65917_RESERVED4,
+       TPS65917_OTP_ERROR_IRQ,
+       TPS65917_WDT_IRQ,
+       TPS65917_RESERVED5,
+       TPS65917_RESET_IN_IRQ,
+       TPS65917_FSD_IRQ,
+       TPS65917_SHORT_IRQ,
+       TPS65917_RESERVED6,
+       /* INT3 registers */
+       TPS65917_GPADC_AUTO_0_IRQ,
+       TPS65917_GPADC_AUTO_1_IRQ,
+       TPS65917_GPADC_EOC_SW_IRQ,
+       TPS65917_RESREVED6,
+       TPS65917_RESERVED7,
+       TPS65917_RESERVED8,
+       TPS65917_RESERVED9,
+       TPS65917_VBUS_IRQ,
+       /* INT4 registers */
+       TPS65917_GPIO_0_IRQ,
+       TPS65917_GPIO_1_IRQ,
+       TPS65917_GPIO_2_IRQ,
+       TPS65917_GPIO_3_IRQ,
+       TPS65917_GPIO_4_IRQ,
+       TPS65917_GPIO_5_IRQ,
+       TPS65917_GPIO_6_IRQ,
+       TPS65917_RESERVED10,
+       /* Total Number IRQs */
+       TPS65917_NUM_IRQ,
+};
+
 /* Define the palmas IRQ numbers */
 enum palmas_irqs {
        /* INT1 registers */
@@ -400,6 +527,7 @@ struct palmas_pmic {
 
        int smps123;
        int smps457;
+       int smps12;
 
        int range[PALMAS_REG_SMPS10_OUT1];
        unsigned int ramp_delay[PALMAS_REG_SMPS10_OUT1];
@@ -2871,6 +2999,715 @@ enum usb_irq_events {
 #define PALMAS_GPADC_TRIM15                                    0x0E
 #define PALMAS_GPADC_TRIM16                                    0x0F
 
+/* TPS65917 Interrupt registers */
+
+/* Registers for function INTERRUPT */
+#define TPS65917_INT1_STATUS                                   0x00
+#define TPS65917_INT1_MASK                                     0x01
+#define TPS65917_INT1_LINE_STATE                               0x02
+#define TPS65917_INT2_STATUS                                   0x05
+#define TPS65917_INT2_MASK                                     0x06
+#define TPS65917_INT2_LINE_STATE                               0x07
+#define TPS65917_INT3_STATUS                                   0x0A
+#define TPS65917_INT3_MASK                                     0x0B
+#define TPS65917_INT3_LINE_STATE                               0x0C
+#define TPS65917_INT4_STATUS                                   0x0F
+#define TPS65917_INT4_MASK                                     0x10
+#define TPS65917_INT4_LINE_STATE                               0x11
+#define TPS65917_INT4_EDGE_DETECT1                             0x12
+#define TPS65917_INT4_EDGE_DETECT2                             0x13
+#define TPS65917_INT_CTRL                                      0x14
+
+/* Bit definitions for INT1_STATUS */
+#define TPS65917_INT1_STATUS_VSYS_MON                          0x40
+#define TPS65917_INT1_STATUS_VSYS_MON_SHIFT                    0x06
+#define TPS65917_INT1_STATUS_HOTDIE                            0x20
+#define TPS65917_INT1_STATUS_HOTDIE_SHIFT                      0x05
+#define TPS65917_INT1_STATUS_PWRDOWN                           0x10
+#define TPS65917_INT1_STATUS_PWRDOWN_SHIFT                     0x04
+#define TPS65917_INT1_STATUS_LONG_PRESS_KEY                    0x04
+#define TPS65917_INT1_STATUS_LONG_PRESS_KEY_SHIFT              0x02
+#define TPS65917_INT1_STATUS_PWRON                             0x02
+#define TPS65917_INT1_STATUS_PWRON_SHIFT                       0x01
+
+/* Bit definitions for INT1_MASK */
+#define TPS65917_INT1_MASK_VSYS_MON                            0x40
+#define TPS65917_INT1_MASK_VSYS_MON_SHIFT                      0x06
+#define TPS65917_INT1_MASK_HOTDIE                              0x20
+#define TPS65917_INT1_MASK_HOTDIE_SHIFT                        0x05
+#define TPS65917_INT1_MASK_PWRDOWN                             0x10
+#define TPS65917_INT1_MASK_PWRDOWN_SHIFT                       0x04
+#define TPS65917_INT1_MASK_LONG_PRESS_KEY                      0x04
+#define TPS65917_INT1_MASK_LONG_PRESS_KEY_SHIFT                0x02
+#define TPS65917_INT1_MASK_PWRON                               0x02
+#define TPS65917_INT1_MASK_PWRON_SHIFT                         0x01
+
+/* Bit definitions for INT1_LINE_STATE */
+#define TPS65917_INT1_LINE_STATE_VSYS_MON                      0x40
+#define TPS65917_INT1_LINE_STATE_VSYS_MON_SHIFT                0x06
+#define TPS65917_INT1_LINE_STATE_HOTDIE                        0x20
+#define TPS65917_INT1_LINE_STATE_HOTDIE_SHIFT                  0x05
+#define TPS65917_INT1_LINE_STATE_PWRDOWN                       0x10
+#define TPS65917_INT1_LINE_STATE_PWRDOWN_SHIFT                 0x04
+#define TPS65917_INT1_LINE_STATE_LONG_PRESS_KEY                0x04
+#define TPS65917_INT1_LINE_STATE_LONG_PRESS_KEY_SHIFT          0x02
+#define TPS65917_INT1_LINE_STATE_PWRON                         0x02
+#define TPS65917_INT1_LINE_STATE_PWRON_SHIFT                   0x01
+
+/* Bit definitions for INT2_STATUS */
+#define TPS65917_INT2_STATUS_SHORT                             0x40
+#define TPS65917_INT2_STATUS_SHORT_SHIFT                       0x06
+#define TPS65917_INT2_STATUS_FSD                               0x20
+#define TPS65917_INT2_STATUS_FSD_SHIFT                         0x05
+#define TPS65917_INT2_STATUS_RESET_IN                          0x10
+#define TPS65917_INT2_STATUS_RESET_IN_SHIFT                    0x04
+#define TPS65917_INT2_STATUS_WDT                               0x04
+#define TPS65917_INT2_STATUS_WDT_SHIFT                         0x02
+#define TPS65917_INT2_STATUS_OTP_ERROR                         0x02
+#define TPS65917_INT2_STATUS_OTP_ERROR_SHIFT                   0x01
+
+/* Bit definitions for INT2_MASK */
+#define TPS65917_INT2_MASK_SHORT                               0x40
+#define TPS65917_INT2_MASK_SHORT_SHIFT                         0x06
+#define TPS65917_INT2_MASK_FSD                                 0x20
+#define TPS65917_INT2_MASK_FSD_SHIFT                           0x05
+#define TPS65917_INT2_MASK_RESET_IN                            0x10
+#define TPS65917_INT2_MASK_RESET_IN_SHIFT                      0x04
+#define TPS65917_INT2_MASK_WDT                                 0x04
+#define TPS65917_INT2_MASK_WDT_SHIFT                           0x02
+#define TPS65917_INT2_MASK_OTP_ERROR_TIMER                     0x02
+#define TPS65917_INT2_MASK_OTP_ERROR_SHIFT                     0x01
+
+/* Bit definitions for INT2_LINE_STATE */
+#define TPS65917_INT2_LINE_STATE_SHORT                         0x40
+#define TPS65917_INT2_LINE_STATE_SHORT_SHIFT                   0x06
+#define TPS65917_INT2_LINE_STATE_FSD                           0x20
+#define TPS65917_INT2_LINE_STATE_FSD_SHIFT                     0x05
+#define TPS65917_INT2_LINE_STATE_RESET_IN                      0x10
+#define TPS65917_INT2_LINE_STATE_RESET_IN_SHIFT                0x04
+#define TPS65917_INT2_LINE_STATE_WDT                           0x04
+#define TPS65917_INT2_LINE_STATE_WDT_SHIFT                     0x02
+#define TPS65917_INT2_LINE_STATE_OTP_ERROR                     0x02
+#define TPS65917_INT2_LINE_STATE_OTP_ERROR_SHIFT               0x01
+
+/* Bit definitions for INT3_STATUS */
+#define TPS65917_INT3_STATUS_VBUS                              0x80
+#define TPS65917_INT3_STATUS_VBUS_SHIFT                        0x07
+#define TPS65917_INT3_STATUS_GPADC_EOC_SW                      0x04
+#define TPS65917_INT3_STATUS_GPADC_EOC_SW_SHIFT                0x02
+#define TPS65917_INT3_STATUS_GPADC_AUTO_1                      0x02
+#define TPS65917_INT3_STATUS_GPADC_AUTO_1_SHIFT                0x01
+#define TPS65917_INT3_STATUS_GPADC_AUTO_0                      0x01
+#define TPS65917_INT3_STATUS_GPADC_AUTO_0_SHIFT                0x00
+
+/* Bit definitions for INT3_MASK */
+#define TPS65917_INT3_MASK_VBUS                                0x80
+#define TPS65917_INT3_MASK_VBUS_SHIFT                          0x07
+#define TPS65917_INT3_MASK_GPADC_EOC_SW                        0x04
+#define TPS65917_INT3_MASK_GPADC_EOC_SW_SHIFT                  0x02
+#define TPS65917_INT3_MASK_GPADC_AUTO_1                        0x02
+#define TPS65917_INT3_MASK_GPADC_AUTO_1_SHIFT                  0x01
+#define TPS65917_INT3_MASK_GPADC_AUTO_0                        0x01
+#define TPS65917_INT3_MASK_GPADC_AUTO_0_SHIFT                  0x00
+
+/* Bit definitions for INT3_LINE_STATE */
+#define TPS65917_INT3_LINE_STATE_VBUS                          0x80
+#define TPS65917_INT3_LINE_STATE_VBUS_SHIFT                    0x07
+#define TPS65917_INT3_LINE_STATE_GPADC_EOC_SW                  0x04
+#define TPS65917_INT3_LINE_STATE_GPADC_EOC_SW_SHIFT            0x02
+#define TPS65917_INT3_LINE_STATE_GPADC_AUTO_1                  0x02
+#define TPS65917_INT3_LINE_STATE_GPADC_AUTO_1_SHIFT            0x01
+#define TPS65917_INT3_LINE_STATE_GPADC_AUTO_0                  0x01
+#define TPS65917_INT3_LINE_STATE_GPADC_AUTO_0_SHIFT            0x00
+
+/* Bit definitions for INT4_STATUS */
+#define TPS65917_INT4_STATUS_GPIO_6                            0x40
+#define TPS65917_INT4_STATUS_GPIO_6_SHIFT                      0x06
+#define TPS65917_INT4_STATUS_GPIO_5                            0x20
+#define TPS65917_INT4_STATUS_GPIO_5_SHIFT                      0x05
+#define TPS65917_INT4_STATUS_GPIO_4                            0x10
+#define TPS65917_INT4_STATUS_GPIO_4_SHIFT                      0x04
+#define TPS65917_INT4_STATUS_GPIO_3                            0x08
+#define TPS65917_INT4_STATUS_GPIO_3_SHIFT                      0x03
+#define TPS65917_INT4_STATUS_GPIO_2                            0x04
+#define TPS65917_INT4_STATUS_GPIO_2_SHIFT                      0x02
+#define TPS65917_INT4_STATUS_GPIO_1                            0x02
+#define TPS65917_INT4_STATUS_GPIO_1_SHIFT                      0x01
+#define TPS65917_INT4_STATUS_GPIO_0                            0x01
+#define TPS65917_INT4_STATUS_GPIO_0_SHIFT                      0x00
+
+/* Bit definitions for INT4_MASK */
+#define TPS65917_INT4_MASK_GPIO_6                              0x40
+#define TPS65917_INT4_MASK_GPIO_6_SHIFT                        0x06
+#define TPS65917_INT4_MASK_GPIO_5                              0x20
+#define TPS65917_INT4_MASK_GPIO_5_SHIFT                        0x05
+#define TPS65917_INT4_MASK_GPIO_4                              0x10
+#define TPS65917_INT4_MASK_GPIO_4_SHIFT                        0x04
+#define TPS65917_INT4_MASK_GPIO_3                              0x08
+#define TPS65917_INT4_MASK_GPIO_3_SHIFT                        0x03
+#define TPS65917_INT4_MASK_GPIO_2                              0x04
+#define TPS65917_INT4_MASK_GPIO_2_SHIFT                        0x02
+#define TPS65917_INT4_MASK_GPIO_1                              0x02
+#define TPS65917_INT4_MASK_GPIO_1_SHIFT                        0x01
+#define TPS65917_INT4_MASK_GPIO_0                              0x01
+#define TPS65917_INT4_MASK_GPIO_0_SHIFT                        0x00
+
+/* Bit definitions for INT4_LINE_STATE */
+#define TPS65917_INT4_LINE_STATE_GPIO_6                        0x40
+#define TPS65917_INT4_LINE_STATE_GPIO_6_SHIFT                  0x06
+#define TPS65917_INT4_LINE_STATE_GPIO_5                        0x20
+#define TPS65917_INT4_LINE_STATE_GPIO_5_SHIFT                  0x05
+#define TPS65917_INT4_LINE_STATE_GPIO_4                        0x10
+#define TPS65917_INT4_LINE_STATE_GPIO_4_SHIFT                  0x04
+#define TPS65917_INT4_LINE_STATE_GPIO_3                        0x08
+#define TPS65917_INT4_LINE_STATE_GPIO_3_SHIFT                  0x03
+#define TPS65917_INT4_LINE_STATE_GPIO_2                        0x04
+#define TPS65917_INT4_LINE_STATE_GPIO_2_SHIFT                  0x02
+#define TPS65917_INT4_LINE_STATE_GPIO_1                        0x02
+#define TPS65917_INT4_LINE_STATE_GPIO_1_SHIFT                  0x01
+#define TPS65917_INT4_LINE_STATE_GPIO_0                        0x01
+#define TPS65917_INT4_LINE_STATE_GPIO_0_SHIFT                  0x00
+
+/* Bit definitions for INT4_EDGE_DETECT1 */
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_3_RISING               0x80
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_3_RISING_SHIFT         0x07
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_3_FALLING              0x40
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_3_FALLING_SHIFT        0x06
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_2_RISING               0x20
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_2_RISING_SHIFT         0x05
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_2_FALLING              0x10
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_2_FALLING_SHIFT        0x04
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_1_RISING               0x08
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_1_RISING_SHIFT         0x03
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_1_FALLING              0x04
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_1_FALLING_SHIFT        0x02
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_0_RISING               0x02
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_0_RISING_SHIFT         0x01
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_0_FALLING              0x01
+#define TPS65917_INT4_EDGE_DETECT1_GPIO_0_FALLING_SHIFT        0x00
+
+/* Bit definitions for INT4_EDGE_DETECT2 */
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_6_RISING               0x20
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_6_RISING_SHIFT         0x05
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_6_FALLING              0x10
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_6_FALLING_SHIFT        0x04
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_5_RISING               0x08
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_5_RISING_SHIFT         0x03
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_5_FALLING              0x04
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_5_FALLING_SHIFT        0x02
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_4_RISING               0x02
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_4_RISING_SHIFT         0x01
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_4_FALLING              0x01
+#define TPS65917_INT4_EDGE_DETECT2_GPIO_4_FALLING_SHIFT        0x00
+
+/* Bit definitions for INT_CTRL */
+#define TPS65917_INT_CTRL_INT_PENDING                          0x04
+#define TPS65917_INT_CTRL_INT_PENDING_SHIFT                    0x02
+#define TPS65917_INT_CTRL_INT_CLEAR                            0x01
+#define TPS65917_INT_CTRL_INT_CLEAR_SHIFT                      0x00
+
+/* TPS65917 SMPS Registers */
+
+/* Registers for function SMPS */
+#define TPS65917_SMPS1_CTRL                                    0x00
+#define TPS65917_SMPS1_FORCE                                   0x02
+#define TPS65917_SMPS1_VOLTAGE                                 0x03
+#define TPS65917_SMPS2_CTRL                                    0x04
+#define TPS65917_SMPS2_FORCE                                   0x06
+#define TPS65917_SMPS2_VOLTAGE                                 0x07
+#define TPS65917_SMPS3_CTRL                                    0x0C
+#define TPS65917_SMPS3_FORCE                                   0x0E
+#define TPS65917_SMPS3_VOLTAGE                                 0x0F
+#define TPS65917_SMPS4_CTRL                                    0x10
+#define TPS65917_SMPS4_VOLTAGE                                 0x13
+#define TPS65917_SMPS5_CTRL                                    0x18
+#define TPS65917_SMPS5_VOLTAGE                                 0x1B
+#define TPS65917_SMPS_CTRL                                     0x24
+#define TPS65917_SMPS_PD_CTRL                                  0x25
+#define TPS65917_SMPS_THERMAL_EN                               0x27
+#define TPS65917_SMPS_THERMAL_STATUS                           0x28
+#define TPS65917_SMPS_SHORT_STATUS                             0x29
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN                0x2A
+#define TPS65917_SMPS_POWERGOOD_MASK1                          0x2B
+#define TPS65917_SMPS_POWERGOOD_MASK2                          0x2C
+
+/* Bit definitions for SMPS1_CTRL */
+#define TPS65917_SMPS1_CTRL_WR_S                               0x80
+#define TPS65917_SMPS1_CTRL_WR_S_SHIFT                         0x07
+#define TPS65917_SMPS1_CTRL_ROOF_FLOOR_EN                      0x40
+#define TPS65917_SMPS1_CTRL_ROOF_FLOOR_EN_SHIFT                0x06
+#define TPS65917_SMPS1_CTRL_STATUS_MASK                        0x30
+#define TPS65917_SMPS1_CTRL_STATUS_SHIFT                       0x04
+#define TPS65917_SMPS1_CTRL_MODE_SLEEP_MASK                    0x0C
+#define TPS65917_SMPS1_CTRL_MODE_SLEEP_SHIFT                   0x02
+#define TPS65917_SMPS1_CTRL_MODE_ACTIVE_MASK                   0x03
+#define TPS65917_SMPS1_CTRL_MODE_ACTIVE_SHIFT                  0x00
+
+/* Bit definitions for SMPS1_FORCE */
+#define TPS65917_SMPS1_FORCE_CMD                               0x80
+#define TPS65917_SMPS1_FORCE_CMD_SHIFT                         0x07
+#define TPS65917_SMPS1_FORCE_VSEL_MASK                         0x7F
+#define TPS65917_SMPS1_FORCE_VSEL_SHIFT                        0x00
+
+/* Bit definitions for SMPS1_VOLTAGE */
+#define TPS65917_SMPS1_VOLTAGE_RANGE                           0x80
+#define TPS65917_SMPS1_VOLTAGE_RANGE_SHIFT                     0x07
+#define TPS65917_SMPS1_VOLTAGE_VSEL_MASK                       0x7F
+#define TPS65917_SMPS1_VOLTAGE_VSEL_SHIFT                      0x00
+
+/* Bit definitions for SMPS2_CTRL */
+#define TPS65917_SMPS2_CTRL_WR_S                               0x80
+#define TPS65917_SMPS2_CTRL_WR_S_SHIFT                         0x07
+#define TPS65917_SMPS2_CTRL_ROOF_FLOOR_EN                      0x40
+#define TPS65917_SMPS2_CTRL_ROOF_FLOOR_EN_SHIFT                0x06
+#define TPS65917_SMPS2_CTRL_STATUS_MASK                        0x30
+#define TPS65917_SMPS2_CTRL_STATUS_SHIFT                       0x04
+#define TPS65917_SMPS2_CTRL_MODE_SLEEP_MASK                    0x0C
+#define TPS65917_SMPS2_CTRL_MODE_SLEEP_SHIFT                   0x02
+#define TPS65917_SMPS2_CTRL_MODE_ACTIVE_MASK                   0x03
+#define TPS65917_SMPS2_CTRL_MODE_ACTIVE_SHIFT                  0x00
+
+/* Bit definitions for SMPS2_FORCE */
+#define TPS65917_SMPS2_FORCE_CMD                               0x80
+#define TPS65917_SMPS2_FORCE_CMD_SHIFT                         0x07
+#define TPS65917_SMPS2_FORCE_VSEL_MASK                         0x7F
+#define TPS65917_SMPS2_FORCE_VSEL_SHIFT                        0x00
+
+/* Bit definitions for SMPS2_VOLTAGE */
+#define TPS65917_SMPS2_VOLTAGE_RANGE                           0x80
+#define TPS65917_SMPS2_VOLTAGE_RANGE_SHIFT                     0x07
+#define TPS65917_SMPS2_VOLTAGE_VSEL_MASK                       0x7F
+#define TPS65917_SMPS2_VOLTAGE_VSEL_SHIFT                      0x00
+
+/* Bit definitions for SMPS3_CTRL */
+#define TPS65917_SMPS3_CTRL_WR_S                               0x80
+#define TPS65917_SMPS3_CTRL_WR_S_SHIFT                         0x07
+#define TPS65917_SMPS3_CTRL_ROOF_FLOOR_EN                      0x40
+#define TPS65917_SMPS3_CTRL_ROOF_FLOOR_EN_SHIFT                0x06
+#define TPS65917_SMPS3_CTRL_STATUS_MASK                        0x30
+#define TPS65917_SMPS3_CTRL_STATUS_SHIFT                       0x04
+#define TPS65917_SMPS3_CTRL_MODE_SLEEP_MASK                    0x0C
+#define TPS65917_SMPS3_CTRL_MODE_SLEEP_SHIFT                   0x02
+#define TPS65917_SMPS3_CTRL_MODE_ACTIVE_MASK                   0x03
+#define TPS65917_SMPS3_CTRL_MODE_ACTIVE_SHIFT                  0x00
+
+/* Bit definitions for SMPS3_FORCE */
+#define TPS65917_SMPS3_FORCE_CMD                               0x80
+#define TPS65917_SMPS3_FORCE_CMD_SHIFT                         0x07
+#define TPS65917_SMPS3_FORCE_VSEL_MASK                         0x7F
+#define TPS65917_SMPS3_FORCE_VSEL_SHIFT                        0x00
+
+/* Bit definitions for SMPS3_VOLTAGE */
+#define TPS65917_SMPS3_VOLTAGE_RANGE                           0x80
+#define TPS65917_SMPS3_VOLTAGE_RANGE_SHIFT                     0x07
+#define TPS65917_SMPS3_VOLTAGE_VSEL_MASK                       0x7F
+#define TPS65917_SMPS3_VOLTAGE_VSEL_SHIFT                      0x00
+
+/* Bit definitions for SMPS4_CTRL */
+#define TPS65917_SMPS4_CTRL_WR_S                               0x80
+#define TPS65917_SMPS4_CTRL_WR_S_SHIFT                         0x07
+#define TPS65917_SMPS4_CTRL_ROOF_FLOOR_EN                      0x40
+#define TPS65917_SMPS4_CTRL_ROOF_FLOOR_EN_SHIFT                0x06
+#define TPS65917_SMPS4_CTRL_STATUS_MASK                        0x30
+#define TPS65917_SMPS4_CTRL_STATUS_SHIFT                       0x04
+#define TPS65917_SMPS4_CTRL_MODE_SLEEP_MASK                    0x0C
+#define TPS65917_SMPS4_CTRL_MODE_SLEEP_SHIFT                   0x02
+#define TPS65917_SMPS4_CTRL_MODE_ACTIVE_MASK                   0x03
+#define TPS65917_SMPS4_CTRL_MODE_ACTIVE_SHIFT                  0x00
+
+/* Bit definitions for SMPS4_VOLTAGE */
+#define TPS65917_SMPS4_VOLTAGE_RANGE                           0x80
+#define TPS65917_SMPS4_VOLTAGE_RANGE_SHIFT                     0x07
+#define TPS65917_SMPS4_VOLTAGE_VSEL_MASK                       0x7F
+#define TPS65917_SMPS4_VOLTAGE_VSEL_SHIFT                      0x00
+
+/* Bit definitions for SMPS5_CTRL */
+#define TPS65917_SMPS5_CTRL_WR_S                               0x80
+#define TPS65917_SMPS5_CTRL_WR_S_SHIFT                         0x07
+#define TPS65917_SMPS5_CTRL_ROOF_FLOOR_EN                      0x40
+#define TPS65917_SMPS5_CTRL_ROOF_FLOOR_EN_SHIFT                0x06
+#define TPS65917_SMPS5_CTRL_STATUS_MASK                        0x30
+#define TPS65917_SMPS5_CTRL_STATUS_SHIFT                       0x04
+#define TPS65917_SMPS5_CTRL_MODE_SLEEP_MASK                    0x0C
+#define TPS65917_SMPS5_CTRL_MODE_SLEEP_SHIFT                   0x02
+#define TPS65917_SMPS5_CTRL_MODE_ACTIVE_MASK                   0x03
+#define TPS65917_SMPS5_CTRL_MODE_ACTIVE_SHIFT                  0x00
+
+/* Bit definitions for SMPS5_VOLTAGE */
+#define TPS65917_SMPS5_VOLTAGE_RANGE                           0x80
+#define TPS65917_SMPS5_VOLTAGE_RANGE_SHIFT                     0x07
+#define TPS65917_SMPS5_VOLTAGE_VSEL_MASK                       0x7F
+#define TPS65917_SMPS5_VOLTAGE_VSEL_SHIFT                      0x00
+
+/* Bit definitions for SMPS_CTRL */
+#define TPS65917_SMPS_CTRL_SMPS1_SMPS12_EN                     0x10
+#define TPS65917_SMPS_CTRL_SMPS1_SMPS12_EN_SHIFT               0x04
+#define TPS65917_SMPS_CTRL_SMPS12_PHASE_CTRL                   0x03
+#define TPS65917_SMPS_CTRL_SMPS12_PHASE_CTRL_SHIFT             0x00
+
+/* Bit definitions for SMPS_PD_CTRL */
+#define TPS65917_SMPS_PD_CTRL_SMPS5                            0x40
+#define TPS65917_SMPS_PD_CTRL_SMPS5_SHIFT                      0x06
+#define TPS65917_SMPS_PD_CTRL_SMPS4                            0x10
+#define TPS65917_SMPS_PD_CTRL_SMPS4_SHIFT                      0x04
+#define TPS65917_SMPS_PD_CTRL_SMPS3                            0x08
+#define TPS65917_SMPS_PD_CTRL_SMPS3_SHIFT                      0x03
+#define TPS65917_SMPS_PD_CTRL_SMPS2                            0x02
+#define TPS65917_SMPS_PD_CTRL_SMPS2_SHIFT                      0x01
+#define TPS65917_SMPS_PD_CTRL_SMPS1                            0x01
+#define TPS65917_SMPS_PD_CTRL_SMPS1_SHIFT                      0x00
+
+/* Bit definitions for SMPS_THERMAL_EN */
+#define TPS65917_SMPS_THERMAL_EN_SMPS5                         0x40
+#define TPS65917_SMPS_THERMAL_EN_SMPS5_SHIFT                   0x06
+#define TPS65917_SMPS_THERMAL_EN_SMPS3                         0x08
+#define TPS65917_SMPS_THERMAL_EN_SMPS3_SHIFT                   0x03
+#define TPS65917_SMPS_THERMAL_EN_SMPS12                        0x01
+#define TPS65917_SMPS_THERMAL_EN_SMPS12_SHIFT                  0x00
+
+/* Bit definitions for SMPS_THERMAL_STATUS */
+#define TPS65917_SMPS_THERMAL_STATUS_SMPS5                     0x40
+#define TPS65917_SMPS_THERMAL_STATUS_SMPS5_SHIFT               0x06
+#define TPS65917_SMPS_THERMAL_STATUS_SMPS3                     0x08
+#define TPS65917_SMPS_THERMAL_STATUS_SMPS3_SHIFT               0x03
+#define TPS65917_SMPS_THERMAL_STATUS_SMPS12                    0x01
+#define TPS65917_SMPS_THERMAL_STATUS_SMPS12_SHIFT              0x00
+
+/* Bit definitions for SMPS_SHORT_STATUS */
+#define TPS65917_SMPS_SHORT_STATUS_SMPS5                       0x40
+#define TPS65917_SMPS_SHORT_STATUS_SMPS5_SHIFT                 0x06
+#define TPS65917_SMPS_SHORT_STATUS_SMPS4                       0x10
+#define TPS65917_SMPS_SHORT_STATUS_SMPS4_SHIFT                 0x04
+#define TPS65917_SMPS_SHORT_STATUS_SMPS3                       0x08
+#define TPS65917_SMPS_SHORT_STATUS_SMPS3_SHIFT                 0x03
+#define TPS65917_SMPS_SHORT_STATUS_SMPS2                       0x02
+#define TPS65917_SMPS_SHORT_STATUS_SMPS2_SHIFT                 0x01
+#define TPS65917_SMPS_SHORT_STATUS_SMPS1                       0x01
+#define TPS65917_SMPS_SHORT_STATUS_SMPS1_SHIFT                 0x00
+
+/* Bit definitions for SMPS_NEGATIVE_CURRENT_LIMIT_EN */
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS5          0x40
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS5_SHIFT    0x06
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS4          0x10
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS4_SHIFT    0x04
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS3          0x08
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS3_SHIFT    0x03
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS2          0x02
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS2_SHIFT    0x01
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS1          0x01
+#define TPS65917_SMPS_NEGATIVE_CURRENT_LIMIT_EN_SMPS1_SHIFT    0x00
+
+/* Bit definitions for SMPS_POWERGOOD_MASK1 */
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS5                    0x40
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS5_SHIFT              0x06
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS4                    0x10
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS4_SHIFT              0x04
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS3                    0x08
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS3_SHIFT              0x03
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS2                    0x02
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS2_SHIFT              0x01
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS1                    0x01
+#define TPS65917_SMPS_POWERGOOD_MASK1_SMPS1_SHIFT              0x00
+
+/* Bit definitions for SMPS_POWERGOOD_MASK2 */
+#define TPS65917_SMPS_POWERGOOD_MASK2_POWERGOOD_TYPE_SELECT            0x80
+#define TPS65917_SMPS_POWERGOOD_MASK2_POWERGOOD_TYPE_SELECT_SHIFT      0x07
+#define TPS65917_SMPS_POWERGOOD_MASK2_OVC_ALARM_SHIFT                  0x10
+#define TPS65917_SMPS_POWERGOOD_MASK2_OVC_ALARM                        0x04
+
+/* Bit definitions for SMPS_PLL_CTRL */
+
+#define TPS65917_SMPS_PLL_CTRL_PLL_EN_PLL_BYPASS_SHIFT         0x08
+#define TPS65917_SMPS_PLL_CTRL_PLL_PLL_EN_BYPASS               0x03
+#define TPS65917_SMPS_PLL_CTRL_PLL_PLL_BYPASS_CLK_SHIFT        0x04
+#define TPS65917_SMPS_PLL_CTRL_PLL_PLL_BYPASS_CLK              0x02
+
+/* Registers for function LDO */
+#define TPS65917_LDO1_CTRL                                     0x00
+#define TPS65917_LDO1_VOLTAGE                                  0x01
+#define TPS65917_LDO2_CTRL                                     0x02
+#define TPS65917_LDO2_VOLTAGE                                  0x03
+#define TPS65917_LDO3_CTRL                                     0x04
+#define TPS65917_LDO3_VOLTAGE                                  0x05
+#define TPS65917_LDO4_CTRL                                     0x0E
+#define TPS65917_LDO4_VOLTAGE                                  0x0F
+#define TPS65917_LDO5_CTRL                                     0x12
+#define TPS65917_LDO5_VOLTAGE                                  0x13
+#define TPS65917_LDO_PD_CTRL1                                  0x1B
+#define TPS65917_LDO_PD_CTRL2                                  0x1C
+#define TPS65917_LDO_SHORT_STATUS1                             0x1D
+#define TPS65917_LDO_SHORT_STATUS2                             0x1E
+#define TPS65917_LDO_PD_CTRL3                                  0x2D
+#define TPS65917_LDO_SHORT_STATUS3                             0x2E
+
+/* Bit definitions for LDO1_CTRL */
+#define TPS65917_LDO1_CTRL_WR_S                                0x80
+#define TPS65917_LDO1_CTRL_WR_S_SHIFT                          0x07
+#define TPS65917_LDO1_CTRL_BYPASS_EN                           0x40
+#define TPS65917_LDO1_CTRL_BYPASS_EN_SHIFT                     0x06
+#define TPS65917_LDO1_CTRL_STATUS                              0x10
+#define TPS65917_LDO1_CTRL_STATUS_SHIFT                        0x04
+#define TPS65917_LDO1_CTRL_MODE_SLEEP                          0x04
+#define TPS65917_LDO1_CTRL_MODE_SLEEP_SHIFT                    0x02
+#define TPS65917_LDO1_CTRL_MODE_ACTIVE                         0x01
+#define TPS65917_LDO1_CTRL_MODE_ACTIVE_SHIFT                   0x00
+
+/* Bit definitions for LDO1_VOLTAGE */
+#define TPS65917_LDO1_VOLTAGE_VSEL_MASK                        0x2F
+#define TPS65917_LDO1_VOLTAGE_VSEL_SHIFT                       0x00
+
+/* Bit definitions for LDO2_CTRL */
+#define TPS65917_LDO2_CTRL_WR_S                                0x80
+#define TPS65917_LDO2_CTRL_WR_S_SHIFT                          0x07
+#define TPS65917_LDO2_CTRL_BYPASS_EN                           0x40
+#define TPS65917_LDO2_CTRL_BYPASS_EN_SHIFT                     0x06
+#define TPS65917_LDO2_CTRL_STATUS                              0x10
+#define TPS65917_LDO2_CTRL_STATUS_SHIFT                        0x04
+#define TPS65917_LDO2_CTRL_MODE_SLEEP                          0x04
+#define TPS65917_LDO2_CTRL_MODE_SLEEP_SHIFT                    0x02
+#define TPS65917_LDO2_CTRL_MODE_ACTIVE                         0x01
+#define TPS65917_LDO2_CTRL_MODE_ACTIVE_SHIFT                   0x00
+
+/* Bit definitions for LDO2_VOLTAGE */
+#define TPS65917_LDO2_VOLTAGE_VSEL_MASK                        0x2F
+#define TPS65917_LDO2_VOLTAGE_VSEL_SHIFT                       0x00
+
+/* Bit definitions for LDO3_CTRL */
+#define TPS65917_LDO3_CTRL_WR_S                                0x80
+#define TPS65917_LDO3_CTRL_WR_S_SHIFT                          0x07
+#define TPS65917_LDO3_CTRL_STATUS                              0x10
+#define TPS65917_LDO3_CTRL_STATUS_SHIFT                        0x04
+#define TPS65917_LDO3_CTRL_MODE_SLEEP                          0x04
+#define TPS65917_LDO3_CTRL_MODE_SLEEP_SHIFT                    0x02
+#define TPS65917_LDO3_CTRL_MODE_ACTIVE                         0x01
+#define TPS65917_LDO3_CTRL_MODE_ACTIVE_SHIFT                   0x00
+
+/* Bit definitions for LDO3_VOLTAGE */
+#define TPS65917_LDO3_VOLTAGE_VSEL_MASK                        0x2F
+#define TPS65917_LDO3_VOLTAGE_VSEL_SHIFT                       0x00
+
+/* Bit definitions for LDO4_CTRL */
+#define TPS65917_LDO4_CTRL_WR_S                                0x80
+#define TPS65917_LDO4_CTRL_WR_S_SHIFT                          0x07
+#define TPS65917_LDO4_CTRL_STATUS                              0x10
+#define TPS65917_LDO4_CTRL_STATUS_SHIFT                        0x04
+#define TPS65917_LDO4_CTRL_MODE_SLEEP                          0x04
+#define TPS65917_LDO4_CTRL_MODE_SLEEP_SHIFT                    0x02
+#define TPS65917_LDO4_CTRL_MODE_ACTIVE                         0x01
+#define TPS65917_LDO4_CTRL_MODE_ACTIVE_SHIFT                   0x00
+
+/* Bit definitions for LDO4_VOLTAGE */
+#define TPS65917_LDO4_VOLTAGE_VSEL_MASK                        0x2F
+#define TPS65917_LDO4_VOLTAGE_VSEL_SHIFT                       0x00
+
+/* Bit definitions for LDO5_CTRL */
+#define TPS65917_LDO5_CTRL_WR_S                                0x80
+#define TPS65917_LDO5_CTRL_WR_S_SHIFT                          0x07
+#define TPS65917_LDO5_CTRL_STATUS                              0x10
+#define TPS65917_LDO5_CTRL_STATUS_SHIFT                        0x04
+#define TPS65917_LDO5_CTRL_MODE_SLEEP                          0x04
+#define TPS65917_LDO5_CTRL_MODE_SLEEP_SHIFT                    0x02
+#define TPS65917_LDO5_CTRL_MODE_ACTIVE                         0x01
+#define TPS65917_LDO5_CTRL_MODE_ACTIVE_SHIFT                   0x00
+
+/* Bit definitions for LDO5_VOLTAGE */
+#define TPS65917_LDO5_VOLTAGE_VSEL_MASK                        0x2F
+#define TPS65917_LDO5_VOLTAGE_VSEL_SHIFT                       0x00
+
+/* Bit definitions for LDO_PD_CTRL1 */
+#define TPS65917_LDO_PD_CTRL1_LDO4                             0x80
+#define TPS65917_LDO_PD_CTRL1_LDO4_SHIFT                       0x07
+#define TPS65917_LDO_PD_CTRL1_LDO2                             0x02
+#define TPS65917_LDO_PD_CTRL1_LDO2_SHIFT                       0x01
+#define TPS65917_LDO_PD_CTRL1_LDO1                             0x01
+#define TPS65917_LDO_PD_CTRL1_LDO1_SHIFT                       0x00
+
+/* Bit definitions for LDO_PD_CTRL2 */
+#define TPS65917_LDO_PD_CTRL2_LDO3                             0x04
+#define TPS65917_LDO_PD_CTRL2_LDO3_SHIFT                       0x02
+#define TPS65917_LDO_PD_CTRL2_LDO5                             0x02
+#define TPS65917_LDO_PD_CTRL2_LDO5_SHIFT                       0x01
+
+/* Bit definitions for LDO_PD_CTRL3 */
+#define TPS65917_LDO_PD_CTRL2_LDOVANA                          0x80
+#define TPS65917_LDO_PD_CTRL2_LDOVANA_SHIFT                    0x07
+
+/* Bit definitions for LDO_SHORT_STATUS1 */
+#define TPS65917_LDO_SHORT_STATUS1_LDO4                        0x80
+#define TPS65917_LDO_SHORT_STATUS1_LDO4_SHIFT                  0x07
+#define TPS65917_LDO_SHORT_STATUS1_LDO2                        0x02
+#define TPS65917_LDO_SHORT_STATUS1_LDO2_SHIFT                  0x01
+#define TPS65917_LDO_SHORT_STATUS1_LDO1                        0x01
+#define TPS65917_LDO_SHORT_STATUS1_LDO1_SHIFT                  0x00
+
+/* Bit definitions for LDO_SHORT_STATUS2 */
+#define TPS65917_LDO_SHORT_STATUS2_LDO3                        0x04
+#define TPS65917_LDO_SHORT_STATUS2_LDO3_SHIFT                  0x02
+#define TPS65917_LDO_SHORT_STATUS2_LDO5                        0x02
+#define TPS65917_LDO_SHORT_STATUS2_LDO5_SHIFT                  0x01
+
+/* Bit definitions for LDO_SHORT_STATUS2 */
+#define TPS65917_LDO_SHORT_STATUS2_LDOVANA                     0x80
+#define TPS65917_LDO_SHORT_STATUS2_LDOVANA_SHIFT               0x07
+
+/* Bit definitions for REGEN1_CTRL */
+#define TPS65917_REGEN1_CTRL_STATUS                            0x10
+#define TPS65917_REGEN1_CTRL_STATUS_SHIFT                      0x04
+#define TPS65917_REGEN1_CTRL_MODE_SLEEP                        0x04
+#define TPS65917_REGEN1_CTRL_MODE_SLEEP_SHIFT                  0x02
+#define TPS65917_REGEN1_CTRL_MODE_ACTIVE                       0x01
+#define TPS65917_REGEN1_CTRL_MODE_ACTIVE_SHIFT                 0x00
+
+/* Bit definitions for PLLEN_CTRL */
+#define TPS65917_PLLEN_CTRL_STATUS                             0x10
+#define TPS65917_PLLEN_CTRL_STATUS_SHIFT                       0x04
+#define TPS65917_PLLEN_CTRL_MODE_SLEEP                         0x04
+#define TPS65917_PLLEN_CTRL_MODE_SLEEP_SHIFT                   0x02
+#define TPS65917_PLLEN_CTRL_MODE_ACTIVE                        0x01
+#define TPS65917_PLLEN_CTRL_MODE_ACTIVE_SHIFT                  0x00
+
+/* Bit definitions for REGEN2_CTRL */
+#define TPS65917_REGEN2_CTRL_STATUS                            0x10
+#define TPS65917_REGEN2_CTRL_STATUS_SHIFT                      0x04
+#define TPS65917_REGEN2_CTRL_MODE_SLEEP                        0x04
+#define TPS65917_REGEN2_CTRL_MODE_SLEEP_SHIFT                  0x02
+#define TPS65917_REGEN2_CTRL_MODE_ACTIVE                       0x01
+#define TPS65917_REGEN2_CTRL_MODE_ACTIVE_SHIFT                 0x00
+
+/* Bit definitions for NSLEEP_RES_ASSIGN */
+#define TPS65917_NSLEEP_RES_ASSIGN_PLL_EN                      0x08
+#define TPS65917_NSLEEP_RES_ASSIGN_PLL_EN_SHIFT                0x03
+#define TPS65917_NSLEEP_RES_ASSIGN_REGEN3                      0x04
+#define TPS65917_NSLEEP_RES_ASSIGN_REGEN3_SHIFT                0x02
+#define TPS65917_NSLEEP_RES_ASSIGN_REGEN2                      0x02
+#define TPS65917_NSLEEP_RES_ASSIGN_REGEN2_SHIFT                0x01
+#define TPS65917_NSLEEP_RES_ASSIGN_REGEN1                      0x01
+#define TPS65917_NSLEEP_RES_ASSIGN_REGEN1_SHIFT                0x00
+
+/* Bit definitions for NSLEEP_SMPS_ASSIGN */
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS5                      0x40
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS5_SHIFT                0x06
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS4                      0x10
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS4_SHIFT                0x04
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS3                      0x08
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS3_SHIFT                0x03
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS2                      0x02
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS2_SHIFT                0x01
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS1                      0x01
+#define TPS65917_NSLEEP_SMPS_ASSIGN_SMPS1_SHIFT                0x00
+
+/* Bit definitions for NSLEEP_LDO_ASSIGN1 */
+#define TPS65917_NSLEEP_LDO_ASSIGN1_LDO4                       0x80
+#define TPS65917_NSLEEP_LDO_ASSIGN1_LDO4_SHIFT                 0x07
+#define TPS65917_NSLEEP_LDO_ASSIGN1_LDO2                       0x02
+#define TPS65917_NSLEEP_LDO_ASSIGN1_LDO2_SHIFT                 0x01
+#define TPS65917_NSLEEP_LDO_ASSIGN1_LDO1                       0x01
+#define TPS65917_NSLEEP_LDO_ASSIGN1_LDO1_SHIFT                 0x00
+
+/* Bit definitions for NSLEEP_LDO_ASSIGN2 */
+#define TPS65917_NSLEEP_LDO_ASSIGN2_LDO3                       0x04
+#define TPS65917_NSLEEP_LDO_ASSIGN2_LDO3_SHIFT                 0x02
+#define TPS65917_NSLEEP_LDO_ASSIGN2_LDO5                       0x02
+#define TPS65917_NSLEEP_LDO_ASSIGN2_LDO5_SHIFT                 0x01
+
+/* Bit definitions for ENABLE1_RES_ASSIGN */
+#define TPS65917_ENABLE1_RES_ASSIGN_PLLEN                      0x08
+#define TPS65917_ENABLE1_RES_ASSIGN_PLLEN_SHIFT                0x03
+#define TPS65917_ENABLE1_RES_ASSIGN_REGEN3                     0x04
+#define TPS65917_ENABLE1_RES_ASSIGN_REGEN3_SHIFT               0x02
+#define TPS65917_ENABLE1_RES_ASSIGN_REGEN2                     0x02
+#define TPS65917_ENABLE1_RES_ASSIGN_REGEN2_SHIFT               0x01
+#define TPS65917_ENABLE1_RES_ASSIGN_REGEN1                     0x01
+#define TPS65917_ENABLE1_RES_ASSIGN_REGEN1_SHIFT               0x00
+
+/* Bit definitions for ENABLE1_SMPS_ASSIGN */
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS5                     0x40
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS5_SHIFT               0x06
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS4                     0x10
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS4_SHIFT               0x04
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS3                     0x08
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS3_SHIFT               0x03
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS2                     0x02
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS2_SHIFT               0x01
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS1                     0x01
+#define TPS65917_ENABLE1_SMPS_ASSIGN_SMPS1_SHIFT               0x00
+
+/* Bit definitions for ENABLE1_LDO_ASSIGN1 */
+#define TPS65917_ENABLE1_LDO_ASSIGN1_LDO4                      0x80
+#define TPS65917_ENABLE1_LDO_ASSIGN1_LDO4_SHIFT                0x07
+#define TPS65917_ENABLE1_LDO_ASSIGN1_LDO2                      0x02
+#define TPS65917_ENABLE1_LDO_ASSIGN1_LDO2_SHIFT                0x01
+#define TPS65917_ENABLE1_LDO_ASSIGN1_LDO1                      0x01
+#define TPS65917_ENABLE1_LDO_ASSIGN1_LDO1_SHIFT                0x00
+
+/* Bit definitions for ENABLE1_LDO_ASSIGN2 */
+#define TPS65917_ENABLE1_LDO_ASSIGN2_LDO3                      0x04
+#define TPS65917_ENABLE1_LDO_ASSIGN2_LDO3_SHIFT                0x02
+#define TPS65917_ENABLE1_LDO_ASSIGN2_LDO5                      0x02
+#define TPS65917_ENABLE1_LDO_ASSIGN2_LDO5_SHIFT                0x01
+
+/* Bit definitions for ENABLE2_RES_ASSIGN */
+#define TPS65917_ENABLE2_RES_ASSIGN_PLLEN                      0x08
+#define TPS65917_ENABLE2_RES_ASSIGN_PLLEN_SHIFT                0x03
+#define TPS65917_ENABLE2_RES_ASSIGN_REGEN3                     0x04
+#define TPS65917_ENABLE2_RES_ASSIGN_REGEN3_SHIFT               0x02
+#define TPS65917_ENABLE2_RES_ASSIGN_REGEN2                     0x02
+#define TPS65917_ENABLE2_RES_ASSIGN_REGEN2_SHIFT               0x01
+#define TPS65917_ENABLE2_RES_ASSIGN_REGEN1                     0x01
+#define TPS65917_ENABLE2_RES_ASSIGN_REGEN1_SHIFT               0x00
+
+/* Bit definitions for ENABLE2_SMPS_ASSIGN */
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS5                     0x40
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS5_SHIFT               0x06
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS4                     0x10
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS4_SHIFT               0x04
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS3                     0x08
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS3_SHIFT               0x03
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS2                     0x02
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS2_SHIFT               0x01
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS1                     0x01
+#define TPS65917_ENABLE2_SMPS_ASSIGN_SMPS1_SHIFT               0x00
+
+/* Bit definitions for ENABLE2_LDO_ASSIGN1 */
+#define TPS65917_ENABLE2_LDO_ASSIGN1_LDO4                      0x80
+#define TPS65917_ENABLE2_LDO_ASSIGN1_LDO4_SHIFT                0x07
+#define TPS65917_ENABLE2_LDO_ASSIGN1_LDO2                      0x02
+#define TPS65917_ENABLE2_LDO_ASSIGN1_LDO2_SHIFT                0x01
+#define TPS65917_ENABLE2_LDO_ASSIGN1_LDO1                      0x01
+#define TPS65917_ENABLE2_LDO_ASSIGN1_LDO1_SHIFT                0x00
+
+/* Bit definitions for ENABLE2_LDO_ASSIGN2 */
+#define TPS65917_ENABLE2_LDO_ASSIGN2_LDO3                      0x04
+#define TPS65917_ENABLE2_LDO_ASSIGN2_LDO3_SHIFT                0x02
+#define TPS65917_ENABLE2_LDO_ASSIGN2_LDO5                      0x02
+#define TPS65917_ENABLE2_LDO_ASSIGN2_LDO5_SHIFT                0x01
+
+/* Bit definitions for REGEN3_CTRL */
+#define TPS65917_REGEN3_CTRL_STATUS                            0x10
+#define TPS65917_REGEN3_CTRL_STATUS_SHIFT                      0x04
+#define TPS65917_REGEN3_CTRL_MODE_SLEEP                        0x04
+#define TPS65917_REGEN3_CTRL_MODE_SLEEP_SHIFT                  0x02
+#define TPS65917_REGEN3_CTRL_MODE_ACTIVE                       0x01
+#define TPS65917_REGEN3_CTRL_MODE_ACTIVE_SHIFT                 0x00
+
+/* Registers for function RESOURCE */
+#define TPS65917_REGEN1_CTRL                                   0x2
+#define TPS65917_PLLEN_CTRL                                    0x3
+#define TPS65917_NSLEEP_RES_ASSIGN                             0x6
+#define TPS65917_NSLEEP_SMPS_ASSIGN                            0x7
+#define TPS65917_NSLEEP_LDO_ASSIGN1                            0x8
+#define TPS65917_NSLEEP_LDO_ASSIGN2                            0x9
+#define TPS65917_ENABLE1_RES_ASSIGN                            0xA
+#define TPS65917_ENABLE1_SMPS_ASSIGN                           0xB
+#define TPS65917_ENABLE1_LDO_ASSIGN1                           0xC
+#define TPS65917_ENABLE1_LDO_ASSIGN2                           0xD
+#define TPS65917_ENABLE2_RES_ASSIGN                            0xE
+#define TPS65917_ENABLE2_SMPS_ASSIGN                           0xF
+#define TPS65917_ENABLE2_LDO_ASSIGN1                           0x10
+#define TPS65917_ENABLE2_LDO_ASSIGN2                           0x11
+#define TPS65917_REGEN2_CTRL                                   0x12
+#define TPS65917_REGEN3_CTRL                                   0x13
+
 static inline int palmas_read(struct palmas *palmas, unsigned int base,
                unsigned int reg, unsigned int *val)
 {
index 7530744..d8ecefa 100644 (file)
@@ -322,18 +322,4 @@ struct ab8500_regulator_platform_data {
        struct regulator_init_data *ext_regulator;
 };
 
-#ifdef CONFIG_REGULATOR_AB8500_DEBUG
-int ab8500_regulator_debug_init(struct platform_device *pdev);
-int ab8500_regulator_debug_exit(struct platform_device *pdev);
-#else
-static inline int ab8500_regulator_debug_init(struct platform_device *pdev)
-{
-       return 0;
-}
-static inline int ab8500_regulator_debug_exit(struct platform_device *pdev)
-{
-       return 0;
-}
-#endif
-
 #endif
index 49206c1..b6c4909 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * act8865.h  --  Voltage regulation for the active-semi act8865
+ * act8865.h  --  Voltage regulation for active-semi act88xx PMUs
  *
  * Copyright (C) 2013 Atmel Corporation.
  *
@@ -29,6 +29,27 @@ enum {
        ACT8865_REG_NUM,
 };
 
+enum {
+       ACT8846_ID_REG1,
+       ACT8846_ID_REG2,
+       ACT8846_ID_REG3,
+       ACT8846_ID_REG4,
+       ACT8846_ID_REG5,
+       ACT8846_ID_REG6,
+       ACT8846_ID_REG7,
+       ACT8846_ID_REG8,
+       ACT8846_ID_REG9,
+       ACT8846_ID_REG10,
+       ACT8846_ID_REG11,
+       ACT8846_ID_REG12,
+       ACT8846_REG_NUM,
+};
+
+enum {
+       ACT8865,
+       ACT8846,
+};
+
 /**
  * act8865_regulator_data - regulator data
  * @id: regulator id
index 14ec18d..f8a8733 100644 (file)
@@ -37,6 +37,7 @@
 
 struct device;
 struct notifier_block;
+struct regmap;
 
 /*
  * Regulator operating modes.
@@ -215,6 +216,13 @@ int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
 
 int regulator_allow_bypass(struct regulator *regulator, bool allow);
 
+struct regmap *regulator_get_regmap(struct regulator *regulator);
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+                                        unsigned *vsel_reg,
+                                        unsigned *vsel_mask);
+int regulator_list_hardware_vsel(struct regulator *regulator,
+                                unsigned selector);
+
 /* regulator notifier block */
 int regulator_register_notifier(struct regulator *regulator,
                              struct notifier_block *nb);
@@ -457,6 +465,24 @@ static inline int regulator_allow_bypass(struct regulator *regulator,
        return 0;
 }
 
+static inline struct regmap *regulator_get_regmap(struct regulator *regulator)
+{
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int regulator_get_hardware_vsel_register(struct regulator *regulator,
+                                                      unsigned *vsel_reg,
+                                                      unsigned *vsel_mask)
+{
+       return -EOPNOTSUPP;
+}
+
+static inline int regulator_list_hardware_vsel(struct regulator *regulator,
+                                              unsigned selector)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int regulator_register_notifier(struct regulator *regulator,
                              struct notifier_block *nb)
 {
diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h
new file mode 100644 (file)
index 0000000..0981ce0
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * da9211.h - Regulator device driver for DA9211
+ * Copyright (C) 2014  Dialog Semiconductor Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ */
+
+#ifndef __LINUX_REGULATOR_DA9211_H
+#define __LINUX_REGULATOR_DA9211_H
+
+#include <linux/regulator/machine.h>
+
+#define DA9211_MAX_REGULATORS  2
+
+struct da9211_pdata {
+       /*
+        * Number of buck
+        * 1 : 4 phase 1 buck
+        * 2 : 2 phase 2 buck
+        */
+       int num_buck;
+       struct regulator_init_data *init_data;
+};
+#endif