Merge remote-tracking branches 'regulator/topic/core', 'regulator/topic/regmap' and...
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Sat, 12 May 2012 10:09:47 +0000 (11:09 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sat, 12 May 2012 10:09:47 +0000 (11:09 +0100)
60 files changed:
Documentation/power/regulator/regulator.txt
drivers/mfd/tps65090.c
drivers/regulator/88pm8607.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/aat2870-regulator.c
drivers/regulator/ab3100.c
drivers/regulator/ab8500.c
drivers/regulator/ad5398.c
drivers/regulator/anatop-regulator.c
drivers/regulator/core.c
drivers/regulator/da903x.c
drivers/regulator/da9052-regulator.c
drivers/regulator/db8500-prcmu.c
drivers/regulator/dummy.c
drivers/regulator/fixed.c
drivers/regulator/gpio-regulator.c
drivers/regulator/isl6271a-regulator.c
drivers/regulator/lp3971.c
drivers/regulator/lp3972.c
drivers/regulator/max1586.c
drivers/regulator/max8649.c
drivers/regulator/max8660.c
drivers/regulator/max8925-regulator.c
drivers/regulator/max8952.c
drivers/regulator/max8997.c
drivers/regulator/max8998.c
drivers/regulator/mc13783-regulator.c
drivers/regulator/mc13892-regulator.c
drivers/regulator/mc13xxx-regulator-core.c
drivers/regulator/mc13xxx.h
drivers/regulator/pcap-regulator.c
drivers/regulator/pcf50633-regulator.c
drivers/regulator/rc5t583-regulator.c [new file with mode: 0644]
drivers/regulator/s5m8767.c
drivers/regulator/tps6105x-regulator.c
drivers/regulator/tps62360-regulator.c
drivers/regulator/tps65023-regulator.c
drivers/regulator/tps6507x-regulator.c
drivers/regulator/tps65090-regulator.c [new file with mode: 0644]
drivers/regulator/tps65217-regulator.c
drivers/regulator/tps6524x-regulator.c
drivers/regulator/tps6586x-regulator.c
drivers/regulator/tps65910-regulator.c
drivers/regulator/tps65912-regulator.c
drivers/regulator/twl-regulator.c
drivers/regulator/wm831x-dcdc.c
drivers/regulator/wm831x-isink.c
drivers/regulator/wm831x-ldo.c
drivers/regulator/wm8350-regulator.c
drivers/regulator/wm8400-regulator.c
drivers/regulator/wm8994-regulator.c
include/linux/mfd/rc5t583.h
include/linux/mfd/s5m87xx/s5m-core.h
include/linux/mfd/s5m87xx/s5m-pmic.h
include/linux/mfd/tps65090.h
include/linux/regulator/driver.h
include/linux/regulator/fixed.h
include/linux/regulator/tps65090-regulator.h [new file with mode: 0644]
sound/soc/codecs/sgtl5000.c

index e272d9909e393dd4091575555a82173e90694fdc..13902778ae44ceb31f4f0c1c5dc173f63ffd9b8a 100644 (file)
@@ -11,8 +11,7 @@ Registration
 Drivers can register a regulator by calling :-
 
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
-       struct device *dev, struct regulator_init_data *init_data,
-       void *driver_data, struct device_node *of_node);
+                                        const struct regulator_config *config);
 
 This will register the regulators capabilities and operations to the regulator
 core.
index a66d4df51293e757590a33369d5138c187e9f59c..47f802bf184818c81d9d0c9baeba9225ec63a603 100644 (file)
@@ -78,17 +78,6 @@ static struct mfd_cell tps65090s[] = {
        },
 };
 
-struct tps65090 {
-       struct mutex            lock;
-       struct device           *dev;
-       struct i2c_client       *client;
-       struct regmap           *rmap;
-       struct irq_chip         irq_chip;
-       struct mutex            irq_lock;
-       int                     irq_base;
-       unsigned int            id;
-};
-
 int tps65090_write(struct device *dev, int reg, uint8_t val)
 {
        struct tps65090 *tps = dev_get_drvdata(dev);
index 28b81ae4cf7f32c18e2d752dad185c4926ba62b9..c3482b954cb7540c0392f66ddb330ef92c300e2a 100644 (file)
@@ -27,13 +27,8 @@ struct pm8607_regulator_info {
        unsigned int    *vol_table;
        unsigned int    *vol_suspend;
 
-       int     vol_reg;
-       int     vol_shift;
-       int     vol_nbits;
        int     update_reg;
        int     update_bit;
-       int     enable_reg;
-       int     enable_bit;
        int     slope_double;
 };
 
@@ -216,7 +211,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
        struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
        int ret = -EINVAL;
 
-       if (info->vol_table && (index < (1 << info->vol_nbits))) {
+       if (info->vol_table && (index < rdev->desc->n_voltages)) {
                ret = info->vol_table[index];
                if (info->slope_double)
                        ret <<= 1;
@@ -224,51 +219,16 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
        return ret;
 }
 
-static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 {
        struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-       int i, ret = -ENOENT;
-
-       if (info->slope_double) {
-               min_uV = min_uV >> 1;
-               max_uV = max_uV >> 1;
-       }
-       if (info->vol_table) {
-               for (i = 0; i < (1 << info->vol_nbits); i++) {
-                       if (!info->vol_table[i])
-                               break;
-                       if ((min_uV <= info->vol_table[i])
-                               && (max_uV >= info->vol_table[i])) {
-                               ret = i;
-                               break;
-                       }
-               }
-       }
-       if (ret < 0)
-               pr_err("invalid voltage range (%d %d) uV\n", min_uV, max_uV);
-       return ret;
-}
-
-static int pm8607_set_voltage(struct regulator_dev *rdev,
-                             int min_uV, int max_uV, unsigned *selector)
-{
-       struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-       uint8_t val, mask;
+       uint8_t val;
        int ret;
 
-       if (min_uV > max_uV) {
-               pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
-               return -EINVAL;
-       }
+       val = (uint8_t)(selector << (ffs(rdev->desc->vsel_mask) - 1));
 
-       ret = choose_voltage(rdev, min_uV, max_uV);
-       if (ret < 0)
-               return -EINVAL;
-       *selector = ret;
-       val = (uint8_t)(ret << info->vol_shift);
-       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
-
-       ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
+       ret = pm860x_set_bits(info->i2c, rdev->desc->vsel_reg,
+                             rdev->desc->vsel_mask, val);
        if (ret)
                return ret;
        switch (info->desc.id) {
@@ -282,60 +242,16 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
        return ret;
 }
 
-static int pm8607_get_voltage(struct regulator_dev *rdev)
-{
-       struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-       uint8_t val, mask;
-       int ret;
-
-       ret = pm860x_reg_read(info->i2c, info->vol_reg);
-       if (ret < 0)
-               return ret;
-
-       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
-       val = ((unsigned char)ret & mask) >> info->vol_shift;
-
-       return pm8607_list_voltage(rdev, val);
-}
-
-static int pm8607_enable(struct regulator_dev *rdev)
-{
-       struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-
-       return pm860x_set_bits(info->i2c, info->enable_reg,
-                              1 << info->enable_bit,
-                              1 << info->enable_bit);
-}
-
-static int pm8607_disable(struct regulator_dev *rdev)
-{
-       struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-
-       return pm860x_set_bits(info->i2c, info->enable_reg,
-                              1 << info->enable_bit, 0);
-}
-
-static int pm8607_is_enabled(struct regulator_dev *rdev)
-{
-       struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
-       int ret;
-
-       ret = pm860x_reg_read(info->i2c, info->enable_reg);
-       if (ret < 0)
-               return ret;
-
-       return !!((unsigned char)ret & (1 << info->enable_bit));
-}
-
 static struct regulator_ops pm8607_regulator_ops = {
-       .set_voltage    = pm8607_set_voltage,
-       .get_voltage    = pm8607_get_voltage,
-       .enable         = pm8607_enable,
-       .disable        = pm8607_disable,
-       .is_enabled     = pm8607_is_enabled,
+       .list_voltage   = pm8607_list_voltage,
+       .set_voltage_sel = pm8607_set_voltage_sel,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
 };
 
-#define PM8607_DVC(vreg, nbits, ureg, ubit, ereg, ebit)                        \
+#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit)                       \
 {                                                                      \
        .desc   = {                                                     \
                .name   = #vreg,                                        \
@@ -343,20 +259,20 @@ static struct regulator_ops pm8607_regulator_ops = {
                .type   = REGULATOR_VOLTAGE,                            \
                .id     = PM8607_ID_##vreg,                             \
                .owner  = THIS_MODULE,                                  \
+               .n_voltages = ARRAY_SIZE(vreg##_table),                 \
+               .vsel_reg = PM8607_##vreg,                              \
+               .vsel_mask = ARRAY_SIZE(vreg##_table) - 1,              \
+               .enable_reg = PM8607_##ereg,                            \
+               .enable_mask = 1 << (ebit),                             \
        },                                                              \
-       .vol_reg        = PM8607_##vreg,                                \
-       .vol_shift      = (0),                                          \
-       .vol_nbits      = (nbits),                                      \
        .update_reg     = PM8607_##ureg,                                \
        .update_bit     = (ubit),                                       \
-       .enable_reg     = PM8607_##ereg,                                \
-       .enable_bit     = (ebit),                                       \
        .slope_double   = (0),                                          \
        .vol_table      = (unsigned int *)&vreg##_table,                \
        .vol_suspend    = (unsigned int *)&vreg##_suspend_table,        \
 }
 
-#define PM8607_LDO(_id, vreg, shift, nbits, ereg, ebit)                        \
+#define PM8607_LDO(_id, vreg, shift, ereg, ebit)                       \
 {                                                                      \
        .desc   = {                                                     \
                .name   = "LDO" #_id,                                   \
@@ -364,35 +280,35 @@ static struct regulator_ops pm8607_regulator_ops = {
                .type   = REGULATOR_VOLTAGE,                            \
                .id     = PM8607_ID_LDO##_id,                           \
                .owner  = THIS_MODULE,                                  \
+               .n_voltages = ARRAY_SIZE(LDO##_id##_table),             \
+               .vsel_reg = PM8607_##vreg,                              \
+               .vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \
+               .enable_reg = PM8607_##ereg,                            \
+               .enable_mask = 1 << (ebit),                             \
        },                                                              \
-       .vol_reg        = PM8607_##vreg,                                \
-       .vol_shift      = (shift),                                      \
-       .vol_nbits      = (nbits),                                      \
-       .enable_reg     = PM8607_##ereg,                                \
-       .enable_bit     = (ebit),                                       \
        .slope_double   = (0),                                          \
        .vol_table      = (unsigned int *)&LDO##_id##_table,            \
        .vol_suspend    = (unsigned int *)&LDO##_id##_suspend_table,    \
 }
 
 static struct pm8607_regulator_info pm8607_regulator_info[] = {
-       PM8607_DVC(BUCK1, 6, GO, 0, SUPPLIES_EN11, 0),
-       PM8607_DVC(BUCK2, 6, GO, 1, SUPPLIES_EN11, 1),
-       PM8607_DVC(BUCK3, 6, GO, 2, SUPPLIES_EN11, 2),
-
-       PM8607_LDO( 1,         LDO1, 0, 2, SUPPLIES_EN11, 3),
-       PM8607_LDO( 2,         LDO2, 0, 3, SUPPLIES_EN11, 4),
-       PM8607_LDO( 3,         LDO3, 0, 3, SUPPLIES_EN11, 5),
-       PM8607_LDO( 4,         LDO4, 0, 3, SUPPLIES_EN11, 6),
-       PM8607_LDO( 5,         LDO5, 0, 2, SUPPLIES_EN11, 7),
-       PM8607_LDO( 6,         LDO6, 0, 3, SUPPLIES_EN12, 0),
-       PM8607_LDO( 7,         LDO7, 0, 3, SUPPLIES_EN12, 1),
-       PM8607_LDO( 8,         LDO8, 0, 3, SUPPLIES_EN12, 2),
-       PM8607_LDO( 9,         LDO9, 0, 3, SUPPLIES_EN12, 3),
-       PM8607_LDO(10,        LDO10, 0, 4, SUPPLIES_EN12, 4),
-       PM8607_LDO(12,        LDO12, 0, 4, SUPPLIES_EN12, 5),
-       PM8607_LDO(13, VIBRATOR_SET, 1, 3,  VIBRATOR_SET, 0),
-       PM8607_LDO(14,        LDO14, 0, 3, SUPPLIES_EN12, 6),
+       PM8607_DVC(BUCK1, GO, 0, SUPPLIES_EN11, 0),
+       PM8607_DVC(BUCK2, GO, 1, SUPPLIES_EN11, 1),
+       PM8607_DVC(BUCK3, GO, 2, SUPPLIES_EN11, 2),
+
+       PM8607_LDO(1,         LDO1, 0, SUPPLIES_EN11, 3),
+       PM8607_LDO(2,         LDO2, 0, SUPPLIES_EN11, 4),
+       PM8607_LDO(3,         LDO3, 0, SUPPLIES_EN11, 5),
+       PM8607_LDO(4,         LDO4, 0, SUPPLIES_EN11, 6),
+       PM8607_LDO(5,         LDO5, 0, SUPPLIES_EN11, 7),
+       PM8607_LDO(6,         LDO6, 0, SUPPLIES_EN12, 0),
+       PM8607_LDO(7,         LDO7, 0, SUPPLIES_EN12, 1),
+       PM8607_LDO(8,         LDO8, 0, SUPPLIES_EN12, 2),
+       PM8607_LDO(9,         LDO9, 0, SUPPLIES_EN12, 3),
+       PM8607_LDO(10,        LDO10, 0, SUPPLIES_EN12, 4),
+       PM8607_LDO(12,        LDO12, 0, SUPPLIES_EN12, 5),
+       PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0),
+       PM8607_LDO(14,        LDO14, 0, SUPPLIES_EN12, 6),
 };
 
 static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
@@ -400,6 +316,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
        struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
        struct pm8607_regulator_info *info = NULL;
        struct regulator_init_data *pdata = pdev->dev.platform_data;
+       struct regulator_config config = { };
        struct resource *res;
        int i;
 
@@ -425,9 +342,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
        if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double)
                info->slope_double = 1;
 
+       config.dev = &pdev->dev;
+       config.init_data = pdata;
+       config.driver_data = info;
+
+       if (chip->id == CHIP_PM8607)
+               config.regmap = chip->regmap;
+       else
+               config.regmap = chip->regmap_companion;
+
        /* replace driver_data with info */
-       info->regulator = regulator_register(&info->desc, &pdev->dev,
-                                            pdata, info, NULL);
+       info->regulator = regulator_register(&info->desc, &config);
        if (IS_ERR(info->regulator)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                        info->desc.name);
index 36db5a441ebacda2498fc4cfcc5b0e24d9437a9f..4ad4e8d3c1eee1005afe3f8ff8ebf64cc567d95d 100644 (file)
@@ -223,6 +223,16 @@ config REGULATOR_PCF50633
         Say Y here to support the voltage regulators and convertors
         on PCF50633
 
+config REGULATOR_RC5T583
+       tristate "RICOH RC5T583 Power regulators"
+       depends on MFD_RC5T583
+       help
+         Select this option to enable the power regulator of RICOH
+         PMIC RC5T583.
+         This driver supports the control of different power rails of device
+         through regulator interface. The device supports multiple DCDC/LDO
+         outputs which can be controlled by i2c communication.
+
 config REGULATOR_S5M8767
        tristate "Samsung S5M8767A voltage regulator"
        depends on MFD_S5M_CORE
@@ -268,11 +278,11 @@ config REGULATOR_TPS6105X
          audio amplifiers.
 
 config REGULATOR_TPS62360
-       tristate "TI TPS62360 Power Regulator"
+       tristate "TI TPS6236x Power Regulator"
        depends on I2C
        select REGMAP_I2C
        help
-         This driver supports TPS62360 voltage regulator chip. This
+         This driver supports TPS6236x voltage regulator chip. This
          regulator is meant for processor core supply. This chip is
          high-frequency synchronous step down dc-dc converter optimized
          for battery-powered portable applications.
@@ -294,6 +304,13 @@ config REGULATOR_TPS6507X
          three step-down converters and two general-purpose LDO voltage regulators.
          It supports TI's software based Class-2 SmartReflex implementation.
 
+config REGULATOR_TPS65090
+       tristate "TI TPS65090 Power regulator"
+       depends on MFD_TPS65090
+       help
+         This driver provides support for the voltage regulators on the
+         TI TPS65090 PMIC.
+
 config REGULATOR_TPS65217
        tristate "TI TPS65217 Power regulators"
        depends on MFD_TPS65217
index 94b52745e9579ec3fbb9790efef74a5d41315770..dcc56dcca3a0e701ba7b1622e70c7636ce0f1bb9 100644 (file)
@@ -9,7 +9,6 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 
-obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
 obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
 obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
@@ -20,6 +19,7 @@ obj-$(CONFIG_REGULATOR_DA903X)        += da903x.o
 obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
 obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
 obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
+obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
@@ -35,11 +35,13 @@ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
+obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
index 9ed5c5d84e12b57aa4cb7080110eff22ef0b134c..7f000d6bb984ab856cf261bfe6627f86339d5032 100644 (file)
@@ -178,6 +178,7 @@ static struct aat2870_regulator *aat2870_get_regulator(int id)
 static int aat2870_regulator_probe(struct platform_device *pdev)
 {
        struct aat2870_regulator *ri;
+       struct regulator_config config = { 0 };
        struct regulator_dev *rdev;
 
        ri = aat2870_get_regulator(pdev->id);
@@ -187,8 +188,11 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
        }
        ri->aat2870 = dev_get_drvdata(pdev->dev.parent);
 
-       rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdev->dev.platform_data, ri, NULL);
+       config.dev = &pdev->dev;
+       config.driver_data = ri;
+       config.init_data = pdev->dev.platform_data;
+
+       rdev = regulator_register(&ri->desc, &config);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "Failed to register regulator %s\n",
                        ri->desc.name);
@@ -231,3 +235,4 @@ module_exit(aat2870_regulator_exit);
 MODULE_DESCRIPTION("AnalogicTech AAT2870 Regulator");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");
+MODULE_ALIAS("platform:aat2870-regulator");
index 042271aace6a65b8a2f40cdc3be75934ae081ff4..ce6192592ca20a77312f3f6ddff7eb4d0bb736a4 100644 (file)
@@ -338,20 +338,12 @@ static int ab3100_get_best_voltage_index(struct regulator_dev *reg,
        return bestindex;
 }
 
-static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
-                                       int min_uV, int max_uV,
-                                       unsigned *selector)
+static int ab3100_set_voltage_regulator_sel(struct regulator_dev *reg,
+                                           unsigned selector)
 {
        struct ab3100_regulator *abreg = reg->reg_data;
        u8 regval;
        int err;
-       int bestindex;
-
-       bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV);
-       if (bestindex < 0)
-               return bestindex;
-
-       *selector = bestindex;
 
        err = abx500_get_register_interruptible(abreg->dev, 0,
                                                abreg->regreg, &regval);
@@ -364,7 +356,7 @@ static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
 
        /* The highest three bits control the variable regulators */
        regval &= ~0xE0;
-       regval |= (bestindex << 5);
+       regval |= (selector << 5);
 
        err = abx500_set_register_interruptible(abreg->dev, 0,
                                                abreg->regreg, regval);
@@ -464,7 +456,7 @@ static struct regulator_ops regulator_ops_variable = {
        .disable     = ab3100_disable_regulator,
        .is_enabled  = ab3100_is_enabled_regulator,
        .get_voltage = ab3100_get_voltage_regulator,
-       .set_voltage = ab3100_set_voltage_regulator,
+       .set_voltage_sel = ab3100_set_voltage_regulator_sel,
        .list_voltage = ab3100_list_voltage_regulator,
        .enable_time = ab3100_enable_time_regulator,
 };
@@ -474,7 +466,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = {
        .disable     = ab3100_disable_regulator,
        .is_enabled  = ab3100_is_enabled_regulator,
        .get_voltage = ab3100_get_voltage_regulator,
-       .set_voltage = ab3100_set_voltage_regulator,
+       .set_voltage_sel = ab3100_set_voltage_regulator_sel,
        .set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
        .list_voltage = ab3100_list_voltage_regulator,
        .enable_time = ab3100_enable_time_regulator,
@@ -582,6 +574,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
 static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
 {
        struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
+       struct regulator_config config = { };
        int err = 0;
        u8 data;
        int i;
@@ -627,15 +620,15 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
                reg->dev = &pdev->dev;
                reg->plfdata = plfdata;
 
+               config.dev = &pdev->dev;
+               config.driver_data = reg;
+               config.init_data = &plfdata->reg_constraints[i];
+
                /*
                 * Register the regulator, pass around
                 * the ab3100_regulator struct
                 */
-               rdev = regulator_register(&ab3100_regulator_desc[i],
-                                         &pdev->dev,
-                                         &plfdata->reg_constraints[i],
-                                         reg, NULL);
-
+               rdev = regulator_register(&ab3100_regulator_desc[i], &config);
                if (IS_ERR(rdev)) {
                        err = PTR_ERR(rdev);
                        dev_err(&pdev->dev,
index c7ee4c15d6f52c7979558efd9d88919e747f3510..d1563907d3c8e482cffbb5ed05e2aeba79f1c152 100644 (file)
@@ -234,25 +234,8 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
                return val;
 }
 
-static int ab8500_get_best_voltage_index(struct regulator_dev *rdev,
-               int min_uV, int max_uV)
-{
-       struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
-       int i;
-
-       /* check the supported voltage */
-       for (i = 0; i < info->voltages_len; i++) {
-               if ((info->voltages[i] >= min_uV) &&
-                   (info->voltages[i] <= max_uV))
-                       return i;
-       }
-
-       return -EINVAL;
-}
-
-static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
-                                       int min_uV, int max_uV,
-                                       unsigned *selector)
+static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
+                                           unsigned selector)
 {
        int ret;
        struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
@@ -263,18 +246,8 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
                return -EINVAL;
        }
 
-       /* get the appropriate voltages within the range */
-       ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV);
-       if (ret < 0) {
-               dev_err(rdev_get_dev(rdev),
-                               "couldn't get best voltage for regulator\n");
-               return ret;
-       }
-
-       *selector = ret;
-
        /* set the registers for the request */
-       regval = (u8)ret;
+       regval = (u8)selector;
        ret = abx500_mask_and_set_register_interruptible(info->dev,
                        info->voltage_bank, info->voltage_reg,
                        info->voltage_mask, regval);
@@ -319,7 +292,7 @@ static struct regulator_ops ab8500_regulator_ops = {
        .disable        = ab8500_regulator_disable,
        .is_enabled     = ab8500_regulator_is_enabled,
        .get_voltage_sel = ab8500_regulator_get_voltage_sel,
-       .set_voltage    = ab8500_regulator_set_voltage,
+       .set_voltage_sel = ab8500_regulator_set_voltage_sel,
        .list_voltage   = ab8500_list_voltage,
        .enable_time    = ab8500_regulator_enable_time,
        .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
@@ -739,6 +712,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
 {
        struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
        struct ab8500_platform_data *pdata;
+       struct regulator_config config = { };
        int i, err;
 
        if (!ab8500) {
@@ -806,6 +780,10 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
                info = &ab8500_regulator_info[i];
                info->dev = &pdev->dev;
 
+               config.dev = &pdev->dev;
+               config.init_data = &pdata->regulator[i];
+               config.driver_data = info;
+
                /* fix for hardware before ab8500v2.0 */
                if (abx500_get_chip_id(info->dev) < 0x20) {
                        if (info->desc.id == AB8500_LDO_AUX3) {
@@ -819,8 +797,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
                }
 
                /* register regulator with framework */
-               info->regulator = regulator_register(&info->desc, &pdev->dev,
-                               &pdata->regulator[i], info, NULL);
+               info->regulator = regulator_register(&info->desc, &config);
                if (IS_ERR(info->regulator)) {
                        err = PTR_ERR(info->regulator);
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
index 26d23adfc66f8f592f18edeb5aa528e762413e8a..46d05f38baf8ee9bbc1cf9b7e1cd80c59651fafe 100644 (file)
@@ -99,8 +99,8 @@ static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int
        if (ad5398_calc_current(chip, selector) > max_uA)
                return -EINVAL;
 
-       dev_dbg(&client->dev, "changing current %dmA\n",
-               ad5398_calc_current(chip, selector) / 1000);
+       dev_dbg(&client->dev, "changing current %duA\n",
+               ad5398_calc_current(chip, selector));
 
        /* read chip enable bit */
        ret = ad5398_read_reg(client, &data);
@@ -184,7 +184,7 @@ static struct regulator_ops ad5398_ops = {
        .is_enabled = ad5398_is_enabled,
 };
 
-static struct regulator_desc ad5398_reg = {
+static const struct regulator_desc ad5398_reg = {
        .name = "isink",
        .id = 0,
        .ops = &ad5398_ops,
@@ -212,6 +212,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
                                const struct i2c_device_id *id)
 {
        struct regulator_init_data *init_data = client->dev.platform_data;
+       struct regulator_config config = { };
        struct ad5398_chip_info *chip;
        const struct ad5398_current_data_format *df =
                        (struct ad5398_current_data_format *)id->driver_data;
@@ -220,10 +221,14 @@ static int __devinit ad5398_probe(struct i2c_client *client,
        if (!init_data)
                return -EINVAL;
 
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+       chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
+       config.dev = &client->dev;
+       config.init_data = init_data;
+       config.driver_data = chip;
+
        chip->client = client;
 
        chip->min_uA = df->min_uA;
@@ -232,8 +237,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
        chip->current_offset = df->current_offset;
        chip->current_mask = (chip->current_level - 1) << chip->current_offset;
 
-       chip->rdev = regulator_register(&ad5398_reg, &client->dev,
-                                       init_data, chip, NULL);
+       chip->rdev = regulator_register(&ad5398_reg, &config);
        if (IS_ERR(chip->rdev)) {
                ret = PTR_ERR(chip->rdev);
                dev_err(&client->dev, "failed to register %s %s\n",
@@ -246,7 +250,6 @@ static int __devinit ad5398_probe(struct i2c_client *client,
        return 0;
 
 err:
-       kfree(chip);
        return ret;
 }
 
@@ -255,8 +258,6 @@ static int __devexit ad5398_remove(struct i2c_client *client)
        struct ad5398_chip_info *chip = i2c_get_clientdata(client);
 
        regulator_unregister(chip->rdev);
-       kfree(chip);
-
        return 0;
 }
 
index 81fd606e47bc8d198d8bbab301b651e061d9a74d..49b2112b0486120c5434f7e2295955202538387f 100644 (file)
@@ -122,6 +122,7 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
        struct anatop_regulator *sreg;
        struct regulator_init_data *initdata;
        struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_config config = { };
        int ret = 0;
 
        initdata = of_get_regulator_init_data(dev, np);
@@ -178,9 +179,13 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
        rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
                / 25000 + 1;
 
+       config.dev = &pdev->dev;
+       config.init_data = initdata;
+       config.driver_data = sreg;
+       config.of_node = pdev->dev.of_node;
+
        /* register regulator */
-       rdev = regulator_register(rdesc, dev,
-                                 initdata, sreg, pdev->dev.of_node);
+       rdev = regulator_register(rdesc, &config);
        if (IS_ERR(rdev)) {
                dev_err(dev, "failed to register %s\n",
                        rdesc->name);
index e70dd382a009a2db05d78087b6e0e588584e6b6e..aec7ad5cb2d326e798a395e2beadf8554c799136 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/of.h>
+#include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
@@ -74,6 +75,7 @@ struct regulator_map {
 struct regulator {
        struct device *dev;
        struct list_head list;
+       unsigned int always_on:1;
        int uA_load;
        int min_uV;
        int max_uV;
@@ -155,6 +157,17 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
        return regnode;
 }
 
+static int _regulator_can_change_status(struct regulator_dev *rdev)
+{
+       if (!rdev->constraints)
+               return 0;
+
+       if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
+               return 1;
+       else
+               return 0;
+}
+
 /* Platform voltage constraint check */
 static int regulator_check_voltage(struct regulator_dev *rdev,
                                   int *min_uV, int *max_uV)
@@ -649,7 +662,7 @@ static void drms_uA_update(struct regulator_dev *rdev)
        /* get input voltage */
        input_uV = 0;
        if (rdev->supply)
-               input_uV = _regulator_get_voltage(rdev);
+               input_uV = regulator_get_voltage(rdev->supply);
        if (input_uV <= 0)
                input_uV = rdev->constraints->input_uV;
        if (input_uV <= 0)
@@ -673,17 +686,14 @@ static int suspend_set_state(struct regulator_dev *rdev,
        struct regulator_state *rstate)
 {
        int ret = 0;
-       bool can_set_state;
-
-       can_set_state = rdev->desc->ops->set_suspend_enable &&
-               rdev->desc->ops->set_suspend_disable;
 
        /* If we have no suspend mode configration don't set anything;
-        * only warn if the driver actually makes the suspend mode
-        * configurable.
+        * only warn if the driver implements set_suspend_voltage or
+        * set_suspend_mode callback.
         */
        if (!rstate->enabled && !rstate->disabled) {
-               if (can_set_state)
+               if (rdev->desc->ops->set_suspend_voltage ||
+                   rdev->desc->ops->set_suspend_mode)
                        rdev_warn(rdev, "No configuration\n");
                return 0;
        }
@@ -693,15 +703,13 @@ static int suspend_set_state(struct regulator_dev *rdev,
                return -EINVAL;
        }
 
-       if (!can_set_state) {
-               rdev_err(rdev, "no way to set suspend state\n");
-               return -EINVAL;
-       }
-
-       if (rstate->enabled)
+       if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
                ret = rdev->desc->ops->set_suspend_enable(rdev);
-       else
+       else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
                ret = rdev->desc->ops->set_suspend_disable(rdev);
+       else /* OK if set_suspend_enable or set_suspend_disable is NULL */
+               ret = 0;
+
        if (ret < 0) {
                rdev_err(rdev, "failed to enabled/disable\n");
                return ret;
@@ -1146,6 +1154,15 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                                   &regulator->max_uV);
        }
 
+       /*
+        * Check now if the regulator is an always on regulator - if
+        * it is then we don't need to do nearly so much work for
+        * enable/disable calls.
+        */
+       if (!_regulator_can_change_status(rdev) &&
+           _regulator_is_enabled(rdev))
+               regulator->always_on = true;
+
        mutex_unlock(&rdev->mutex);
        return regulator;
 link_name_err:
@@ -1169,26 +1186,52 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
 }
 
 static struct regulator_dev *regulator_dev_lookup(struct device *dev,
-                                                        const char *supply)
+                                                 const char *supply,
+                                                 int *ret)
 {
        struct regulator_dev *r;
        struct device_node *node;
+       struct regulator_map *map;
+       const char *devname = NULL;
 
        /* first do a dt based lookup */
        if (dev && dev->of_node) {
                node = of_get_regulator(dev, supply);
-               if (node)
+               if (node) {
                        list_for_each_entry(r, &regulator_list, list)
                                if (r->dev.parent &&
                                        node == r->dev.of_node)
                                        return r;
+               } else {
+                       /*
+                        * If we couldn't even get the node then it's
+                        * not just that the device didn't register
+                        * yet, there's no node and we'll never
+                        * succeed.
+                        */
+                       *ret = -ENODEV;
+               }
        }
 
        /* if not found, try doing it non-dt way */
+       if (dev)
+               devname = dev_name(dev);
+
        list_for_each_entry(r, &regulator_list, list)
                if (strcmp(rdev_get_name(r), supply) == 0)
                        return r;
 
+       list_for_each_entry(map, &regulator_map_list, list) {
+               /* If the mapping has a device set up it must match */
+               if (map->dev_name &&
+                   (!devname || strcmp(map->dev_name, devname)))
+                       continue;
+
+               if (strcmp(map->supply, supply) == 0)
+                       return map->regulator;
+       }
+
+
        return NULL;
 }
 
@@ -1197,7 +1240,6 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
                                        int exclusive)
 {
        struct regulator_dev *rdev;
-       struct regulator_map *map;
        struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
        const char *devname = NULL;
        int ret;
@@ -1212,22 +1254,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 
        mutex_lock(&regulator_list_mutex);
 
-       rdev = regulator_dev_lookup(dev, id);
+       rdev = regulator_dev_lookup(dev, id, &ret);
        if (rdev)
                goto found;
 
-       list_for_each_entry(map, &regulator_map_list, list) {
-               /* If the mapping has a device set up it must match */
-               if (map->dev_name &&
-                   (!devname || strcmp(map->dev_name, devname)))
-                       continue;
-
-               if (strcmp(map->supply, id) == 0) {
-                       rdev = map->regulator;
-                       goto found;
-               }
-       }
-
        if (board_wants_dummy_regulator) {
                rdev = dummy_regulator_rdev;
                goto found;
@@ -1435,17 +1465,6 @@ void devm_regulator_put(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(devm_regulator_put);
 
-static int _regulator_can_change_status(struct regulator_dev *rdev)
-{
-       if (!rdev->constraints)
-               return 0;
-
-       if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
-               return 1;
-       else
-               return 0;
-}
-
 /* locks held by regulator_enable() */
 static int _regulator_enable(struct regulator_dev *rdev)
 {
@@ -1525,6 +1544,9 @@ int regulator_enable(struct regulator *regulator)
        struct regulator_dev *rdev = regulator->rdev;
        int ret = 0;
 
+       if (regulator->always_on)
+               return 0;
+
        if (rdev->supply) {
                ret = regulator_enable(rdev->supply);
                if (ret != 0)
@@ -1603,6 +1625,9 @@ int regulator_disable(struct regulator *regulator)
        struct regulator_dev *rdev = regulator->rdev;
        int ret = 0;
 
+       if (regulator->always_on)
+               return 0;
+
        mutex_lock(&rdev->mutex);
        ret = _regulator_disable(rdev);
        mutex_unlock(&rdev->mutex);
@@ -1711,6 +1736,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
        struct regulator_dev *rdev = regulator->rdev;
        int ret;
 
+       if (regulator->always_on)
+               return 0;
+
        mutex_lock(&rdev->mutex);
        rdev->deferred_disables++;
        mutex_unlock(&rdev->mutex);
@@ -1724,6 +1752,61 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
 }
 EXPORT_SYMBOL_GPL(regulator_disable_deferred);
 
+/**
+ * regulator_is_enabled_regmap - standard is_enabled() for regmap users
+ *
+ * @rdev: regulator to operate on
+ *
+ * Regulators that use regmap for their register I/O can set the
+ * enable_reg and enable_mask fields in their descriptor and then use
+ * this as their is_enabled operation, saving some code.
+ */
+int regulator_is_enabled_regmap(struct regulator_dev *rdev)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
+       if (ret != 0)
+               return ret;
+
+       return (val & rdev->desc->enable_mask) != 0;
+}
+EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
+
+/**
+ * regulator_enable_regmap - standard enable() for regmap users
+ *
+ * @rdev: regulator to operate on
+ *
+ * Regulators that use regmap for their register I/O can set the
+ * enable_reg and enable_mask fields in their descriptor and then use
+ * this as their enable() operation, saving some code.
+ */
+int regulator_enable_regmap(struct regulator_dev *rdev)
+{
+       return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+                                 rdev->desc->enable_mask,
+                                 rdev->desc->enable_mask);
+}
+EXPORT_SYMBOL_GPL(regulator_enable_regmap);
+
+/**
+ * regulator_disable_regmap - standard disable() for regmap users
+ *
+ * @rdev: regulator to operate on
+ *
+ * Regulators that use regmap for their register I/O can set the
+ * enable_reg and enable_mask fields in their descriptor and then use
+ * this as their disable() operation, saving some code.
+ */
+int regulator_disable_regmap(struct regulator_dev *rdev)
+{
+       return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+                                 rdev->desc->enable_mask, 0);
+}
+EXPORT_SYMBOL_GPL(regulator_disable_regmap);
+
 static int _regulator_is_enabled(struct regulator_dev *rdev)
 {
        /* If we don't know then assume that the regulator is always on */
@@ -1749,6 +1832,9 @@ int regulator_is_enabled(struct regulator *regulator)
 {
        int ret;
 
+       if (regulator->always_on)
+               return 1;
+
        mutex_lock(&regulator->rdev->mutex);
        ret = _regulator_is_enabled(regulator->rdev);
        mutex_unlock(&regulator->rdev->mutex);
@@ -1837,29 +1923,85 @@ int regulator_is_supported_voltage(struct regulator *regulator,
 }
 EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
 
+/**
+ * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
+ *
+ * @rdev: regulator to operate on
+ *
+ * Regulators that use regmap for their register I/O can set the
+ * vsel_reg and vsel_mask fields in their descriptor and then use this
+ * as their get_voltage_vsel operation, saving some code.
+ */
+int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
+{
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+       if (ret != 0)
+               return ret;
+
+       val &= rdev->desc->vsel_mask;
+       val >>= ffs(rdev->desc->vsel_mask) - 1;
+
+       return val;
+}
+EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
+
+/**
+ * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
+ *
+ * @rdev: regulator to operate on
+ * @sel: Selector to set
+ *
+ * Regulators that use regmap for their register I/O can set the
+ * vsel_reg and vsel_mask fields in their descriptor and then use this
+ * as their set_voltage_vsel operation, saving some code.
+ */
+int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
+{
+       sel <<= ffs(rdev->desc->vsel_mask) - 1;
+
+       return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+                                 rdev->desc->vsel_mask, sel);
+}
+EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
+
 static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                                     int min_uV, int max_uV)
 {
        int ret;
        int delay = 0;
        unsigned int selector;
+       int old_selector = -1;
+       int best_val = INT_MAX;
 
        trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
 
        min_uV += rdev->constraints->uV_offset;
        max_uV += rdev->constraints->uV_offset;
 
+       /*
+        * If we can't obtain the old selector there is not enough
+        * info to call set_voltage_time_sel().
+        */
+       if (rdev->desc->ops->set_voltage_time_sel &&
+           rdev->desc->ops->get_voltage_sel) {
+               old_selector = rdev->desc->ops->get_voltage_sel(rdev);
+               if (old_selector < 0)
+                       return old_selector;
+       }
+
        if (rdev->desc->ops->set_voltage) {
                ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
                                                   &selector);
 
                if (rdev->desc->ops->list_voltage)
-                       selector = rdev->desc->ops->list_voltage(rdev,
+                       best_val = rdev->desc->ops->list_voltage(rdev,
                                                                 selector);
                else
-                       selector = -1;
+                       best_val = -1;
        } else if (rdev->desc->ops->set_voltage_sel) {
-               int best_val = INT_MAX;
                int i;
 
                selector = 0;
@@ -1878,36 +2020,27 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                        }
                }
 
-               /*
-                * If we can't obtain the old selector there is not enough
-                * info to call set_voltage_time_sel().
-                */
-               if (rdev->desc->ops->set_voltage_time_sel &&
-                   rdev->desc->ops->get_voltage_sel) {
-                       unsigned int old_selector = 0;
-
-                       ret = rdev->desc->ops->get_voltage_sel(rdev);
-                       if (ret < 0)
-                               return ret;
-                       old_selector = ret;
-                       ret = rdev->desc->ops->set_voltage_time_sel(rdev,
-                                               old_selector, selector);
-                       if (ret < 0)
-                               rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret);
-                       else
-                               delay = ret;
-               }
-
-               if (best_val != INT_MAX) {
+               if (best_val != INT_MAX)
                        ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
-                       selector = best_val;
-               } else {
+               else
                        ret = -EINVAL;
-               }
        } else {
                ret = -EINVAL;
        }
 
+       /* Call set_voltage_time_sel if successfully obtained old_selector */
+       if (ret == 0 && old_selector >= 0 &&
+           rdev->desc->ops->set_voltage_time_sel) {
+
+               delay = rdev->desc->ops->set_voltage_time_sel(rdev,
+                                               old_selector, selector);
+               if (delay < 0) {
+                       rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
+                                 delay);
+                       delay = 0;
+               }
+       }
+
        /* Insert any necessary delays */
        if (delay >= 1000) {
                mdelay(delay / 1000);
@@ -1920,7 +2053,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
                                     NULL);
 
-       trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
+       trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
 
        return ret;
 }
@@ -2324,6 +2457,9 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
         */
        ret = -EINVAL;
 
+       if (!rdev->desc->ops->set_mode)
+               goto out;
+
        /* get output voltage */
        output_uV = _regulator_get_voltage(rdev);
        if (output_uV <= 0) {
@@ -2525,9 +2661,13 @@ int regulator_bulk_enable(int num_consumers,
        int i;
        int ret = 0;
 
-       for (i = 0; i < num_consumers; i++)
-               async_schedule_domain(regulator_bulk_enable_async,
-                                     &consumers[i], &async_domain);
+       for (i = 0; i < num_consumers; i++) {
+               if (consumers[i].consumer->always_on)
+                       consumers[i].ret = 0;
+               else
+                       async_schedule_domain(regulator_bulk_enable_async,
+                                             &consumers[i], &async_domain);
+       }
 
        async_synchronize_full_domain(&async_domain);
 
@@ -2566,7 +2706,7 @@ int regulator_bulk_disable(int num_consumers,
                           struct regulator_bulk_data *consumers)
 {
        int i;
-       int ret;
+       int ret, r;
 
        for (i = num_consumers - 1; i >= 0; --i) {
                ret = regulator_disable(consumers[i].consumer);
@@ -2578,8 +2718,12 @@ int regulator_bulk_disable(int num_consumers,
 
 err:
        pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
-       for (++i; i < num_consumers; ++i)
-               regulator_enable(consumers[i].consumer);
+       for (++i; i < num_consumers; ++i) {
+               r = regulator_enable(consumers[i].consumer);
+               if (r != 0)
+                       pr_err("Failed to reename %s: %d\n",
+                              consumers[i].supply, r);
+       }
 
        return ret;
 }
@@ -2756,10 +2900,6 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
                        return status;
        }
 
-       /* suspend mode constraints need multiple supporting methods */
-       if (!(ops->set_suspend_enable && ops->set_suspend_disable))
-               return status;
-
        status = device_create_file(dev, &dev_attr_suspend_standby_state);
        if (status < 0)
                return status;
@@ -2820,28 +2960,29 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
 /**
  * regulator_register - register regulator
  * @regulator_desc: regulator to register
- * @dev: struct device for the regulator
- * @init_data: platform provided init data, passed through by driver
- * @driver_data: private regulator data
- * @of_node: OpenFirmware node to parse for device tree bindings (may be
- *           NULL).
+ * @config: runtime configuration for regulator
  *
  * Called by regulator drivers to register a regulator.
  * Returns 0 on success.
  */
-struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
-       struct device *dev, const struct regulator_init_data *init_data,
-       void *driver_data, struct device_node *of_node)
+struct regulator_dev *
+regulator_register(const struct regulator_desc *regulator_desc,
+                  const struct regulator_config *config)
 {
        const struct regulation_constraints *constraints = NULL;
+       const struct regulator_init_data *init_data;
        static atomic_t regulator_no = ATOMIC_INIT(0);
        struct regulator_dev *rdev;
+       struct device *dev;
        int ret, i;
        const char *supply = NULL;
 
-       if (regulator_desc == NULL)
+       if (regulator_desc == NULL || config == NULL)
                return ERR_PTR(-EINVAL);
 
+       dev = config->dev;
+       WARN_ON(!dev);
+
        if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
                return ERR_PTR(-EINVAL);
 
@@ -2865,6 +3006,8 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
                return ERR_PTR(-EINVAL);
        }
 
+       init_data = config->init_data;
+
        rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
        if (rdev == NULL)
                return ERR_PTR(-ENOMEM);
@@ -2872,9 +3015,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        mutex_lock(&regulator_list_mutex);
 
        mutex_init(&rdev->mutex);
-       rdev->reg_data = driver_data;
+       rdev->reg_data = config->driver_data;
        rdev->owner = regulator_desc->owner;
        rdev->desc = regulator_desc;
+       rdev->regmap = config->regmap;
        INIT_LIST_HEAD(&rdev->consumer_list);
        INIT_LIST_HEAD(&rdev->list);
        BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
@@ -2889,7 +3033,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 
        /* register with sysfs */
        rdev->dev.class = &regulator_class;
-       rdev->dev.of_node = of_node;
+       rdev->dev.of_node = config->of_node;
        rdev->dev.parent = dev;
        dev_set_name(&rdev->dev, "regulator.%d",
                     atomic_inc_return(&regulator_no) - 1);
@@ -2922,7 +3066,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        if (supply) {
                struct regulator_dev *r;
 
-               r = regulator_dev_lookup(dev, supply);
+               r = regulator_dev_lookup(dev, supply, &ret);
 
                if (!r) {
                        dev_err(dev, "Failed to find supply %s\n", supply);
index 1851f0929ef01fdb1401b63dd0d731caf83775b9..682bdb391abde96336cfa8978837925509f88e60 100644 (file)
@@ -517,6 +517,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
 {
        struct da903x_regulator_info *ri = NULL;
        struct regulator_dev *rdev;
+       struct regulator_config config = { };
 
        ri = find_regulator_info(pdev->id);
        if (ri == NULL) {
@@ -536,8 +537,11 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
        if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
                ri->desc.ops = &da9030_regulator_ldo1_15_ops;
 
-       rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdev->dev.platform_data, ri, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = ri;
+
+       rdev = regulator_register(&ri->desc, &config);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
index 09915e89705dfd45f3f0b9f8102ac8946defa9b2..2943ef6bdf45b1ef8a5068fb7923f9870f11190c 100644 (file)
@@ -19,6 +19,9 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#ifdef CONFIG_OF
+#include <linux/regulator/of_regulator.h>
+#endif
 
 #include <linux/mfd/da9052/da9052.h>
 #include <linux/mfd/da9052/reg.h>
 #define DA9052_BUCK_ILIM_MASK_EVEN     0x0c
 #define DA9052_BUCK_ILIM_MASK_ODD      0xc0
 
+/* DA9052 REGULATOR IDs */
+#define DA9052_ID_BUCK1                0
+#define DA9052_ID_BUCK2                1
+#define DA9052_ID_BUCK3                2
+#define DA9052_ID_BUCK4                3
+#define DA9052_ID_LDO1         4
+#define DA9052_ID_LDO2         5
+#define DA9052_ID_LDO3         6
+#define DA9052_ID_LDO4         7
+#define DA9052_ID_LDO5         8
+#define DA9052_ID_LDO6         9
+#define DA9052_ID_LDO7         10
+#define DA9052_ID_LDO8         11
+#define DA9052_ID_LDO9         12
+#define DA9052_ID_LDO10                13
+
 static const u32 da9052_current_limits[3][4] = {
        {700000, 800000, 1000000, 1200000},     /* DA9052-BC BUCKs */
        {1600000, 2000000, 2400000, 3000000},   /* DA9053-AA/Bx BUCK-CORE */
@@ -50,8 +69,6 @@ struct da9052_regulator_info {
        int step_uV;
        int min_uV;
        int max_uV;
-       unsigned char volt_shift;
-       unsigned char en_bit;
        unsigned char activate_bit;
 };
 
@@ -70,42 +87,6 @@ static int verify_range(struct da9052_regulator_info *info,
        return 0;
 }
 
-static int da9052_regulator_enable(struct regulator_dev *rdev)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
-
-       return da9052_reg_update(regulator->da9052,
-                                DA9052_BUCKCORE_REG + offset,
-                                1 << info->en_bit, 1 << info->en_bit);
-}
-
-static int da9052_regulator_disable(struct regulator_dev *rdev)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
-
-       return da9052_reg_update(regulator->da9052,
-                                DA9052_BUCKCORE_REG + offset,
-                                1 << info->en_bit, 0);
-}
-
-static int da9052_regulator_is_enabled(struct regulator_dev *rdev)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
-       int ret;
-
-       ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
-       if (ret < 0)
-               return ret;
-
-       return ret & (1 << info->en_bit);
-}
-
 static int da9052_dcdc_get_current_limit(struct regulator_dev *rdev)
 {
        struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
@@ -173,36 +154,23 @@ static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
                                         reg_val << 6);
 }
 
-static int da9052_list_buckperi_voltage(struct regulator_dev *rdev,
-                                        unsigned int selector)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int volt_uV;
-
-       if ((regulator->da9052->chip_id == DA9052) &&
-           (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
-               volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
-                           + info->min_uV);
-               volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
-                           * (DA9052_BUCK_PERI_3uV_STEP);
-       } else
-                       volt_uV = (selector * info->step_uV) + info->min_uV;
-
-       if (volt_uV > info->max_uV)
-               return -EINVAL;
-
-       return volt_uV;
-}
-
 static int da9052_list_voltage(struct regulator_dev *rdev,
                                unsigned int selector)
 {
        struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
        struct da9052_regulator_info *info = regulator->info;
+       int id = rdev_get_id(rdev);
        int volt_uV;
 
-       volt_uV = info->min_uV + info->step_uV * selector;
+       if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052)
+               && (selector >= DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)) {
+               volt_uV = ((DA9052_BUCK_PERI_REG_MAP_UPTO_3uV * info->step_uV)
+                         + info->min_uV);
+               volt_uV += (selector - DA9052_BUCK_PERI_REG_MAP_UPTO_3uV)
+                                   * (DA9052_BUCK_PERI_3uV_STEP);
+       } else {
+               volt_uV = (selector * info->step_uV) + info->min_uV;
+       }
 
        if (volt_uV > info->max_uV)
                return -EINVAL;
@@ -210,13 +178,13 @@ static int da9052_list_voltage(struct regulator_dev *rdev,
        return volt_uV;
 }
 
-static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
+static int da9052_regulator_set_voltage(struct regulator_dev *rdev,
                                             int min_uV, int max_uV,
                                             unsigned int *selector)
 {
        struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
        struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
+       int id = rdev_get_id(rdev);
        int ret;
 
        ret = verify_range(info, min_uV, max_uV);
@@ -226,281 +194,135 @@ static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev,
        if (min_uV < info->min_uV)
                min_uV = info->min_uV;
 
-       *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
-
-       ret = da9052_list_voltage(rdev, *selector);
-       if (ret < 0)
-               return ret;
-
-       return da9052_reg_update(regulator->da9052,
-                                DA9052_BUCKCORE_REG + offset,
-                                (1 << info->volt_shift) - 1, *selector);
-}
-
-static int da9052_set_ldo_voltage(struct regulator_dev *rdev,
-                                  int min_uV, int max_uV,
-                                  unsigned int *selector)
-{
-       return da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
-}
-
-static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev,
-                                     int min_uV, int max_uV,
-                                     unsigned int *selector)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int ret;
-
-       ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
-       if (ret < 0)
-               return ret;
-
-       /* Some LDOs are DVC controlled which requires enabling of
-        * the LDO activate bit to implment the changes on the
-        * LDO output.
-       */
-       return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
-                                info->activate_bit, info->activate_bit);
-}
-
-static int da9052_set_dcdc_voltage(struct regulator_dev *rdev,
-                                   int min_uV, int max_uV,
-                                   unsigned int *selector)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int ret;
-
-       ret = da9052_regulator_set_voltage_int(rdev, min_uV, max_uV, selector);
-       if (ret < 0)
-               return ret;
-
-       /* Some DCDCs are DVC controlled which requires enabling of
-        * the DCDC activate bit to implment the changes on the
-        * DCDC output.
-       */
-       return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
-                                info->activate_bit, info->activate_bit);
-}
-
-static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
-       int ret;
-
-       ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
-       if (ret < 0)
-               return ret;
-
-       ret &= ((1 << info->volt_shift) - 1);
-
-       return ret;
-}
-
-static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV,
-                                       int max_uV, unsigned int *selector)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
-       int ret;
-
-       ret = verify_range(info, min_uV, max_uV);
-       if (ret < 0)
-               return ret;
-
-       if (min_uV < info->min_uV)
-               min_uV = info->min_uV;
-
-       if ((regulator->da9052->chip_id == DA9052) &&
-           (min_uV >= DA9052_CONST_3uV))
-               *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
-                           DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
-                                        DA9052_BUCK_PERI_3uV_STEP);
-       else
+       if ((id == DA9052_ID_BUCK4) && (regulator->da9052->chip_id == DA9052)
+               && (min_uV >= DA9052_CONST_3uV)) {
+                       *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV +
+                                   DIV_ROUND_UP(min_uV - DA9052_CONST_3uV,
+                                                DA9052_BUCK_PERI_3uV_STEP);
+       } else {
                *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
+       }
 
-       ret = da9052_list_buckperi_voltage(rdev, *selector);
+       ret = da9052_list_voltage(rdev, *selector);
        if (ret < 0)
                return ret;
 
-       return da9052_reg_update(regulator->da9052,
-                                DA9052_BUCKCORE_REG + offset,
-                                (1 << info->volt_shift) - 1, *selector);
-}
-
-static int da9052_get_buckperi_voltage_sel(struct regulator_dev *rdev)
-{
-       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
-       struct da9052_regulator_info *info = regulator->info;
-       int offset = rdev_get_id(rdev);
-       int ret;
-
-       ret = da9052_reg_read(regulator->da9052, DA9052_BUCKCORE_REG + offset);
+       ret = da9052_reg_update(regulator->da9052, rdev->desc->vsel_reg,
+                               rdev->desc->vsel_mask, *selector);
        if (ret < 0)
                return ret;
 
-       ret &= ((1 << info->volt_shift) - 1);
+       /* Some LDOs and DCDCs are DVC controlled which requires enabling of
+        * the activate bit to implment the changes on the output.
+        */
+       switch (id) {
+       case DA9052_ID_BUCK1:
+       case DA9052_ID_BUCK2:
+       case DA9052_ID_BUCK3:
+       case DA9052_ID_LDO2:
+       case DA9052_ID_LDO3:
+               ret = da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
+                                       info->activate_bit, info->activate_bit);
+               break;
+       }
 
        return ret;
 }
 
-static struct regulator_ops da9052_buckperi_ops = {
-       .list_voltage = da9052_list_buckperi_voltage,
-       .get_voltage_sel = da9052_get_buckperi_voltage_sel,
-       .set_voltage = da9052_set_buckperi_voltage,
-
-       .get_current_limit = da9052_dcdc_get_current_limit,
-       .set_current_limit = da9052_dcdc_set_current_limit,
-
-       .is_enabled = da9052_regulator_is_enabled,
-       .enable = da9052_regulator_enable,
-       .disable = da9052_regulator_disable,
-};
-
 static struct regulator_ops da9052_dcdc_ops = {
-       .set_voltage = da9052_set_dcdc_voltage,
+       .set_voltage = da9052_regulator_set_voltage,
        .get_current_limit = da9052_dcdc_get_current_limit,
        .set_current_limit = da9052_dcdc_set_current_limit,
 
        .list_voltage = da9052_list_voltage,
-       .get_voltage_sel = da9052_get_regulator_voltage_sel,
-       .is_enabled = da9052_regulator_is_enabled,
-       .enable = da9052_regulator_enable,
-       .disable = da9052_regulator_disable,
-};
-
-static struct regulator_ops da9052_ldo5_6_ops = {
-       .set_voltage = da9052_set_ldo5_6_voltage,
-
-       .list_voltage = da9052_list_voltage,
-       .get_voltage_sel = da9052_get_regulator_voltage_sel,
-       .is_enabled = da9052_regulator_is_enabled,
-       .enable = da9052_regulator_enable,
-       .disable = da9052_regulator_disable,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
 };
 
 static struct regulator_ops da9052_ldo_ops = {
-       .set_voltage = da9052_set_ldo_voltage,
+       .set_voltage = da9052_regulator_set_voltage,
 
        .list_voltage = da9052_list_voltage,
-       .get_voltage_sel = da9052_get_regulator_voltage_sel,
-       .is_enabled = da9052_regulator_is_enabled,
-       .enable = da9052_regulator_enable,
-       .disable = da9052_regulator_disable,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
 };
 
-#define DA9052_LDO5_6(_id, step, min, max, sbits, ebits, abits) \
-{\
-       .reg_desc = {\
-               .name = "LDO" #_id,\
-               .ops = &da9052_ldo5_6_ops,\
-               .type = REGULATOR_VOLTAGE,\
-               .id = _id,\
-               .n_voltages = (max - min) / step + 1, \
-               .owner = THIS_MODULE,\
-       },\
-       .min_uV = (min) * 1000,\
-       .max_uV = (max) * 1000,\
-       .step_uV = (step) * 1000,\
-       .volt_shift = (sbits),\
-       .en_bit = (ebits),\
-       .activate_bit = (abits),\
-}
-
 #define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \
 {\
        .reg_desc = {\
-               .name = "LDO" #_id,\
+               .name = #_id,\
                .ops = &da9052_ldo_ops,\
                .type = REGULATOR_VOLTAGE,\
-               .id = _id,\
+               .id = DA9052_ID_##_id,\
                .n_voltages = (max - min) / step + 1, \
                .owner = THIS_MODULE,\
+               .vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
+               .vsel_mask = (1 << (sbits)) - 1,\
+               .enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
+               .enable_mask = 1 << (ebits),\
        },\
        .min_uV = (min) * 1000,\
        .max_uV = (max) * 1000,\
        .step_uV = (step) * 1000,\
-       .volt_shift = (sbits),\
-       .en_bit = (ebits),\
        .activate_bit = (abits),\
 }
 
 #define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
 {\
        .reg_desc = {\
-               .name = "BUCK" #_id,\
+               .name = #_id,\
                .ops = &da9052_dcdc_ops,\
                .type = REGULATOR_VOLTAGE,\
-               .id = _id,\
+               .id = DA9052_ID_##_id,\
                .n_voltages = (max - min) / step + 1, \
                .owner = THIS_MODULE,\
+               .vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
+               .vsel_mask = (1 << (sbits)) - 1,\
+               .enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
+               .enable_mask = 1 << (ebits),\
        },\
        .min_uV = (min) * 1000,\
        .max_uV = (max) * 1000,\
        .step_uV = (step) * 1000,\
-       .volt_shift = (sbits),\
-       .en_bit = (ebits),\
-       .activate_bit = (abits),\
-}
-
-#define DA9052_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
-{\
-       .reg_desc = {\
-               .name = "BUCK" #_id,\
-               .ops = &da9052_buckperi_ops,\
-               .type = REGULATOR_VOLTAGE,\
-               .id = _id,\
-               .n_voltages = (max - min) / step + 1, \
-               .owner = THIS_MODULE,\
-       },\
-       .min_uV = (min) * 1000,\
-       .max_uV = (max) * 1000,\
-       .step_uV = (step) * 1000,\
-       .volt_shift = (sbits),\
-       .en_bit = (ebits),\
        .activate_bit = (abits),\
 }
 
 static struct da9052_regulator_info da9052_regulator_info[] = {
-       /* Buck1 - 4 */
-       DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
-       DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
-       DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
-       DA9052_BUCKPERI(3, 50, 1800, 3600, 5, 6, 0),
-       /* LD01 - LDO10 */
-       DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
-       DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
-       DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
-       DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
-       DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
-       DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
+       DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
+       DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
+       DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
+       DA9052_DCDC(BUCK4, 50, 1800, 3600, 5, 6, 0),
+       DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0),
+       DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
+       DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
+       DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0),
+       DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0),
+       DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0),
 };
 
 static struct da9052_regulator_info da9053_regulator_info[] = {
-       /* Buck1 - 4 */
-       DA9052_DCDC(0, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
-       DA9052_DCDC(1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
-       DA9052_DCDC(2, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
-       DA9052_BUCKPERI(3, 25, 925, 2500, 6, 6, 0),
-       /* LD01 - LDO10 */
-       DA9052_LDO(4, 50, 600, 1800, 5, 6, 0),
-       DA9052_LDO5_6(5, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
-       DA9052_LDO5_6(6, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
-       DA9052_LDO(7, 25, 1725, 3300, 6, 6, 0),
-       DA9052_LDO(8, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(9, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(10, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(11, 50, 1200, 3600, 6, 6, 0),
-       DA9052_LDO(12, 50, 1250, 3650, 6, 6, 0),
-       DA9052_LDO(13, 50, 1200, 3600, 6, 6, 0),
+       DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO),
+       DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO),
+       DA9052_DCDC(BUCK3, 25, 925, 2500, 6, 6, DA9052_SUPPLY_VBMEMGO),
+       DA9052_DCDC(BUCK4, 25, 925, 2500, 6, 6, 0),
+       DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0),
+       DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO),
+       DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO),
+       DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0),
+       DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0),
+       DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0),
+       DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0),
 };
 
 static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
@@ -533,10 +355,10 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
 
 static int __devinit da9052_regulator_probe(struct platform_device *pdev)
 {
+       struct regulator_config config = { };
        struct da9052_regulator *regulator;
        struct da9052 *da9052;
        struct da9052_pdata *pdata;
-       int ret;
 
        regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator),
                                 GFP_KERNEL);
@@ -551,26 +373,49 @@ static int __devinit da9052_regulator_probe(struct platform_device *pdev)
                                              pdev->id);
        if (regulator->info == NULL) {
                dev_err(&pdev->dev, "invalid regulator ID specified\n");
-               ret = -EINVAL;
-               goto err;
+               return -EINVAL;
        }
+
+       config.dev = &pdev->dev;
+       config.driver_data = regulator;
+       config.regmap = da9052->regmap;
+       if (pdata && pdata->regulators) {
+               config.init_data = pdata->regulators[pdev->id];
+       } else {
+#ifdef CONFIG_OF
+               struct device_node *nproot = da9052->dev->of_node;
+               struct device_node *np;
+
+               if (!nproot)
+                       return -ENODEV;
+
+               nproot = of_find_node_by_name(nproot, "regulators");
+               if (!nproot)
+                       return -ENODEV;
+
+               for (np = of_get_next_child(nproot, NULL); !np;
+                    np = of_get_next_child(nproot, np)) {
+                       if (!of_node_cmp(np->name,
+                                        regulator->info->reg_desc.name)) {
+                               config.init_data = of_get_regulator_init_data(
+                                       &pdev->dev, np);
+                               break;
+                       }
+               }
+#endif
+       }
+
        regulator->rdev = regulator_register(&regulator->info->reg_desc,
-                                            &pdev->dev,
-                                            pdata->regulators[pdev->id],
-                                            regulator, NULL);
+                                            &config);
        if (IS_ERR(regulator->rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                        regulator->info->reg_desc.name);
-               ret = PTR_ERR(regulator->rdev);
-               goto err;
+               return PTR_ERR(regulator->rdev);
        }
 
        platform_set_drvdata(pdev, regulator);
 
        return 0;
-err:
-       devm_kfree(&pdev->dev, regulator);
-       return ret;
 }
 
 static int __devexit da9052_regulator_remove(struct platform_device *pdev)
@@ -578,8 +423,6 @@ static int __devexit da9052_regulator_remove(struct platform_device *pdev)
        struct da9052_regulator *regulator = platform_get_drvdata(pdev);
 
        regulator_unregister(regulator->rdev);
-       devm_kfree(&pdev->dev, regulator);
-
        return 0;
 }
 
index 4bd25e75efa0e2ff7b7383e8dbb39387830296be..87b2e83be11c60f7db9f17b41e09b57e4221846a 100644 (file)
@@ -414,6 +414,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
 {
        struct regulator_init_data *db8500_init_data =
                                        dev_get_platdata(&pdev->dev);
+       struct regulator_config config = { };
        int i, err;
 
        /* register all regulators */
@@ -425,9 +426,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
                info = &dbx500_regulator_info[i];
                info->dev = &pdev->dev;
 
+               config.dev = &pdev->dev;
+               config.init_data = init_data;
+               config.driver_data = info;
+
                /* register with the regulator framework */
-               info->rdev = regulator_register(&info->desc, &pdev->dev,
-                               init_data, info, NULL);
+               info->rdev = regulator_register(&info->desc, &config);
                if (IS_ERR(info->rdev)) {
                        err = PTR_ERR(info->rdev);
                        dev_err(&pdev->dev, "failed to register %s: err %i\n",
index 0ee00de4be72867e38febb48ae35d4f8f115bc4f..86f655c7f7a14ac5df494bcb5dcf3fb4b7e83955 100644 (file)
@@ -39,10 +39,13 @@ static struct regulator_desc dummy_desc = {
 
 static int __devinit dummy_regulator_probe(struct platform_device *pdev)
 {
+       struct regulator_config config = { };
        int ret;
 
-       dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
-                                                 &dummy_initdata, NULL, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = &dummy_initdata;
+
+       dummy_regulator_rdev = regulator_register(&dummy_desc, &config);
        if (IS_ERR(dummy_regulator_rdev)) {
                ret = PTR_ERR(dummy_regulator_rdev);
                pr_err("Failed to register regulator: %d\n", ret);
index 40f38030b394d3d99418a195e92417fc61b04e8b..b47b005a8d280557fd7ffe2be3104be42371e89d 100644 (file)
@@ -105,10 +105,8 @@ static int fixed_voltage_enable(struct regulator_dev *dev)
 {
        struct fixed_voltage_data *data = rdev_get_drvdata(dev);
 
-       if (gpio_is_valid(data->gpio)) {
-               gpio_set_value_cansleep(data->gpio, data->enable_high);
-               data->is_enabled = true;
-       }
+       gpio_set_value_cansleep(data->gpio, data->enable_high);
+       data->is_enabled = true;
 
        return 0;
 }
@@ -117,10 +115,8 @@ static int fixed_voltage_disable(struct regulator_dev *dev)
 {
        struct fixed_voltage_data *data = rdev_get_drvdata(dev);
 
-       if (gpio_is_valid(data->gpio)) {
-               gpio_set_value_cansleep(data->gpio, !data->enable_high);
-               data->is_enabled = false;
-       }
+       gpio_set_value_cansleep(data->gpio, !data->enable_high);
+       data->is_enabled = false;
 
        return 0;
 }
@@ -153,7 +149,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
        return data->microvolts;
 }
 
-static struct regulator_ops fixed_voltage_ops = {
+static struct regulator_ops fixed_voltage_gpio_ops = {
        .is_enabled = fixed_voltage_is_enabled,
        .enable = fixed_voltage_enable,
        .disable = fixed_voltage_disable,
@@ -162,10 +158,16 @@ static struct regulator_ops fixed_voltage_ops = {
        .list_voltage = fixed_voltage_list_voltage,
 };
 
+static struct regulator_ops fixed_voltage_ops = {
+       .get_voltage = fixed_voltage_get_voltage,
+       .list_voltage = fixed_voltage_list_voltage,
+};
+
 static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
 {
        struct fixed_voltage_config *config;
        struct fixed_voltage_data *drvdata;
+       struct regulator_config cfg = { };
        int ret;
 
        if (pdev->dev.of_node)
@@ -176,7 +178,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
        if (!config)
                return -ENOMEM;
 
-       drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
+       drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
+                              GFP_KERNEL);
        if (drvdata == NULL) {
                dev_err(&pdev->dev, "Failed to allocate device data\n");
                ret = -ENOMEM;
@@ -191,7 +194,6 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
        }
        drvdata->desc.type = REGULATOR_VOLTAGE;
        drvdata->desc.owner = THIS_MODULE;
-       drvdata->desc.ops = &fixed_voltage_ops;
 
        if (config->microvolts)
                drvdata->desc.n_voltages = 1;
@@ -201,6 +203,7 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
        drvdata->startup_delay = config->startup_delay;
 
        if (gpio_is_valid(config->gpio)) {
+               int gpio_flag;
                drvdata->enable_high = config->enable_high;
 
                /* FIXME: Remove below print warning
@@ -218,39 +221,39 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
                        dev_warn(&pdev->dev,
                                "using GPIO 0 for regulator enable control\n");
 
-               ret = gpio_request(config->gpio, config->supply_name);
-               if (ret) {
-                       dev_err(&pdev->dev,
-                          "Could not obtain regulator enable GPIO %d: %d\n",
-                                                       config->gpio, ret);
-                       goto err_name;
-               }
-
-               /* set output direction without changing state
+               /*
+                * set output direction without changing state
                 * to prevent glitch
                 */
                drvdata->is_enabled = config->enabled_at_boot;
                ret = drvdata->is_enabled ?
                                config->enable_high : !config->enable_high;
+               gpio_flag = ret ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+
+               if (config->gpio_is_open_drain)
+                       gpio_flag |= GPIOF_OPEN_DRAIN;
 
-               ret = gpio_direction_output(config->gpio, ret);
+               ret = gpio_request_one(config->gpio, gpio_flag,
+                                               config->supply_name);
                if (ret) {
                        dev_err(&pdev->dev,
-                          "Could not configure regulator enable GPIO %d direction: %d\n",
+                          "Could not obtain regulator enable GPIO %d: %d\n",
                                                        config->gpio, ret);
-                       goto err_gpio;
+                       goto err_name;
                }
 
+               drvdata->desc.ops = &fixed_voltage_gpio_ops;
+
        } else {
-               /* Regulator without GPIO control is considered
-                * always enabled
-                */
-               drvdata->is_enabled = true;
+               drvdata->desc.ops = &fixed_voltage_ops;
        }
 
-       drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
-                                         config->init_data, drvdata,
-                                         pdev->dev.of_node);
+       cfg.dev = &pdev->dev;
+       cfg.init_data = config->init_data;
+       cfg.driver_data = drvdata;
+       cfg.of_node = pdev->dev.of_node;
+
+       drvdata->dev = regulator_register(&drvdata->desc, &cfg);
        if (IS_ERR(drvdata->dev)) {
                ret = PTR_ERR(drvdata->dev);
                dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
@@ -270,7 +273,6 @@ err_gpio:
 err_name:
        kfree(drvdata->desc.name);
 err:
-       kfree(drvdata);
        return ret;
 }
 
@@ -282,7 +284,6 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
        if (gpio_is_valid(drvdata->gpio))
                gpio_free(drvdata->gpio);
        kfree(drvdata->desc.name);
-       kfree(drvdata);
 
        return 0;
 }
index 42e1cb1835e54e9534ced30aa7aaf49f2897bf38..f93b06b1e7ec8b129962a14722695e5b21a43840 100644 (file)
@@ -105,15 +105,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev,
                                        int min, int max)
 {
        struct gpio_regulator_data *data = rdev_get_drvdata(dev);
-       int ptr, target, state;
+       int ptr, target, state, best_val = INT_MAX;
 
-       target = -1;
        for (ptr = 0; ptr < data->nr_states; ptr++)
-               if (data->states[ptr].value >= min &&
+               if (data->states[ptr].value < best_val &&
+                   data->states[ptr].value >= min &&
                    data->states[ptr].value <= max)
                        target = data->states[ptr].gpios;
 
-       if (target < 0)
+       if (best_val == INT_MAX)
                return -EINVAL;
 
        for (ptr = 0; ptr < data->nr_gpios; ptr++) {
@@ -172,9 +172,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
 {
        struct gpio_regulator_config *config = pdev->dev.platform_data;
        struct gpio_regulator_data *drvdata;
+       struct regulator_config cfg = { };
        int ptr, ret, state;
 
-       drvdata = kzalloc(sizeof(struct gpio_regulator_data), GFP_KERNEL);
+       drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
+                              GFP_KERNEL);
        if (drvdata == NULL) {
                dev_err(&pdev->dev, "Failed to allocate device data\n");
                return -ENOMEM;
@@ -283,8 +285,11 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev)
        }
        drvdata->state = state;
 
-       drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
-                                         config->init_data, drvdata, NULL);
+       cfg.dev = &pdev->dev;
+       cfg.init_data = config->init_data;
+       cfg.driver_data = &drvdata;
+
+       drvdata->dev = regulator_register(&drvdata->desc, &cfg);
        if (IS_ERR(drvdata->dev)) {
                ret = PTR_ERR(drvdata->dev);
                dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
@@ -307,7 +312,6 @@ err_memgpio:
 err_name:
        kfree(drvdata->desc.name);
 err:
-       kfree(drvdata);
        return ret;
 }
 
@@ -326,7 +330,6 @@ static int __devexit gpio_regulator_remove(struct platform_device *pdev)
                gpio_free(drvdata->enable_gpio);
 
        kfree(drvdata->desc.name);
-       kfree(drvdata);
 
        return 0;
 }
index 775f5fd208c375e87690f6fb48b7bb38893e566f..60044c362eb5003e92d84fe638b4d5a292c1b0a4 100644 (file)
@@ -112,7 +112,7 @@ static struct regulator_ops isl_fixed_ops = {
        .list_voltage   = isl6271a_list_fixed_voltage,
 };
 
-static struct regulator_desc isl_rd[] = {
+static const struct regulator_desc isl_rd[] = {
        {
                .name           = "Core Buck",
                .id             = 0,
@@ -140,6 +140,7 @@ static struct regulator_desc isl_rd[] = {
 static int __devinit isl6271a_probe(struct i2c_client *i2c,
                                     const struct i2c_device_id *id)
 {
+       struct regulator_config config = { };
        struct regulator_init_data *init_data   = i2c->dev.platform_data;
        struct isl_pmic *pmic;
        int err, i;
@@ -147,12 +148,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
        if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -EIO;
 
-       if (!init_data) {
-               dev_err(&i2c->dev, "no platform data supplied\n");
-               return -EIO;
-       }
-
-       pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL);
+       pmic = devm_kzalloc(&i2c->dev, sizeof(struct isl_pmic), GFP_KERNEL);
        if (!pmic)
                return -ENOMEM;
 
@@ -161,8 +157,14 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
        mutex_init(&pmic->mtx);
 
        for (i = 0; i < 3; i++) {
-               pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
-                                               init_data, pmic, NULL);
+               config.dev = &i2c->dev;
+               if (i == 0)
+                       config.init_data = init_data;
+               else
+                       config.init_data = 0;
+               config.driver_data = pmic;
+
+               pmic->rdev[i] = regulator_register(&isl_rd[i], &config);
                if (IS_ERR(pmic->rdev[i])) {
                        dev_err(&i2c->dev, "failed to register %s\n", id->name);
                        err = PTR_ERR(pmic->rdev[i]);
@@ -177,8 +179,6 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
 error:
        while (--i >= 0)
                regulator_unregister(pmic->rdev[i]);
-
-       kfree(pmic);
        return err;
 }
 
@@ -189,9 +189,6 @@ static int __devexit isl6271a_remove(struct i2c_client *i2c)
 
        for (i = 0; i < 3; i++)
                regulator_unregister(pmic->rdev[i]);
-
-       kfree(pmic);
-
        return 0;
 }
 
index 0cfabd318a59faa015b21226ebe9417f91ac7f12..981bea9cb9d7d9c55a2f6e821523c695f35bf83c 100644 (file)
@@ -124,6 +124,10 @@ static const int *ldo_voltage_map[] = {
 static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
 {
        int ldo = rdev_get_id(dev) - LP3971_LDO1;
+
+       if (index > LDO_VOL_MAX_IDX)
+               return -EINVAL;
+
        return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
 }
 
@@ -168,32 +172,15 @@ static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
        return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
 }
 
-static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
-                                 int min_uV, int max_uV,
-                                 unsigned int *selector)
+static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev,
+                                     unsigned int selector)
 {
        struct lp3971 *lp3971 = rdev_get_drvdata(dev);
        int ldo = rdev_get_id(dev) - LP3971_LDO1;
-       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
-       const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
-       u16 val;
-
-       if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
-           min_vol > vol_map[LDO_VOL_MAX_IDX])
-               return -EINVAL;
-
-       for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
-               if (vol_map[val] >= min_vol)
-                       break;
-
-       if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol)
-               return -EINVAL;
-
-       *selector = val;
 
        return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
                        LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo),
-                       val << LDO_VOL_CONTR_SHIFT(ldo));
+                       selector << LDO_VOL_CONTR_SHIFT(ldo));
 }
 
 static struct regulator_ops lp3971_ldo_ops = {
@@ -202,11 +189,14 @@ static struct regulator_ops lp3971_ldo_ops = {
        .enable = lp3971_ldo_enable,
        .disable = lp3971_ldo_disable,
        .get_voltage = lp3971_ldo_get_voltage,
-       .set_voltage = lp3971_ldo_set_voltage,
+       .set_voltage_sel = lp3971_ldo_set_voltage_sel,
 };
 
 static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
 {
+       if (index < BUCK_TARGET_VOL_MIN_IDX || index > BUCK_TARGET_VOL_MAX_IDX)
+               return -EINVAL;
+
        return 1000 * buck_voltage_map[index];
 }
 
@@ -259,33 +249,15 @@ static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
        return val;
 }
 
-static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
-                                  int min_uV, int max_uV,
-                                  unsigned int *selector)
+static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev,
+                                      unsigned int selector)
 {
        struct lp3971 *lp3971 = rdev_get_drvdata(dev);
        int buck = rdev_get_id(dev) - LP3971_DCDC1;
-       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
-       const int *vol_map = buck_voltage_map;
-       u16 val;
        int ret;
 
-       if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
-           min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
-               return -EINVAL;
-
-       for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
-            val++)
-               if (vol_map[val] >= min_vol)
-                       break;
-
-       if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol)
-               return -EINVAL;
-
-       *selector = val;
-
        ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
-              BUCK_TARGET_VOL_MASK, val);
+              BUCK_TARGET_VOL_MASK, selector);
        if (ret)
                return ret;
 
@@ -306,10 +278,10 @@ static struct regulator_ops lp3971_dcdc_ops = {
        .enable = lp3971_dcdc_enable,
        .disable = lp3971_dcdc_disable,
        .get_voltage = lp3971_dcdc_get_voltage,
-       .set_voltage = lp3971_dcdc_set_voltage,
+       .set_voltage_sel = lp3971_dcdc_set_voltage_sel,
 };
 
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
        {
                .name = "LDO1",
                .id = LP3971_LDO1,
@@ -449,10 +421,15 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
 
        /* Instantiate the regulators */
        for (i = 0; i < pdata->num_regulators; i++) {
+               struct regulator_config config = { };
                struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
-               lp3971->rdev[i] = regulator_register(&regulators[reg->id],
-                               lp3971->dev, reg->initdata, lp3971, NULL);
 
+               config.dev = lp3971->dev;
+               config.init_data = reg->initdata;
+               config.driver_data = lp3971;
+
+               lp3971->rdev[i] = regulator_register(&regulators[reg->id],
+                                                    &config);
                if (IS_ERR(lp3971->rdev[i])) {
                        err = PTR_ERR(lp3971->rdev[i]);
                        dev_err(lp3971->dev, "regulator init failed: %d\n",
@@ -545,23 +522,7 @@ static struct i2c_driver lp3971_i2c_driver = {
        .id_table = lp3971_i2c_id,
 };
 
-static int __init lp3971_module_init(void)
-{
-       int ret;
-
-       ret = i2c_add_driver(&lp3971_i2c_driver);
-       if (ret != 0)
-               pr_err("Failed to register I2C driver: %d\n", ret);
-
-       return ret;
-}
-module_init(lp3971_module_init);
-
-static void __exit lp3971_module_exit(void)
-{
-       i2c_del_driver(&lp3971_i2c_driver);
-}
-module_exit(lp3971_module_exit);
+module_i2c_driver(lp3971_i2c_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
index 49a15eefe5fe25390bdaf52cd0455675565cb516..de073df7d3449a69d0a991c27c95f23f6b0285e3 100644 (file)
@@ -245,6 +245,11 @@ static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val)
 static int lp3972_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
 {
        int ldo = rdev_get_id(dev) - LP3972_LDO1;
+
+       if (index < LP3972_LDO_VOL_MIN_IDX(ldo) ||
+           index > LP3972_LDO_VOL_MAX_IDX(ldo))
+               return -EINVAL;
+
        return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[index];
 }
 
@@ -292,34 +297,16 @@ static int lp3972_ldo_get_voltage(struct regulator_dev *dev)
        return 1000 * LP3972_LDO_VOL_VALUE_MAP(ldo)[val];
 }
 
-static int lp3972_ldo_set_voltage(struct regulator_dev *dev,
-                                 int min_uV, int max_uV,
-                                 unsigned int *selector)
+static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
+                                     unsigned int selector)
 {
        struct lp3972 *lp3972 = rdev_get_drvdata(dev);
        int ldo = rdev_get_id(dev) - LP3972_LDO1;
-       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
-       const int *vol_map = LP3972_LDO_VOL_VALUE_MAP(ldo);
-       u16 val;
        int shift, ret;
 
-       if (min_vol < vol_map[LP3972_LDO_VOL_MIN_IDX(ldo)] ||
-           min_vol > vol_map[LP3972_LDO_VOL_MAX_IDX(ldo)])
-               return -EINVAL;
-
-       for (val = LP3972_LDO_VOL_MIN_IDX(ldo);
-               val <= LP3972_LDO_VOL_MAX_IDX(ldo); val++)
-               if (vol_map[val] >= min_vol)
-                       break;
-
-       if (val > LP3972_LDO_VOL_MAX_IDX(ldo) || vol_map[val] > max_vol)
-               return -EINVAL;
-
-       *selector = val;
-
        shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo);
        ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo),
-               LP3972_LDO_VOL_MASK(ldo) << shift, val << shift);
+               LP3972_LDO_VOL_MASK(ldo) << shift, selector << shift);
 
        if (ret)
                return ret;
@@ -355,12 +342,17 @@ static struct regulator_ops lp3972_ldo_ops = {
        .enable = lp3972_ldo_enable,
        .disable = lp3972_ldo_disable,
        .get_voltage = lp3972_ldo_get_voltage,
-       .set_voltage = lp3972_ldo_set_voltage,
+       .set_voltage_sel = lp3972_ldo_set_voltage_sel,
 };
 
 static int lp3972_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
 {
        int buck = rdev_get_id(dev) - LP3972_DCDC1;
+
+       if (index < LP3972_BUCK_VOL_MIN_IDX(buck) ||
+           index > LP3972_BUCK_VOL_MAX_IDX(buck))
+               return -EINVAL;
+
        return 1000 * buck_voltage_map[buck][index];
 }
 
@@ -419,34 +411,15 @@ static int lp3972_dcdc_get_voltage(struct regulator_dev *dev)
        return val;
 }
 
-static int lp3972_dcdc_set_voltage(struct regulator_dev *dev,
-                                  int min_uV, int max_uV,
-                                  unsigned int *selector)
+static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
+                                      unsigned int selector)
 {
        struct lp3972 *lp3972 = rdev_get_drvdata(dev);
        int buck = rdev_get_id(dev) - LP3972_DCDC1;
-       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
-       const int *vol_map = buck_voltage_map[buck];
-       u16 val;
        int ret;
 
-       if (min_vol < vol_map[LP3972_BUCK_VOL_MIN_IDX(buck)] ||
-           min_vol > vol_map[LP3972_BUCK_VOL_MAX_IDX(buck)])
-               return -EINVAL;
-
-       for (val = LP3972_BUCK_VOL_MIN_IDX(buck);
-               val <= LP3972_BUCK_VOL_MAX_IDX(buck); val++)
-               if (vol_map[val] >= min_vol)
-                       break;
-
-       if (val > LP3972_BUCK_VOL_MAX_IDX(buck) ||
-           vol_map[val] > max_vol)
-               return -EINVAL;
-
-       *selector = val;
-
        ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck),
-                               LP3972_BUCK_VOL_MASK, val);
+                               LP3972_BUCK_VOL_MASK, selector);
        if (ret)
                return ret;
 
@@ -468,10 +441,10 @@ static struct regulator_ops lp3972_dcdc_ops = {
        .enable = lp3972_dcdc_enable,
        .disable = lp3972_dcdc_disable,
        .get_voltage = lp3972_dcdc_get_voltage,
-       .set_voltage = lp3972_dcdc_set_voltage,
+       .set_voltage_sel = lp3972_dcdc_set_voltage_sel,
 };
 
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
        {
                .name = "LDO1",
                .id = LP3972_LDO1,
@@ -554,9 +527,14 @@ static int __devinit setup_regulators(struct lp3972 *lp3972,
        /* Instantiate the regulators */
        for (i = 0; i < pdata->num_regulators; i++) {
                struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
-               lp3972->rdev[i] = regulator_register(&regulators[reg->id],
-                               lp3972->dev, reg->initdata, lp3972, NULL);
+               struct regulator_config config = { };
 
+               config.dev = lp3972->dev;
+               config.init_data = reg->initdata;
+               config.driver_data = lp3972;
+
+               lp3972->rdev[i] = regulator_register(&regulators[reg->id],
+                                                    &config);
                if (IS_ERR(lp3972->rdev[i])) {
                        err = PTR_ERR(lp3972->rdev[i]);
                        dev_err(lp3972->dev, "regulator init failed: %d\n",
index 282d2ee0604eb89eb16ea2b56e97bff02f50c76c..b9444ee08da9d27af4ec3d9e632e21b75eefa394 100644 (file)
@@ -161,7 +161,7 @@ static struct regulator_ops max1586_v6_ops = {
        .list_voltage = max1586_v6_list,
 };
 
-static struct regulator_desc max1586_reg[] = {
+static const struct regulator_desc max1586_reg[] = {
        {
                .name = "Output_V3",
                .id = MAX1586_V3,
@@ -185,21 +185,21 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
 {
        struct regulator_dev **rdev;
        struct max1586_platform_data *pdata = client->dev.platform_data;
+       struct regulator_config config = { };
        struct max1586_data *max1586;
        int i, id, ret = -ENOMEM;
 
-       max1586 = kzalloc(sizeof(struct max1586_data) +
+       max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) +
                        sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
                        GFP_KERNEL);
        if (!max1586)
-               goto out;
+               return -ENOMEM;
 
        max1586->client = client;
 
-       if (!pdata->v3_gain) {
-               ret = -EINVAL;
-               goto out_unmap;
-       }
+       if (!pdata->v3_gain)
+               return -EINVAL;
+
        max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
        max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
 
@@ -212,9 +212,12 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
                        dev_err(&client->dev, "invalid regulator id %d\n", id);
                        goto err;
                }
-               rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
-                                            pdata->subdevs[i].platform_data,
-                                            max1586, NULL);
+
+               config.dev = &client->dev;
+               config.init_data = pdata->subdevs[i].platform_data;
+               config.driver_data = max1586;
+
+               rdev[i] = regulator_register(&max1586_reg[id], &config);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(&client->dev, "failed to register %s\n",
@@ -230,9 +233,6 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
 err:
        while (--i >= 0)
                regulator_unregister(rdev[i]);
-out_unmap:
-       kfree(max1586);
-out:
        return ret;
 }
 
@@ -244,8 +244,6 @@ static int __devexit max1586_pmic_remove(struct i2c_client *client)
        for (i = 0; i <= MAX1586_V6; i++)
                if (max1586->rdev[i])
                        regulator_unregister(max1586->rdev[i]);
-       kfree(max1586);
-
        return 0;
 }
 
index 824c650436edec5c8d3e39fb6d0d3ffcd0233b28..4ce72081c2e3e493d7ef36e1efb71422970b5915 100644 (file)
@@ -207,7 +207,7 @@ static struct regulator_ops max8649_dcdc_ops = {
 
 };
 
-static struct regulator_desc dcdc_desc = {
+static const struct regulator_desc dcdc_desc = {
        .name           = "max8649",
        .ops            = &max8649_dcdc_ops,
        .type           = REGULATOR_VOLTAGE,
@@ -225,21 +225,23 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
 {
        struct max8649_platform_data *pdata = client->dev.platform_data;
        struct max8649_regulator_info *info = NULL;
+       struct regulator_config config = { };
        unsigned int val;
        unsigned char data;
        int ret;
 
-       info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL);
+       info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info),
+                           GFP_KERNEL);
        if (!info) {
                dev_err(&client->dev, "No enough memory\n");
                return -ENOMEM;
        }
 
-       info->regmap = regmap_init_i2c(client, &max8649_regmap_config);
+       info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config);
        if (IS_ERR(info->regmap)) {
                ret = PTR_ERR(info->regmap);
                dev_err(&client->dev, "Failed to allocate register map: %d\n", ret);
-               goto fail;
+               return ret;
        }
 
        info->dev = &client->dev;
@@ -267,7 +269,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
        if (ret != 0) {
                dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
                        ret);
-               goto out;
+               return ret;
        }
        dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val);
 
@@ -297,22 +299,18 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
                                   MAX8649_RAMP_DOWN);
        }
 
-       info->regulator = regulator_register(&dcdc_desc, &client->dev,
-                                            pdata->regulator, info, NULL);
+       config.dev = &client->dev;
+       config.init_data = pdata->regulator;
+       config.driver_data = info;
+
+       info->regulator = regulator_register(&dcdc_desc, &config);
        if (IS_ERR(info->regulator)) {
                dev_err(info->dev, "failed to register regulator %s\n",
                        dcdc_desc.name);
-               ret = PTR_ERR(info->regulator);
-               goto out;
+               return PTR_ERR(info->regulator);
        }
 
-       dev_info(info->dev, "Max8649 regulator device is detected.\n");
        return 0;
-out:
-       regmap_exit(info->regmap);
-fail:
-       kfree(info);
-       return ret;
 }
 
 static int __devexit max8649_regulator_remove(struct i2c_client *client)
@@ -322,8 +320,6 @@ static int __devexit max8649_regulator_remove(struct i2c_client *client)
        if (info) {
                if (info->regulator)
                        regulator_unregister(info->regulator);
-               regmap_exit(info->regmap);
-               kfree(info);
        }
 
        return 0;
index 4c5b05311f47e02b646f5a87d239bd7b9839c6f6..9997cfbc34711022f55c2ceeefff750ccd085a44 100644 (file)
@@ -313,7 +313,7 @@ static struct regulator_ops max8660_ldo67_ops = {
        .set_voltage = max8660_ldo67_set,
 };
 
-static struct regulator_desc max8660_reg[] = {
+static const struct regulator_desc max8660_reg[] = {
        {
                .name = "V3(DCDC)",
                .id = MAX8660_V3,
@@ -361,21 +361,20 @@ static int __devinit max8660_probe(struct i2c_client *client,
 {
        struct regulator_dev **rdev;
        struct max8660_platform_data *pdata = client->dev.platform_data;
+       struct regulator_config config = { };
        struct max8660 *max8660;
        int boot_on, i, id, ret = -EINVAL;
 
        if (pdata->num_subdevs > MAX8660_V_END) {
                dev_err(&client->dev, "Too many regulators found!\n");
-               goto out;
+               return -EINVAL;
        }
 
        max8660 = kzalloc(sizeof(struct max8660) +
                        sizeof(struct regulator_dev *) * MAX8660_V_END,
                        GFP_KERNEL);
-       if (!max8660) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!max8660)
+               return -ENOMEM;
 
        max8660->client = client;
        rdev = max8660->rdev;
@@ -404,7 +403,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
        for (i = 0; i < pdata->num_subdevs; i++) {
 
                if (!pdata->subdevs[i].platform_data)
-                       goto err_free;
+                       goto err_out;
 
                boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
 
@@ -430,7 +429,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
                case MAX8660_V7:
                        if (!strcmp(i2c_id->name, "max8661")) {
                                dev_err(&client->dev, "Regulator not on this chip!\n");
-                               goto err_free;
+                               goto err_out;
                        }
 
                        if (boot_on)
@@ -440,7 +439,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
                default:
                        dev_err(&client->dev, "invalid regulator %s\n",
                                 pdata->subdevs[i].name);
-                       goto err_free;
+                       goto err_out;
                }
        }
 
@@ -449,9 +448,11 @@ static int __devinit max8660_probe(struct i2c_client *client,
 
                id = pdata->subdevs[i].id;
 
-               rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
-                                            pdata->subdevs[i].platform_data,
-                                            max8660, NULL);
+               config.dev = &client->dev;
+               config.init_data = pdata->subdevs[i].platform_data;
+               config.driver_data = max8660;
+
+               rdev[i] = regulator_register(&max8660_reg[id], &config);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(&client->dev, "failed to register %s\n",
@@ -461,15 +462,12 @@ static int __devinit max8660_probe(struct i2c_client *client,
        }
 
        i2c_set_clientdata(client, max8660);
-       dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
        return 0;
 
 err_unregister:
        while (--i >= 0)
                regulator_unregister(rdev[i]);
-err_free:
-       kfree(max8660);
-out:
+err_out:
        return ret;
 }
 
@@ -481,8 +479,6 @@ static int __devexit max8660_remove(struct i2c_client *client)
        for (i = 0; i < MAX8660_V_END; i++)
                if (max8660->rdev[i])
                        regulator_unregister(max8660->rdev[i]);
-       kfree(max8660);
-
        return 0;
 }
 
index 2f242f43096e4788368683157e1edbbf268a6270..de30ea2b80f5b626299b58d957f048b95d48a78f 100644 (file)
@@ -42,8 +42,6 @@ struct max8925_regulator_info {
        int     max_uV;
        int     step_uV;
        int     vol_reg;
-       int     vol_shift;
-       int     vol_nbits;
        int     enable_reg;
 };
 
@@ -75,8 +73,7 @@ static int max8925_set_voltage(struct regulator_dev *rdev,
        }
        data = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV);
        *selector = data;
-       data <<= info->vol_shift;
-       mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+       mask = rdev->desc->n_voltages - 1;
 
        return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
 }
@@ -90,8 +87,8 @@ static int max8925_get_voltage(struct regulator_dev *rdev)
        ret = max8925_reg_read(info->i2c, info->vol_reg);
        if (ret < 0)
                return ret;
-       mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
-       data = (ret & mask) >> info->vol_shift;
+       mask = rdev->desc->n_voltages - 1;
+       data = ret & mask;
 
        return max8925_list_voltage(rdev, data);
 }
@@ -163,6 +160,7 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev)
 }
 
 static struct regulator_ops max8925_regulator_sdv_ops = {
+       .list_voltage           = max8925_list_voltage,
        .set_voltage            = max8925_set_voltage,
        .get_voltage            = max8925_get_voltage,
        .enable                 = max8925_enable,
@@ -174,6 +172,7 @@ static struct regulator_ops max8925_regulator_sdv_ops = {
 };
 
 static struct regulator_ops max8925_regulator_ldo_ops = {
+       .list_voltage           = max8925_list_voltage,
        .set_voltage            = max8925_set_voltage,
        .get_voltage            = max8925_get_voltage,
        .enable                 = max8925_enable,
@@ -189,13 +188,12 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
                .type   = REGULATOR_VOLTAGE,                    \
                .id     = MAX8925_ID_SD##_id,                   \
                .owner  = THIS_MODULE,                          \
+               .n_voltages = 64,                               \
        },                                                      \
        .min_uV         = min * 1000,                           \
        .max_uV         = max * 1000,                           \
        .step_uV        = step * 1000,                          \
        .vol_reg        = MAX8925_SDV##_id,                     \
-       .vol_shift      = 0,                                    \
-       .vol_nbits      = 6,                                    \
        .enable_reg     = MAX8925_SDCTL##_id,                   \
 }
 
@@ -207,13 +205,12 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
                .type   = REGULATOR_VOLTAGE,                    \
                .id     = MAX8925_ID_LDO##_id,                  \
                .owner  = THIS_MODULE,                          \
+               .n_voltages = 64,                               \
        },                                                      \
        .min_uV         = min * 1000,                           \
        .max_uV         = max * 1000,                           \
        .step_uV        = step * 1000,                          \
        .vol_reg        = MAX8925_LDOVOUT##_id,                 \
-       .vol_shift      = 0,                                    \
-       .vol_nbits      = 6,                                    \
        .enable_reg     = MAX8925_LDOCTL##_id,                  \
 }
 
@@ -261,6 +258,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
 {
        struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
        struct max8925_platform_data *pdata = chip->dev->platform_data;
+       struct regulator_config config = { };
        struct max8925_regulator_info *ri;
        struct regulator_dev *rdev;
 
@@ -272,8 +270,11 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
        ri->i2c = chip->i2c;
        ri->chip = chip;
 
-       rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdata->regulator[pdev->id], ri, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdata->regulator[pdev->id];
+       config.driver_data = ri;
+
+       rdev = regulator_register(&ri->desc, &config);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
index 75d89400c1234db391556ec14e0ced14775580ac..c0ab4ddc10236364fd752d927a146bb2a971ef5d 100644 (file)
@@ -130,11 +130,10 @@ static int max8952_get_voltage(struct regulator_dev *rdev)
        return max8952_voltage(max8952, vid);
 }
 
-static int max8952_set_voltage(struct regulator_dev *rdev,
-                              int min_uV, int max_uV, unsigned *selector)
+static int max8952_set_voltage_sel(struct regulator_dev *rdev,
+                                  unsigned selector)
 {
        struct max8952_data *max8952 = rdev_get_drvdata(rdev);
-       s8 vid = -1, i;
 
        if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
                        !gpio_is_valid(max8952->pdata->gpio_vid1)) {
@@ -142,23 +141,10 @@ static int max8952_set_voltage(struct regulator_dev *rdev,
                return -EPERM;
        }
 
-       for (i = 0; i < MAX8952_NUM_DVS_MODE; i++) {
-               int volt = max8952_voltage(max8952, i);
-
-               /* Set the voltage as low as possible within the range */
-               if (volt <= max_uV && volt >= min_uV)
-                       if (vid == -1 || max8952_voltage(max8952, vid) > volt)
-                               vid = i;
-       }
-
-       if (vid >= 0 && vid < MAX8952_NUM_DVS_MODE) {
-               max8952->vid0 = (vid % 2 == 1);
-               max8952->vid1 = (((vid >> 1) % 2) == 1);
-               *selector = vid;
-               gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
-               gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
-       } else
-               return -EINVAL;
+       max8952->vid0 = selector & 0x1;
+       max8952->vid1 = (selector >> 1) & 0x1;
+       gpio_set_value(max8952->pdata->gpio_vid0, max8952->vid0);
+       gpio_set_value(max8952->pdata->gpio_vid1, max8952->vid1);
 
        return 0;
 }
@@ -169,11 +155,11 @@ static struct regulator_ops max8952_ops = {
        .enable                 = max8952_enable,
        .disable                = max8952_disable,
        .get_voltage            = max8952_get_voltage,
-       .set_voltage            = max8952_set_voltage,
+       .set_voltage_sel        = max8952_set_voltage_sel,
        .set_suspend_disable    = max8952_disable,
 };
 
-static struct regulator_desc regulator = {
+static const struct regulator_desc regulator = {
        .name           = "MAX8952_VOUT",
        .id             = 0,
        .n_voltages     = MAX8952_NUM_DVS_MODE,
@@ -187,6 +173,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
 {
        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
        struct max8952_platform_data *pdata = client->dev.platform_data;
+       struct regulator_config config = { };
        struct max8952_data *max8952;
 
        int ret = 0, err = 0;
@@ -207,8 +194,11 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
        max8952->dev = &client->dev;
        max8952->pdata = pdata;
 
-       max8952->rdev = regulator_register(&regulator, max8952->dev,
-                       &pdata->reg_data, max8952, NULL);
+       config.dev = max8952->dev;
+       config.init_data = &pdata->reg_data;
+       config.driver_data = max8952;
+
+       max8952->rdev = regulator_register(&regulator, &config);
 
        if (IS_ERR(max8952->rdev)) {
                ret = PTR_ERR(max8952->rdev);
@@ -217,8 +207,8 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
        }
 
        max8952->en = !!(pdata->reg_data.constraints.boot_on);
-       max8952->vid0 = (pdata->default_mode % 2) == 1;
-       max8952->vid1 = ((pdata->default_mode >> 1) % 2) == 1;
+       max8952->vid0 = pdata->default_mode & 0x1;
+       max8952->vid1 = (pdata->default_mode >> 1) & 0x1;
 
        if (gpio_is_valid(pdata->gpio_en)) {
                if (!gpio_request(pdata->gpio_en, "MAX8952 EN"))
@@ -241,13 +231,13 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
                        gpio_is_valid(pdata->gpio_vid1)) {
                if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0"))
                        gpio_direction_output(pdata->gpio_vid0,
-                                       (pdata->default_mode) % 2);
+                                       (pdata->default_mode) & 0x1);
                else
                        err = 1;
 
                if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1"))
                        gpio_direction_output(pdata->gpio_vid1,
-                               (pdata->default_mode >> 1) % 2);
+                               (pdata->default_mode >> 1) & 0x1);
                else {
                        if (!err)
                                gpio_free(pdata->gpio_vid0);
index 96579296f04d91aaf2859288f6e34ae806e901e4..db09244bb3edb2305d8765cffd270ba5f5a00586 100644 (file)
@@ -68,29 +68,28 @@ struct voltage_map_desc {
        int min;
        int max;
        int step;
-       unsigned int n_bits;
 };
 
 /* Voltage maps in mV */
 static const struct voltage_map_desc ldo_voltage_map_desc = {
-       .min = 800,     .max = 3950,    .step = 50,     .n_bits = 6,
+       .min = 800,     .max = 3950,    .step = 50,
 }; /* LDO1 ~ 18, 21 all */
 
 static const struct voltage_map_desc buck1245_voltage_map_desc = {
-       .min = 650,     .max = 2225,    .step = 25,     .n_bits = 6,
+       .min = 650,     .max = 2225,    .step = 25,
 }; /* Buck1, 2, 4, 5 */
 
 static const struct voltage_map_desc buck37_voltage_map_desc = {
-       .min = 750,     .max = 3900,    .step = 50,     .n_bits = 6,
+       .min = 750,     .max = 3900,    .step = 50,
 }; /* Buck3, 7 */
 
 /* current map in mA */
 static const struct voltage_map_desc charger_current_map_desc = {
-       .min = 200,     .max = 950,     .step = 50,     .n_bits = 4,
+       .min = 200,     .max = 950,     .step = 50,
 };
 
 static const struct voltage_map_desc topoff_current_map_desc = {
-       .min = 50,      .max = 200,     .step = 10,     .n_bits = 4,
+       .min = 50,      .max = 200,     .step = 10,
 };
 
 static const struct voltage_map_desc *reg_voltage_map[] = {
@@ -320,6 +319,7 @@ static int max8997_reg_disable(struct regulator_dev *rdev)
 static int max8997_get_voltage_register(struct regulator_dev *rdev,
                int *_reg, int *_shift, int *_mask)
 {
+       struct max8997_data *max8997 = rdev_get_drvdata(rdev);
        int rid = rdev_get_id(rdev);
        int reg, shift = 0, mask = 0x3f;
 
@@ -329,9 +329,13 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
                break;
        case MAX8997_BUCK1:
                reg = MAX8997_REG_BUCK1DVS1;
+               if (max8997->buck1_gpiodvs)
+                       reg += max8997->buck125_gpioindex;
                break;
        case MAX8997_BUCK2:
                reg = MAX8997_REG_BUCK2DVS1;
+               if (max8997->buck2_gpiodvs)
+                       reg += max8997->buck125_gpioindex;
                break;
        case MAX8997_BUCK3:
                reg = MAX8997_REG_BUCK3DVS;
@@ -341,6 +345,8 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev,
                break;
        case MAX8997_BUCK5:
                reg = MAX8997_REG_BUCK5DVS1;
+               if (max8997->buck5_gpiodvs)
+                       reg += max8997->buck125_gpioindex;
                break;
        case MAX8997_BUCK7:
                reg = MAX8997_REG_BUCK7DVS;
@@ -381,18 +387,12 @@ static int max8997_get_voltage(struct regulator_dev *rdev)
        struct max8997_data *max8997 = rdev_get_drvdata(rdev);
        struct i2c_client *i2c = max8997->iodev->i2c;
        int reg, shift, mask, ret;
-       int rid = rdev_get_id(rdev);
        u8 val;
 
        ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
        if (ret)
                return ret;
 
-       if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) ||
-                       (rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) ||
-                       (rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs))
-               reg += max8997->buck125_gpioindex;
-
        ret = max8997_read_reg(i2c, reg, &val);
        if (ret)
                return ret;
@@ -415,7 +415,7 @@ static inline int max8997_get_voltage_proper_val(
                const struct voltage_map_desc *desc,
                int min_vol, int max_vol)
 {
-       int i = 0;
+       int i;
 
        if (desc == NULL)
                return -EINVAL;
@@ -423,14 +423,12 @@ static inline int max8997_get_voltage_proper_val(
        if (max_vol < desc->min || min_vol > desc->max)
                return -EINVAL;
 
-       while (desc->min + desc->step * i < min_vol &&
-                       desc->min + desc->step * i < desc->max)
-               i++;
+       if (min_vol < desc->min)
+               min_vol = desc->min;
 
-       if (desc->min + desc->step * i > max_vol)
-               return -EINVAL;
+       i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
 
-       if (i >= (1 << desc->n_bits))
+       if (desc->min + desc->step * i > max_vol)
                return -EINVAL;
 
        return i;
@@ -854,109 +852,65 @@ static struct regulator_ops max8997_charger_fixedstate_ops = {
        .set_current_limit      = max8997_set_voltage_ldobuck_wrap,
 };
 
-#define regulator_desc_ldo(num)                {       \
-       .name           = "LDO"#num,            \
-       .id             = MAX8997_LDO##num,     \
-       .ops            = &max8997_ldo_ops,     \
+#define MAX8997_VOLTAGE_REGULATOR(_name, _ops) {\
+       .name           = #_name,               \
+       .id             = MAX8997_##_name,      \
+       .ops            = &_ops,                \
        .type           = REGULATOR_VOLTAGE,    \
        .owner          = THIS_MODULE,          \
 }
-#define regulator_desc_buck(num)               {       \
-       .name           = "BUCK"#num,           \
-       .id             = MAX8997_BUCK##num,    \
-       .ops            = &max8997_buck_ops,    \
-       .type           = REGULATOR_VOLTAGE,    \
+
+#define MAX8997_CURRENT_REGULATOR(_name, _ops) {\
+       .name           = #_name,               \
+       .id             = MAX8997_##_name,      \
+       .ops            = &_ops,                \
+       .type           = REGULATOR_CURRENT,    \
        .owner          = THIS_MODULE,          \
 }
 
 static struct regulator_desc regulators[] = {
-       regulator_desc_ldo(1),
-       regulator_desc_ldo(2),
-       regulator_desc_ldo(3),
-       regulator_desc_ldo(4),
-       regulator_desc_ldo(5),
-       regulator_desc_ldo(6),
-       regulator_desc_ldo(7),
-       regulator_desc_ldo(8),
-       regulator_desc_ldo(9),
-       regulator_desc_ldo(10),
-       regulator_desc_ldo(11),
-       regulator_desc_ldo(12),
-       regulator_desc_ldo(13),
-       regulator_desc_ldo(14),
-       regulator_desc_ldo(15),
-       regulator_desc_ldo(16),
-       regulator_desc_ldo(17),
-       regulator_desc_ldo(18),
-       regulator_desc_ldo(21),
-       regulator_desc_buck(1),
-       regulator_desc_buck(2),
-       regulator_desc_buck(3),
-       regulator_desc_buck(4),
-       regulator_desc_buck(5),
-       {
-               .name   = "BUCK6",
-               .id     = MAX8997_BUCK6,
-               .ops    = &max8997_fixedvolt_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner  = THIS_MODULE,
-       },
-       regulator_desc_buck(7),
-       {
-               .name   = "EN32KHz_AP",
-               .id     = MAX8997_EN32KHZ_AP,
-               .ops    = &max8997_fixedvolt_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner  = THIS_MODULE,
-       }, {
-               .name   = "EN32KHz_CP",
-               .id     = MAX8997_EN32KHZ_CP,
-               .ops    = &max8997_fixedvolt_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner  = THIS_MODULE,
-       }, {
-               .name   = "ENVICHG",
-               .id     = MAX8997_ENVICHG,
-               .ops    = &max8997_fixedvolt_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner  = THIS_MODULE,
-       }, {
-               .name   = "ESAFEOUT1",
-               .id     = MAX8997_ESAFEOUT1,
-               .ops    = &max8997_safeout_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner   = THIS_MODULE,
-       }, {
-               .name   = "ESAFEOUT2",
-               .id     = MAX8997_ESAFEOUT2,
-               .ops    = &max8997_safeout_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner   = THIS_MODULE,
-       }, {
-               .name   = "CHARGER_CV",
-               .id     = MAX8997_CHARGER_CV,
-               .ops    = &max8997_fixedstate_ops,
-               .type   = REGULATOR_VOLTAGE,
-               .owner   = THIS_MODULE,
-       }, {
-               .name   = "CHARGER",
-               .id     = MAX8997_CHARGER,
-               .ops    = &max8997_charger_ops,
-               .type   = REGULATOR_CURRENT,
-               .owner   = THIS_MODULE,
-       }, {
-               .name   = "CHARGER_TOPOFF",
-               .id     = MAX8997_CHARGER_TOPOFF,
-               .ops    = &max8997_charger_fixedstate_ops,
-               .type   = REGULATOR_CURRENT,
-               .owner   = THIS_MODULE,
-       },
+       MAX8997_VOLTAGE_REGULATOR(LDO1, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO2, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO3, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO4, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO5, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO6, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO7, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO8, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO9, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO10, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO11, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO12, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO13, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO14, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO15, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO16, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO17, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO18, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(LDO21, max8997_ldo_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK1, max8997_buck_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK2, max8997_buck_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK3, max8997_buck_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK4, max8997_buck_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK5, max8997_buck_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK6, max8997_fixedvolt_ops),
+       MAX8997_VOLTAGE_REGULATOR(BUCK7, max8997_buck_ops),
+       MAX8997_VOLTAGE_REGULATOR(EN32KHZ_AP, max8997_fixedvolt_ops),
+       MAX8997_VOLTAGE_REGULATOR(EN32KHZ_CP, max8997_fixedvolt_ops),
+       MAX8997_VOLTAGE_REGULATOR(ENVICHG, max8997_fixedvolt_ops),
+       MAX8997_VOLTAGE_REGULATOR(ESAFEOUT1, max8997_safeout_ops),
+       MAX8997_VOLTAGE_REGULATOR(ESAFEOUT2, max8997_safeout_ops),
+       MAX8997_VOLTAGE_REGULATOR(CHARGER_CV, max8997_fixedstate_ops),
+       MAX8997_CURRENT_REGULATOR(CHARGER, max8997_charger_ops),
+       MAX8997_CURRENT_REGULATOR(CHARGER_TOPOFF,
+                                 max8997_charger_fixedstate_ops),
 };
 
 static __devinit int max8997_pmic_probe(struct platform_device *pdev)
 {
        struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+       struct regulator_config config = { };
        struct regulator_dev **rdev;
        struct max8997_data *max8997;
        struct i2c_client *i2c;
@@ -1140,8 +1094,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
                else if (id == MAX8997_CHARGER_CV)
                        regulators[id].n_voltages = 16;
 
-               rdev[i] = regulator_register(&regulators[id], max8997->dev,
-                               pdata->regulators[i].initdata, max8997, NULL);
+               config.dev = max8997->dev;
+               config.init_data = pdata->regulators[i].initdata;
+               config.driver_data = max8997;
+
+               rdev[i] = regulator_register(&regulators[id], &config);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(max8997->dev, "regulator init failed for %d\n",
index 5890265eeacc092505f66506db187241b52065c3..4ca22f9b52e354680e743ac94555fba8bef47b87 100644 (file)
@@ -277,7 +277,7 @@ static int max8998_get_voltage_register(struct regulator_dev *rdev,
        return 0;
 }
 
-static int max8998_get_voltage(struct regulator_dev *rdev)
+static int max8998_get_voltage_sel(struct regulator_dev *rdev)
 {
        struct max8998_data *max8998 = rdev_get_drvdata(rdev);
        struct i2c_client *i2c = max8998->iodev->i2c;
@@ -295,7 +295,7 @@ static int max8998_get_voltage(struct regulator_dev *rdev)
        val >>= shift;
        val &= mask;
 
-       return max8998_list_voltage(rdev, val);
+       return val;
 }
 
 static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
@@ -306,8 +306,7 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
        int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
        const struct voltage_map_desc *desc;
        int ldo = rdev_get_id(rdev);
-       int reg, shift = 0, mask, ret;
-       int i = 0;
+       int reg, shift = 0, mask, ret, i;
 
        if (ldo >= ARRAY_SIZE(ldo_voltage_map))
                return -EINVAL;
@@ -319,9 +318,10 @@ static int max8998_set_voltage_ldo(struct regulator_dev *rdev,
        if (max_vol < desc->min || min_vol > desc->max)
                return -EINVAL;
 
-       while (desc->min + desc->step*i < min_vol &&
-              desc->min + desc->step*i < desc->max)
-               i++;
+       if (min_vol < desc->min)
+               min_vol = desc->min;
+
+       i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
 
        if (desc->min + desc->step*i > max_vol)
                return -EINVAL;
@@ -359,8 +359,7 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
        const struct voltage_map_desc *desc;
        int buck = rdev_get_id(rdev);
        int reg, shift = 0, mask, ret;
-       int difference = 0, i = 0, j = 0, previous_vol = 0;
-       u8 val = 0;
+       int i, j, previous_sel;
        static u8 buck1_last_val;
 
        if (buck >= ARRAY_SIZE(ldo_voltage_map))
@@ -374,9 +373,10 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
        if (max_vol < desc->min || min_vol > desc->max)
                return -EINVAL;
 
-       while (desc->min + desc->step*i < min_vol &&
-              desc->min + desc->step*i < desc->max)
-               i++;
+       if (min_vol < desc->min)
+               min_vol = desc->min;
+
+       i = DIV_ROUND_UP(min_vol - desc->min, desc->step);
 
        if (desc->min + desc->step*i > max_vol)
                return -EINVAL;
@@ -387,13 +387,14 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev,
        if (ret)
                return ret;
 
-       previous_vol = max8998_get_voltage(rdev);
+       previous_sel = max8998_get_voltage_sel(rdev);
 
        /* Check if voltage needs to be changed */
        /* if previous_voltage equal new voltage, return */
-       if (previous_vol == max8998_list_voltage(rdev, i)) {
+       if (previous_sel == i) {
                dev_dbg(max8998->dev, "No voltage change, old:%d, new:%d\n",
-                       previous_vol, max8998_list_voltage(rdev, i));
+                       max8998_list_voltage(rdev, previous_sel),
+                       max8998_list_voltage(rdev, i));
                return ret;
        }
 
@@ -482,19 +483,40 @@ buck2_exit:
                break;
        }
 
+       return ret;
+}
+
+static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev,
+                                            unsigned int old_selector,
+                                            unsigned int new_selector)
+{
+       struct max8998_data *max8998 = rdev_get_drvdata(rdev);
+       struct i2c_client *i2c = max8998->iodev->i2c;
+       const struct voltage_map_desc *desc;
+       int buck = rdev_get_id(rdev);
+       u8 val = 0;
+       int difference, ret;
+
+       if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4)
+               return -EINVAL;
+
+       desc = ldo_voltage_map[buck];
+
        /* Voltage stabilization */
-       max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
+       ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val);
+       if (ret)
+               return ret;
 
        /* lp3974 hasn't got ENRAMP bit - ramp is assumed as true */
        /* MAX8998 has ENRAMP bit implemented, so test it*/
        if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP))
-               return ret;
+               return 0;
 
-       difference = desc->min + desc->step*i - previous_vol/1000;
+       difference = (new_selector - old_selector) * desc->step;
        if (difference > 0)
-               udelay(difference / ((val & 0x0f) + 1));
+               return difference / ((val & 0x0f) + 1);
 
-       return ret;
+       return 0;
 }
 
 static struct regulator_ops max8998_ldo_ops = {
@@ -502,7 +524,7 @@ static struct regulator_ops max8998_ldo_ops = {
        .is_enabled             = max8998_ldo_is_enabled,
        .enable                 = max8998_ldo_enable,
        .disable                = max8998_ldo_disable,
-       .get_voltage            = max8998_get_voltage,
+       .get_voltage_sel        = max8998_get_voltage_sel,
        .set_voltage            = max8998_set_voltage_ldo,
        .set_suspend_enable     = max8998_ldo_enable,
        .set_suspend_disable    = max8998_ldo_disable,
@@ -513,8 +535,9 @@ static struct regulator_ops max8998_buck_ops = {
        .is_enabled             = max8998_ldo_is_enabled,
        .enable                 = max8998_ldo_enable,
        .disable                = max8998_ldo_disable,
-       .get_voltage            = max8998_get_voltage,
+       .get_voltage_sel        = max8998_get_voltage_sel,
        .set_voltage            = max8998_set_voltage_buck,
+       .set_voltage_time_sel   = max8998_set_voltage_buck_time_sel,
        .set_suspend_enable     = max8998_ldo_enable,
        .set_suspend_disable    = max8998_ldo_disable,
 };
@@ -685,6 +708,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
 {
        struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
+       struct regulator_config config = { };
        struct regulator_dev **rdev;
        struct max8998_data *max8998;
        struct i2c_client *i2c;
@@ -840,8 +864,12 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
                        int count = (desc->max - desc->min) / desc->step + 1;
                        regulators[index].n_voltages = count;
                }
-               rdev[i] = regulator_register(&regulators[index], max8998->dev,
-                               pdata->regulators[i].initdata, max8998, NULL);
+
+               config.dev = max8998->dev;
+               config.init_data = pdata->regulators[i].initdata;
+               config.driver_data = max8998;
+
+               rdev[i] = regulator_register(&regulators[index], &config);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(max8998->dev, "regulator init failed\n");
index 6c0face87ffe834db5d69fb19d85f3e1d4ace9b5..7dcdfa283e9368c8bfa492a2104b516dc363d991 100644 (file)
@@ -340,6 +340,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
        struct mc13xxx_regulator_platform_data *pdata =
                dev_get_platdata(&pdev->dev);
        struct mc13xxx_regulator_init_data *init_data;
+       struct regulator_config config = { };
        int i, ret;
 
        dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
@@ -357,11 +358,16 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
        priv->mc13xxx = mc13783;
 
        for (i = 0; i < pdata->num_regulators; i++) {
+               struct regulator_desc *desc;
+
                init_data = &pdata->regulators[i];
-               priv->regulators[i] = regulator_register(
-                               &mc13783_regulators[init_data->id].desc,
-                               &pdev->dev, init_data->init_data, priv, NULL);
+               desc = &mc13783_regulators[init_data->id].desc;
+
+               config.dev = &pdev->dev;
+               config.init_data = init_data->init_data;
+               config.driver_data = priv;
 
+               priv->regulators[i] = regulator_register(desc, &config);
                if (IS_ERR(priv->regulators[i])) {
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
                                mc13783_regulators[i].desc.name);
index 845aa2263b8af7a1de6b7456fb4c8cf547167c18..970a233dbe46f3aa9e167195bc98f0d60ba9d624 100644 (file)
@@ -428,24 +428,15 @@ static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev)
        return val;
 }
 
-static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
-               int min_uV, int max_uV, unsigned *selector)
+static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
+                                               unsigned selector)
 {
        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
        int hi, value, mask, id = rdev_get_id(rdev);
        u32 valread;
        int ret;
 
-       dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
-               __func__, id, min_uV, max_uV);
-
-       /* Find the best index */
-       value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
-       dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
-       if (value < 0)
-               return value;
-
-       value = mc13892_regulators[id].voltages[value];
+       value = mc13892_regulators[id].voltages[selector];
 
        mc13xxx_lock(priv->mc13xxx);
        ret = mc13xxx_reg_read(priv->mc13xxx,
@@ -480,7 +471,7 @@ err:
 static struct regulator_ops mc13892_sw_regulator_ops = {
        .is_enabled = mc13xxx_sw_regulator_is_enabled,
        .list_voltage = mc13xxx_regulator_list_voltage,
-       .set_voltage = mc13892_sw_regulator_set_voltage,
+       .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel,
        .get_voltage = mc13892_sw_regulator_get_voltage,
 };
 
@@ -528,6 +519,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
        struct mc13xxx_regulator_platform_data *pdata =
                dev_get_platdata(&pdev->dev);
        struct mc13xxx_regulator_init_data *mc13xxx_data;
+       struct regulator_config config = { };
        int i, ret;
        int num_regulators = 0;
        u32 val;
@@ -597,9 +589,12 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
                }
                desc = &mc13892_regulators[id].desc;
 
-               priv->regulators[i] = regulator_register(
-                       desc, &pdev->dev, init_data, priv, node);
+               config.dev = &pdev->dev;
+               config.init_data = init_data;
+               config.driver_data = priv;
+               config.of_node = node;
 
+               priv->regulators[i] = regulator_register(desc, &config);
                if (IS_ERR(priv->regulators[i])) {
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
                                mc13892_regulators[i].desc.name);
index 62dcd0a432bb65832fc7bcf454b08587401ad293..4fa9704739bc41bb764ece50e58071783501966a 100644 (file)
@@ -94,62 +94,18 @@ int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
 }
 EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage);
 
-int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
-                                               int min_uV, int max_uV)
+static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev,
+                                            unsigned selector)
 {
        struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
        struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
-       int reg_id = rdev_get_id(rdev);
-       int i;
-       int bestmatch;
-       int bestindex;
-
-       /*
-        * Locate the minimum voltage fitting the criteria on
-        * this regulator. The switchable voltages are not
-        * in strict falling order so we need to check them
-        * all for the best match.
-        */
-       bestmatch = INT_MAX;
-       bestindex = -1;
-       for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) {
-               if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV &&
-                   mc13xxx_regulators[reg_id].voltages[i] < bestmatch) {
-                       bestmatch = mc13xxx_regulators[reg_id].voltages[i];
-                       bestindex = i;
-               }
-       }
-
-       if (bestindex < 0 || bestmatch > max_uV) {
-               dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
-                               min_uV, max_uV);
-               return -EINVAL;
-       }
-       return bestindex;
-}
-EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index);
-
-static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
-               int max_uV, unsigned *selector)
-{
-       struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
-       struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
-       int value, id = rdev_get_id(rdev);
+       int id = rdev_get_id(rdev);
        int ret;
 
-       dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
-               __func__, id, min_uV, max_uV);
-
-       /* Find the best index */
-       value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
-       dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
-       if (value < 0)
-               return value;
-
        mc13xxx_lock(priv->mc13xxx);
        ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
                        mc13xxx_regulators[id].vsel_mask,
-                       value << mc13xxx_regulators[id].vsel_shift);
+                       selector << mc13xxx_regulators[id].vsel_shift);
        mc13xxx_unlock(priv->mc13xxx);
 
        return ret;
@@ -187,7 +143,7 @@ struct regulator_ops mc13xxx_regulator_ops = {
        .disable = mc13xxx_regulator_disable,
        .is_enabled = mc13xxx_regulator_is_enabled,
        .list_voltage = mc13xxx_regulator_list_voltage,
-       .set_voltage = mc13xxx_regulator_set_voltage,
+       .set_voltage_sel = mc13xxx_regulator_set_voltage_sel,
        .get_voltage = mc13xxx_regulator_get_voltage,
 };
 EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops);
index b3961c658b0594a8c728f780f1c49fd7830e4959..044aba4d28eca99f952207adf15e4b382b2c9f96 100644 (file)
@@ -35,8 +35,6 @@ struct mc13xxx_regulator_priv {
 
 extern int mc13xxx_sw_regulator(struct regulator_dev *rdev);
 extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev);
-extern int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
-                                               int min_uV, int max_uV);
 extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
                                                unsigned selector);
 extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
index a5aab1b08bcf6f246255b42600a3a355fc7de5a5..8211101121f0c6a07b68184db5bb95bbd53d7e73 100644 (file)
@@ -150,57 +150,33 @@ static struct pcap_regulator vreg_table[] = {
        VREG_INFO(SW2S,  PCAP_REG_LOWPWR,  NA, 20, NA, NA), */
 };
 
-static int pcap_regulator_set_voltage(struct regulator_dev *rdev,
-                                     int min_uV, int max_uV,
-                                     unsigned *selector)
+static int pcap_regulator_set_voltage_sel(struct regulator_dev *rdev,
+                                         unsigned selector)
 {
        struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
        void *pcap = rdev_get_drvdata(rdev);
-       int uV;
-       u8 i;
 
        /* the regulator doesn't support voltage switching */
        if (vreg->n_voltages == 1)
                return -EINVAL;
 
-       for (i = 0; i < vreg->n_voltages; i++) {
-               /* For V1 the first is not the best match */
-               if (i == 0 && rdev_get_id(rdev) == V1)
-                       i = 1;
-               else if (i + 1 == vreg->n_voltages && rdev_get_id(rdev) == V1)
-                       i = 0;
-
-               uV = vreg->voltage_table[i] * 1000;
-               if (min_uV <= uV && uV <= max_uV) {
-                       *selector = i;
-                       return ezx_pcap_set_bits(pcap, vreg->reg,
-                                       (vreg->n_voltages - 1) << vreg->index,
-                                       i << vreg->index);
-               }
-
-               if (i == 0 && rdev_get_id(rdev) == V1)
-                       i = vreg->n_voltages - 1;
-       }
-
-       /* the requested voltage range is not supported by this regulator */
-       return -EINVAL;
+       return ezx_pcap_set_bits(pcap, vreg->reg,
+                                (vreg->n_voltages - 1) << vreg->index,
+                                selector << vreg->index);
 }
 
-static int pcap_regulator_get_voltage(struct regulator_dev *rdev)
+static int pcap_regulator_get_voltage_sel(struct regulator_dev *rdev)
 {
        struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
        void *pcap = rdev_get_drvdata(rdev);
        u32 tmp;
-       int mV;
 
        if (vreg->n_voltages == 1)
-               return vreg->voltage_table[0] * 1000;
+               return 0;
 
        ezx_pcap_read(pcap, vreg->reg, &tmp);
        tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1));
-       mV = vreg->voltage_table[tmp];
-
-       return mV * 1000;
+       return tmp;
 }
 
 static int pcap_regulator_enable(struct regulator_dev *rdev)
@@ -248,8 +224,8 @@ static int pcap_regulator_list_voltage(struct regulator_dev *rdev,
 
 static struct regulator_ops pcap_regulator_ops = {
        .list_voltage   = pcap_regulator_list_voltage,
-       .set_voltage    = pcap_regulator_set_voltage,
-       .get_voltage    = pcap_regulator_get_voltage,
+       .set_voltage_sel = pcap_regulator_set_voltage_sel,
+       .get_voltage_sel = pcap_regulator_get_voltage_sel,
        .enable         = pcap_regulator_enable,
        .disable        = pcap_regulator_disable,
        .is_enabled     = pcap_regulator_is_enabled,
@@ -265,7 +241,7 @@ static struct regulator_ops pcap_regulator_ops = {
                .owner          = THIS_MODULE,                  \
        }
 
-static struct regulator_desc pcap_regulators[] = {
+static const struct regulator_desc pcap_regulators[] = {
        VREG(V1), VREG(V2), VREG(V3), VREG(V4), VREG(V5), VREG(V6), VREG(V7),
        VREG(V8), VREG(V9), VREG(V10), VREG(VAUX1), VREG(VAUX2), VREG(VAUX3),
        VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2),
@@ -275,9 +251,13 @@ static int __devinit pcap_regulator_probe(struct platform_device *pdev)
 {
        struct regulator_dev *rdev;
        void *pcap = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_config config = { };
+
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = pcap;
 
-       rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev,
-                               pdev->dev.platform_data, pcap, NULL);
+       rdev = regulator_register(&pcap_regulators[pdev->id], &config);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
index 6db46c632f130753e46f60c3f45055a8f53a9519..3c9d14c0017bba05c5c770dea4478c51b60f533e 100644 (file)
 #include <linux/mfd/pcf50633/core.h>
 #include <linux/mfd/pcf50633/pmic.h>
 
-#define PCF50633_REGULATOR(_name, _id, _n)             \
-       {                                       \
-               .name = _name,                  \
-               .id = _id,                      \
-               .ops = &pcf50633_regulator_ops, \
-               .n_voltages = _n, \
-               .type = REGULATOR_VOLTAGE,      \
-               .owner = THIS_MODULE,           \
+#define PCF50633_REGULATOR(_name, _id, _n)                     \
+       {                                                       \
+               .name = _name,                                  \
+               .id = PCF50633_REGULATOR_##_id,                 \
+               .ops = &pcf50633_regulator_ops,                 \
+               .n_voltages = _n,                               \
+               .type = REGULATOR_VOLTAGE,                      \
+               .owner = THIS_MODULE,                           \
+               .vsel_reg = PCF50633_REG_##_id##OUT,            \
+               .vsel_mask = 0xff,                              \
+               .enable_reg = PCF50633_REG_##_id##OUT + 1,      \
+               .enable_mask = PCF50633_REGULATOR_ON,           \
        }
 
-static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
-       [PCF50633_REGULATOR_AUTO]       = PCF50633_REG_AUTOOUT,
-       [PCF50633_REGULATOR_DOWN1]      = PCF50633_REG_DOWN1OUT,
-       [PCF50633_REGULATOR_DOWN2]      = PCF50633_REG_DOWN2OUT,
-       [PCF50633_REGULATOR_MEMLDO]     = PCF50633_REG_MEMLDOOUT,
-       [PCF50633_REGULATOR_LDO1]       = PCF50633_REG_LDO1OUT,
-       [PCF50633_REGULATOR_LDO2]       = PCF50633_REG_LDO2OUT,
-       [PCF50633_REGULATOR_LDO3]       = PCF50633_REG_LDO3OUT,
-       [PCF50633_REGULATOR_LDO4]       = PCF50633_REG_LDO4OUT,
-       [PCF50633_REGULATOR_LDO5]       = PCF50633_REG_LDO5OUT,
-       [PCF50633_REGULATOR_LDO6]       = PCF50633_REG_LDO6OUT,
-       [PCF50633_REGULATOR_HCLDO]      = PCF50633_REG_HCLDOOUT,
-};
-
 /* Bits from voltage value */
 static u8 auto_voltage_bits(unsigned int millivolts)
 {
        if (millivolts < 1800)
-               return 0;
+               return 0x2f;
        if (millivolts > 3800)
                return 0xff;
 
@@ -87,6 +77,9 @@ static u8 ldo_voltage_bits(unsigned int millivolts)
 /* Obtain voltage value from bits */
 static unsigned int auto_voltage_value(u8 bits)
 {
+       /* AUTOOUT: 00000000 to 00101110 are reserved.
+        * Return 0 for bits in reserved range, which means this selector code
+        * can't be used on this system */
        if (bits < 0x2f)
                return 0;
 
@@ -123,7 +116,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
 
        millivolts = min_uV / 1000;
 
-       regnr = pcf50633_regulator_registers[regulator_id];
+       regnr = rdev->desc->vsel_reg;
 
        switch (regulator_id) {
        case PCF50633_REGULATOR_AUTO:
@@ -154,20 +147,22 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
        return pcf50633_reg_write(pcf, regnr, volt_bits);
 }
 
-static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
-                                               u8 bits)
+static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
+                                               unsigned int index)
 {
+       int regulator_id = rdev_get_id(rdev);
+
        int millivolts;
 
-       switch (id) {
+       switch (regulator_id) {
        case PCF50633_REGULATOR_AUTO:
-               millivolts = auto_voltage_value(bits);
+               millivolts = auto_voltage_value(index);
                break;
        case PCF50633_REGULATOR_DOWN1:
-               millivolts = down_voltage_value(bits);
+               millivolts = down_voltage_value(index);
                break;
        case PCF50633_REGULATOR_DOWN2:
-               millivolts = down_voltage_value(bits);
+               millivolts = down_voltage_value(index);
                break;
        case PCF50633_REGULATOR_LDO1:
        case PCF50633_REGULATOR_LDO2:
@@ -177,7 +172,7 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
        case PCF50633_REGULATOR_LDO6:
        case PCF50633_REGULATOR_HCLDO:
        case PCF50633_REGULATOR_MEMLDO:
-               millivolts = ldo_voltage_value(bits);
+               millivolts = ldo_voltage_value(index);
                break;
        default:
                return -EINVAL;
@@ -186,140 +181,44 @@ static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
        return millivolts * 1000;
 }
 
-static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
-{
-       struct pcf50633 *pcf;
-       int regulator_id;
-       u8 volt_bits, regnr;
-
-       pcf = rdev_get_drvdata(rdev);
-
-       regulator_id = rdev_get_id(rdev);
-       if (regulator_id >= PCF50633_NUM_REGULATORS)
-               return -EINVAL;
-
-       regnr = pcf50633_regulator_registers[regulator_id];
-
-       volt_bits = pcf50633_reg_read(pcf, regnr);
-
-       return pcf50633_regulator_voltage_value(regulator_id, volt_bits);
-}
-
-static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
-                                               unsigned int index)
-{
-       struct pcf50633 *pcf;
-       int regulator_id;
-
-       pcf = rdev_get_drvdata(rdev);
-
-       regulator_id = rdev_get_id(rdev);
-
-       switch (regulator_id) {
-       case PCF50633_REGULATOR_AUTO:
-               index += 0x2f;
-               break;
-       default:
-               break;
-       }
-
-       return pcf50633_regulator_voltage_value(regulator_id, index);
-}
-
-static int pcf50633_regulator_enable(struct regulator_dev *rdev)
-{
-       struct pcf50633 *pcf = rdev_get_drvdata(rdev);
-       int regulator_id;
-       u8 regnr;
-
-       regulator_id = rdev_get_id(rdev);
-       if (regulator_id >= PCF50633_NUM_REGULATORS)
-               return -EINVAL;
-
-       /* The *ENA register is always one after the *OUT register */
-       regnr = pcf50633_regulator_registers[regulator_id] + 1;
-
-       return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON,
-                                                      PCF50633_REGULATOR_ON);
-}
-
-static int pcf50633_regulator_disable(struct regulator_dev *rdev)
-{
-       struct pcf50633 *pcf = rdev_get_drvdata(rdev);
-       int regulator_id;
-       u8 regnr;
-
-       regulator_id = rdev_get_id(rdev);
-       if (regulator_id >= PCF50633_NUM_REGULATORS)
-               return -EINVAL;
-
-       /* the *ENA register is always one after the *OUT register */
-       regnr = pcf50633_regulator_registers[regulator_id] + 1;
-
-       return pcf50633_reg_set_bit_mask(pcf, regnr,
-                                       PCF50633_REGULATOR_ON, 0);
-}
-
-static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
-{
-       struct pcf50633 *pcf = rdev_get_drvdata(rdev);
-       int regulator_id = rdev_get_id(rdev);
-       u8 regnr;
-
-       regulator_id = rdev_get_id(rdev);
-       if (regulator_id >= PCF50633_NUM_REGULATORS)
-               return -EINVAL;
-
-       /* the *ENA register is always one after the *OUT register */
-       regnr = pcf50633_regulator_registers[regulator_id] + 1;
-
-       return pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON;
-}
-
 static struct regulator_ops pcf50633_regulator_ops = {
        .set_voltage = pcf50633_regulator_set_voltage,
-       .get_voltage = pcf50633_regulator_get_voltage,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .list_voltage = pcf50633_regulator_list_voltage,
-       .enable = pcf50633_regulator_enable,
-       .disable = pcf50633_regulator_disable,
-       .is_enabled = pcf50633_regulator_is_enabled,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
 };
 
-static struct regulator_desc regulators[] = {
-       [PCF50633_REGULATOR_AUTO] =
-               PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 81),
-       [PCF50633_REGULATOR_DOWN1] =
-               PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 96),
-       [PCF50633_REGULATOR_DOWN2] =
-               PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 96),
-       [PCF50633_REGULATOR_LDO1] =
-               PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 28),
-       [PCF50633_REGULATOR_LDO2] =
-               PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 28),
-       [PCF50633_REGULATOR_LDO3] =
-               PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 28),
-       [PCF50633_REGULATOR_LDO4] =
-               PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 28),
-       [PCF50633_REGULATOR_LDO5] =
-               PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 28),
-       [PCF50633_REGULATOR_LDO6] =
-               PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 28),
-       [PCF50633_REGULATOR_HCLDO] =
-               PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 28),
-       [PCF50633_REGULATOR_MEMLDO] =
-               PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 28),
+static const struct regulator_desc regulators[] = {
+       [PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128),
+       [PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96),
+       [PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96),
+       [PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28),
+       [PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28),
+       [PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28),
+       [PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28),
+       [PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28),
+       [PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28),
+       [PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28),
+       [PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28),
 };
 
 static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
 {
        struct regulator_dev *rdev;
        struct pcf50633 *pcf;
+       struct regulator_config config = { };
 
        /* Already set by core driver */
        pcf = dev_to_pcf50633(pdev->dev.parent);
 
-       rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data, pcf, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = pcf;
+       config.regmap = pcf->regmap;
+
+       rdev = regulator_register(&regulators[pdev->id], &config);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c
new file mode 100644 (file)
index 0000000..c4adefe
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * Regulator driver for RICOH RC5T583 power management chip.
+ *
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
+ * Author: Laxman dewangan <ldewangan@nvidia.com>
+ *
+ * based on code
+ *      Copyright (C) 2011 RICOH COMPANY,LTD
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.h>
+#include <linux/mfd/rc5t583.h>
+
+struct rc5t583_regulator_info {
+       int                     deepsleep_id;
+
+       /* Regulator register address.*/
+       uint8_t                 reg_disc_reg;
+       uint8_t                 disc_bit;
+       uint8_t                 deepsleep_reg;
+
+       /* Chip constraints on regulator behavior */
+       int                     min_uV;
+       int                     max_uV;
+       int                     step_uV;
+
+       /* Regulator specific turn-on delay  and voltage settling time*/
+       int                     enable_uv_per_us;
+       int                     change_uv_per_us;
+
+       /* Used by regulator core */
+       struct regulator_desc   desc;
+};
+
+struct rc5t583_regulator {
+       struct rc5t583_regulator_info *reg_info;
+
+       /* Devices */
+       struct device           *dev;
+       struct rc5t583          *mfd;
+       struct regulator_dev    *rdev;
+};
+
+static int rc5t583_list_voltage(struct regulator_dev *rdev, unsigned selector)
+{
+       struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
+       struct rc5t583_regulator_info *ri = reg->reg_info;
+       return ri->min_uV + (ri->step_uV * selector);
+}
+
+static int rc5t583_set_voltage(struct regulator_dev *rdev,
+                              int min_uV, int max_uV, unsigned *selector)
+{
+       struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
+       struct rc5t583_regulator_info *ri = reg->reg_info;
+       int sel, ret;
+
+       if (min_uV < ri->min_uV)
+               min_uV = ri->min_uV;
+
+       sel = DIV_ROUND_UP(min_uV - ri->min_uV, ri->step_uV);
+
+       if (sel >= rdev->desc->n_voltages) {
+               dev_err(&rdev->dev, "Invalid selector 0x%02x\n", sel);
+               return -EINVAL;
+       }
+
+       *selector = sel;
+
+       ret = rc5t583_update(reg->mfd->dev, rdev->desc->vsel_reg, sel,
+                            rdev->desc->vsel_mask);
+       if (ret < 0)
+               dev_err(&rdev->dev, "Error in update voltage register 0x%02x\n",
+                       rdev->desc->vsel_reg);
+       return ret;
+}
+
+static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
+{
+       struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
+       int vsel = regulator_get_voltage_sel_regmap(rdev);
+       int curr_uV = rc5t583_list_voltage(rdev, vsel);
+
+       return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us);
+}
+
+static int rc5t583_set_voltage_time_sel(struct regulator_dev *rdev,
+               unsigned int old_selector, unsigned int new_selector)
+{
+       struct rc5t583_regulator *reg = rdev_get_drvdata(rdev);
+       int old_uV, new_uV;
+       old_uV = rc5t583_list_voltage(rdev, old_selector);
+
+       if (old_uV < 0)
+               return old_uV;
+
+       new_uV = rc5t583_list_voltage(rdev, new_selector);
+       if (new_uV < 0)
+               return new_uV;
+
+       return DIV_ROUND_UP(abs(old_uV - new_uV),
+                               reg->reg_info->change_uv_per_us);
+}
+
+
+static struct regulator_ops rc5t583_ops = {
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .enable_time            = rc5t583_regulator_enable_time,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage            = rc5t583_set_voltage,
+       .list_voltage           = rc5t583_list_voltage,
+       .set_voltage_time_sel   = rc5t583_set_voltage_time_sel,
+};
+
+#define RC5T583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, \
+               _vout_mask, _min_mv, _max_mv, _step_uV, _enable_mv) \
+{                                                              \
+       .reg_disc_reg   = RC5T583_REG_##_disc_reg,              \
+       .disc_bit       = _disc_bit,                            \
+       .deepsleep_reg  = RC5T583_REG_##_id##DAC_DS,            \
+       .min_uV         = _min_mv * 1000,                       \
+       .max_uV         = _max_mv * 1000,                       \
+       .step_uV        = _step_uV,                             \
+       .enable_uv_per_us = _enable_mv * 1000,                  \
+       .change_uv_per_us = 40 * 1000,                          \
+       .deepsleep_id   = RC5T583_DS_##_id,                     \
+       .desc = {                                               \
+               .name = "rc5t583-regulator-"#_id,               \
+               .id = RC5T583_REGULATOR_##_id,                  \
+               .n_voltages = (_max_mv - _min_mv) * 1000 / _step_uV + 1, \
+               .ops = &rc5t583_ops,                            \
+               .type = REGULATOR_VOLTAGE,                      \
+               .owner = THIS_MODULE,                           \
+               .vsel_reg = RC5T583_REG_##_id##DAC,             \
+               .vsel_mask = _vout_mask,                        \
+               .enable_reg = RC5T583_REG_##_en_reg,            \
+               .enable_mask = BIT(_en_bit),                    \
+       },                                                      \
+}
+
+static struct rc5t583_regulator_info rc5t583_reg_info[RC5T583_REGULATOR_MAX] = {
+       RC5T583_REG(DC0, DC0CTL, 0, DC0CTL, 1, 0x7F, 700, 1500, 12500, 4),
+       RC5T583_REG(DC1, DC1CTL, 0, DC1CTL, 1, 0x7F, 700, 1500, 12500, 14),
+       RC5T583_REG(DC2, DC2CTL, 0, DC2CTL, 1, 0x7F, 900, 2400, 12500, 14),
+       RC5T583_REG(DC3, DC3CTL, 0, DC3CTL, 1, 0x7F, 900, 2400, 12500, 14),
+       RC5T583_REG(LDO0, LDOEN2, 0, LDODIS2, 0, 0x7F, 900, 3400, 25000, 160),
+       RC5T583_REG(LDO1, LDOEN2, 1, LDODIS2, 1, 0x7F, 900, 3400, 25000, 160),
+       RC5T583_REG(LDO2, LDOEN2, 2, LDODIS2, 2, 0x7F, 900, 3400, 25000, 160),
+       RC5T583_REG(LDO3, LDOEN2, 3, LDODIS2, 3, 0x7F, 900, 3400, 25000, 160),
+       RC5T583_REG(LDO4, LDOEN2, 4, LDODIS2, 4, 0x3F, 750, 1500, 12500, 133),
+       RC5T583_REG(LDO5, LDOEN2, 5, LDODIS2, 5, 0x7F, 900, 3400, 25000, 267),
+       RC5T583_REG(LDO6, LDOEN2, 6, LDODIS2, 6, 0x7F, 900, 3400, 25000, 133),
+       RC5T583_REG(LDO7, LDOEN2, 7, LDODIS2, 7, 0x7F, 900, 3400, 25000, 233),
+       RC5T583_REG(LDO8, LDOEN1, 0, LDODIS1, 0, 0x7F, 900, 3400, 25000, 233),
+       RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
+};
+
+static int __devinit rc5t583_regulator_probe(struct platform_device *pdev)
+{
+       struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
+       struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
+       struct regulator_init_data *reg_data;
+       struct regulator_config config = { };
+       struct rc5t583_regulator *reg = NULL;
+       struct rc5t583_regulator *regs;
+       struct regulator_dev *rdev;
+       struct rc5t583_regulator_info *ri;
+       int ret;
+       int id;
+
+       if (!pdata) {
+               dev_err(&pdev->dev, "No platform data, exiting...\n");
+               return -ENODEV;
+       }
+
+       regs = devm_kzalloc(&pdev->dev, RC5T583_REGULATOR_MAX *
+                       sizeof(struct rc5t583_regulator), GFP_KERNEL);
+       if (!regs) {
+               dev_err(&pdev->dev, "Memory allocation failed exiting..\n");
+               return -ENOMEM;
+       }
+
+
+       for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) {
+               reg_data = pdata->reg_init_data[id];
+
+               /* No need to register if there is no regulator data */
+               if (!reg_data)
+                       continue;
+
+               reg = &regs[id];
+               ri = &rc5t583_reg_info[id];
+               reg->reg_info = ri;
+               reg->mfd = rc5t583;
+               reg->dev = &pdev->dev;
+
+               if (ri->deepsleep_id == RC5T583_DS_NONE)
+                       goto skip_ext_pwr_config;
+
+               ret = rc5t583_ext_power_req_config(rc5t583->dev,
+                               ri->deepsleep_id,
+                               pdata->regulator_ext_pwr_control[id],
+                               pdata->regulator_deepsleep_slot[id]);
+               /*
+                * Configuring external control is not a major issue,
+                * just give warning.
+                */
+               if (ret < 0)
+                       dev_warn(&pdev->dev,
+                               "Failed to configure ext control %d\n", id);
+
+skip_ext_pwr_config:
+               config.dev = &pdev->dev;
+               config.init_data = reg_data;
+               config.driver_data = reg;
+               config.regmap = rc5t583->regmap;
+
+               rdev = regulator_register(&ri->desc, &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(&pdev->dev, "Failed to register regulator %s\n",
+                                               ri->desc.name);
+                       ret = PTR_ERR(rdev);
+                       goto clean_exit;
+               }
+               reg->rdev = rdev;
+       }
+       platform_set_drvdata(pdev, regs);
+       return 0;
+
+clean_exit:
+       while (--id >= 0)
+               regulator_unregister(regs[id].rdev);
+
+       return ret;
+}
+
+static int __devexit rc5t583_regulator_remove(struct platform_device *pdev)
+{
+       struct rc5t583_regulator *regs = platform_get_drvdata(pdev);
+       int id;
+
+       for (id = 0; id < RC5T583_REGULATOR_MAX; ++id)
+               regulator_unregister(regs[id].rdev);
+       return 0;
+}
+
+static struct platform_driver rc5t583_regulator_driver = {
+       .driver = {
+               .name   = "rc5t583-regulator",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = rc5t583_regulator_probe,
+       .remove         = __devexit_p(rc5t583_regulator_remove),
+};
+
+static int __init rc5t583_regulator_init(void)
+{
+       return platform_driver_register(&rc5t583_regulator_driver);
+}
+subsys_initcall(rc5t583_regulator_init);
+
+static void __exit rc5t583_regulator_exit(void)
+{
+       platform_driver_unregister(&rc5t583_regulator_driver);
+}
+module_exit(rc5t583_regulator_exit);
+
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("RC5T583 regulator driver");
+MODULE_ALIAS("platform:rc5t583-regulator");
+MODULE_LICENSE("GPL v2");
index 4ca2db0590048e833ddb88e9eb2a88fee1e3c494..cb53187a60d3f89b4e1a5a4cb6480f86bd0d9b06 100644 (file)
@@ -28,6 +28,7 @@ struct s5m8767_info {
        struct s5m87xx_dev *iodev;
        int num_regulators;
        struct regulator_dev **rdev;
+       struct s5m_opmode_data *opmode;
 
        int ramp_delay;
        bool buck2_ramp;
@@ -141,9 +142,56 @@ static int s5m8767_list_voltage(struct regulator_dev *rdev,
        return val;
 }
 
-static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
+unsigned int s5m8767_opmode_reg[][4] = {
+       /* {OFF, ON, LOWPOWER, SUSPEND} */
+       /* LDO1 ... LDO28 */
+       {0x0, 0x3, 0x2, 0x1}, /* LDO1 */
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x0, 0x0, 0x0},
+       {0x0, 0x3, 0x2, 0x1}, /* LDO5 */
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1}, /* LDO10 */
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1}, /* LDO15 */
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x0, 0x0, 0x0},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1}, /* LDO20 */
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x0, 0x0, 0x0},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1}, /* LDO25 */
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1},
+       {0x0, 0x3, 0x2, 0x1}, /* LDO28 */
+
+       /* BUCK1 ... BUCK9 */
+       {0x0, 0x3, 0x1, 0x1}, /* BUCK1 */
+       {0x0, 0x3, 0x1, 0x1},
+       {0x0, 0x3, 0x1, 0x1},
+       {0x0, 0x3, 0x1, 0x1},
+       {0x0, 0x3, 0x2, 0x1}, /* BUCK5 */
+       {0x0, 0x3, 0x1, 0x1},
+       {0x0, 0x3, 0x1, 0x1},
+       {0x0, 0x3, 0x1, 0x1},
+       {0x0, 0x3, 0x1, 0x1}, /* BUCK9 */
+};
+
+static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
+                               int *enable_ctrl)
 {
        int reg_id = rdev_get_id(rdev);
+       unsigned int mode;
+       struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
 
        switch (reg_id) {
        case S5M8767_LDO1 ... S5M8767_LDO2:
@@ -168,6 +216,8 @@ static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
                return -EINVAL;
        }
 
+       mode = s5m8767->opmode[reg_id].mode;
+       *enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
        return 0;
 }
 
@@ -175,10 +225,10 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
 {
        struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
        int ret, reg;
-       int mask = 0xc0, pattern = 0xc0;
+       int mask = 0xc0, enable_ctrl;
        u8 val;
 
-       ret = s5m8767_get_register(rdev, &reg);
+       ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
        if (ret == -EINVAL)
                return 1;
        else if (ret)
@@ -188,33 +238,33 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
        if (ret)
                return ret;
 
-       return (val & mask) == pattern;
+       return (val & mask) == enable_ctrl;
 }
 
 static int s5m8767_reg_enable(struct regulator_dev *rdev)
 {
        struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
        int ret, reg;
-       int mask = 0xc0, pattern = 0xc0;
+       int mask = 0xc0, enable_ctrl;
 
-       ret = s5m8767_get_register(rdev, &reg);
+       ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
        if (ret)
                return ret;
 
-       return s5m_reg_update(s5m8767->iodev, reg, pattern, mask);
+       return s5m_reg_update(s5m8767->iodev, reg, enable_ctrl, mask);
 }
 
 static int s5m8767_reg_disable(struct regulator_dev *rdev)
 {
        struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
        int ret, reg;
-       int  mask = 0xc0, pattern = 0xc0;
+       int  mask = 0xc0, enable_ctrl;
 
-       ret = s5m8767_get_register(rdev, &reg);
+       ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
        if (ret)
                return ret;
 
-       return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask);
+       return s5m_reg_update(s5m8767->iodev, reg, ~mask, mask);
 }
 
 static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
@@ -305,14 +355,33 @@ static int s5m8767_convert_voltage_to_sel(
        return selector;
 }
 
+static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
+{
+       int temp_index = s5m8767->buck_gpioindex;
+
+       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+}
+
+static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
+{
+       int temp_index = s5m8767->buck_gpioindex;
+
+       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+}
+
 static int s5m8767_set_voltage(struct regulator_dev *rdev,
                                int min_uV, int max_uV, unsigned *selector)
 {
        struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
        const struct s5m_voltage_desc *desc;
        int reg_id = rdev_get_id(rdev);
-       int sel, reg, mask, ret;
+       int sel, reg, mask, ret = 0, old_index, index = 0;
        u8 val;
+       u8 *buck234_vol = NULL;
 
        switch (reg_id) {
        case S5M8767_LDO1 ... S5M8767_LDO28:
@@ -320,6 +389,12 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev,
                break;
        case S5M8767_BUCK1 ... S5M8767_BUCK6:
                mask = 0xff;
+               if (reg_id == S5M8767_BUCK2 && s5m8767->buck2_gpiodvs)
+                       buck234_vol = &s5m8767->buck2_vol[0];
+               else if (reg_id == S5M8767_BUCK3 && s5m8767->buck3_gpiodvs)
+                       buck234_vol = &s5m8767->buck3_vol[0];
+               else if (reg_id == S5M8767_BUCK4 && s5m8767->buck4_gpiodvs)
+                       buck234_vol = &s5m8767->buck4_vol[0];
                break;
        case S5M8767_BUCK7 ... S5M8767_BUCK8:
                return -EINVAL;
@@ -336,102 +411,32 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev,
        if (sel < 0)
                return sel;
 
-       ret = s5m8767_get_voltage_register(rdev, &reg);
-       if (ret)
-               return ret;
-
-       s5m_reg_read(s5m8767->iodev, reg, &val);
-       val &= ~mask;
-       val |= sel;
-
-       ret = s5m_reg_write(s5m8767->iodev, reg, val);
-       *selector = sel;
-
-       return ret;
-}
-
-static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
-{
-       int temp_index = s5m8767->buck_gpioindex;
-
-       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
-}
-
-static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
-{
-       int temp_index = s5m8767->buck_gpioindex;
-
-       gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
-       gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
-}
-
-static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
-                                   int min_uV, int max_uV, unsigned *selector)
-{
-       struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
-       int reg_id = rdev_get_id(rdev);
-       const struct s5m_voltage_desc *desc;
-       int new_val, old_val, i = 0;
-
-       if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
-               return -EINVAL;
-
-       switch (reg_id) {
-       case S5M8767_BUCK1:
-               return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
-       case S5M8767_BUCK2 ... S5M8767_BUCK4:
-               break;
-       case S5M8767_BUCK5 ... S5M8767_BUCK6:
-               return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
-       case S5M8767_BUCK9:
-               return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
-       }
+       /* buck234_vol != NULL means to control buck234 voltage via DVS GPIO */
+       if (buck234_vol) {
+               while (*buck234_vol != sel) {
+                       buck234_vol++;
+                       index++;
+               }
+               old_index = s5m8767->buck_gpioindex;
+               s5m8767->buck_gpioindex = index;
+
+               if (index > old_index)
+                       s5m8767_set_high(s5m8767);
+               else
+                       s5m8767_set_low(s5m8767);
+       } else {
+               ret = s5m8767_get_voltage_register(rdev, &reg);
+               if (ret)
+                       return ret;
 
-       desc = reg_voltage_map[reg_id];
-       new_val = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV);
-       if (new_val < 0)
-               return new_val;
+               s5m_reg_read(s5m8767->iodev, reg, &val);
+               val = (val & ~mask) | sel;
 
-       switch (reg_id) {
-       case S5M8767_BUCK2:
-               if (s5m8767->buck2_gpiodvs) {
-                       while (s5m8767->buck2_vol[i] != new_val)
-                               i++;
-               } else
-                       return s5m8767_set_voltage(rdev, min_uV,
-                                                  max_uV, selector);
-               break;
-       case S5M8767_BUCK3:
-               if (s5m8767->buck3_gpiodvs) {
-                       while (s5m8767->buck3_vol[i] != new_val)
-                               i++;
-               } else
-                       return s5m8767_set_voltage(rdev, min_uV,
-                                                  max_uV, selector);
-               break;
-       case S5M8767_BUCK4:
-               if (s5m8767->buck3_gpiodvs) {
-                       while (s5m8767->buck4_vol[i] != new_val)
-                               i++;
-               } else
-                       return s5m8767_set_voltage(rdev, min_uV,
-                                                  max_uV, selector);
-               break;
+               ret = s5m_reg_write(s5m8767->iodev, reg, val);
        }
 
-       old_val = s5m8767->buck_gpioindex;
-       s5m8767->buck_gpioindex = i;
-
-       if (i > old_val)
-               s5m8767_set_high(s5m8767);
-       else
-               s5m8767_set_low(s5m8767);
-
-       *selector = new_val;
-       return 0;
+       *selector = sel;
+       return ret;
 }
 
 static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
@@ -450,7 +455,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
        return 0;
 }
 
-static struct regulator_ops s5m8767_ldo_ops = {
+static struct regulator_ops s5m8767_ops = {
        .list_voltage           = s5m8767_list_voltage,
        .is_enabled             = s5m8767_reg_is_enabled,
        .enable                 = s5m8767_reg_enable,
@@ -460,75 +465,59 @@ static struct regulator_ops s5m8767_ldo_ops = {
        .set_voltage_time_sel   = s5m8767_set_voltage_time_sel,
 };
 
-static struct regulator_ops s5m8767_buck_ops = {
-       .list_voltage           = s5m8767_list_voltage,
-       .is_enabled             = s5m8767_reg_is_enabled,
-       .enable                 = s5m8767_reg_enable,
-       .disable                = s5m8767_reg_disable,
-       .get_voltage_sel        = s5m8767_get_voltage_sel,
-       .set_voltage            = s5m8767_set_voltage_buck,
-       .set_voltage_time_sel   = s5m8767_set_voltage_time_sel,
-};
-
-#define regulator_desc_ldo(num)                {       \
-       .name           = "LDO"#num,            \
-       .id             = S5M8767_LDO##num,     \
-       .ops            = &s5m8767_ldo_ops,     \
-       .type           = REGULATOR_VOLTAGE,    \
-       .owner          = THIS_MODULE,          \
-}
-#define regulator_desc_buck(num)       {       \
-       .name           = "BUCK"#num,           \
-       .id             = S5M8767_BUCK##num,    \
-       .ops            = &s5m8767_buck_ops,    \
+#define s5m8767_regulator_desc(_name) {                \
+       .name           = #_name,               \
+       .id             = S5M8767_##_name,      \
+       .ops            = &s5m8767_ops,         \
        .type           = REGULATOR_VOLTAGE,    \
        .owner          = THIS_MODULE,          \
 }
 
 static struct regulator_desc regulators[] = {
-       regulator_desc_ldo(1),
-       regulator_desc_ldo(2),
-       regulator_desc_ldo(3),
-       regulator_desc_ldo(4),
-       regulator_desc_ldo(5),
-       regulator_desc_ldo(6),
-       regulator_desc_ldo(7),
-       regulator_desc_ldo(8),
-       regulator_desc_ldo(9),
-       regulator_desc_ldo(10),
-       regulator_desc_ldo(11),
-       regulator_desc_ldo(12),
-       regulator_desc_ldo(13),
-       regulator_desc_ldo(14),
-       regulator_desc_ldo(15),
-       regulator_desc_ldo(16),
-       regulator_desc_ldo(17),
-       regulator_desc_ldo(18),
-       regulator_desc_ldo(19),
-       regulator_desc_ldo(20),
-       regulator_desc_ldo(21),
-       regulator_desc_ldo(22),
-       regulator_desc_ldo(23),
-       regulator_desc_ldo(24),
-       regulator_desc_ldo(25),
-       regulator_desc_ldo(26),
-       regulator_desc_ldo(27),
-       regulator_desc_ldo(28),
-       regulator_desc_buck(1),
-       regulator_desc_buck(2),
-       regulator_desc_buck(3),
-       regulator_desc_buck(4),
-       regulator_desc_buck(5),
-       regulator_desc_buck(6),
-       regulator_desc_buck(7),
-       regulator_desc_buck(8),
-       regulator_desc_buck(9),
+       s5m8767_regulator_desc(LDO1),
+       s5m8767_regulator_desc(LDO2),
+       s5m8767_regulator_desc(LDO3),
+       s5m8767_regulator_desc(LDO4),
+       s5m8767_regulator_desc(LDO5),
+       s5m8767_regulator_desc(LDO6),
+       s5m8767_regulator_desc(LDO7),
+       s5m8767_regulator_desc(LDO8),
+       s5m8767_regulator_desc(LDO9),
+       s5m8767_regulator_desc(LDO10),
+       s5m8767_regulator_desc(LDO11),
+       s5m8767_regulator_desc(LDO12),
+       s5m8767_regulator_desc(LDO13),
+       s5m8767_regulator_desc(LDO14),
+       s5m8767_regulator_desc(LDO15),
+       s5m8767_regulator_desc(LDO16),
+       s5m8767_regulator_desc(LDO17),
+       s5m8767_regulator_desc(LDO18),
+       s5m8767_regulator_desc(LDO19),
+       s5m8767_regulator_desc(LDO20),
+       s5m8767_regulator_desc(LDO21),
+       s5m8767_regulator_desc(LDO22),
+       s5m8767_regulator_desc(LDO23),
+       s5m8767_regulator_desc(LDO24),
+       s5m8767_regulator_desc(LDO25),
+       s5m8767_regulator_desc(LDO26),
+       s5m8767_regulator_desc(LDO27),
+       s5m8767_regulator_desc(LDO28),
+       s5m8767_regulator_desc(BUCK1),
+       s5m8767_regulator_desc(BUCK2),
+       s5m8767_regulator_desc(BUCK3),
+       s5m8767_regulator_desc(BUCK4),
+       s5m8767_regulator_desc(BUCK5),
+       s5m8767_regulator_desc(BUCK6),
+       s5m8767_regulator_desc(BUCK7),
+       s5m8767_regulator_desc(BUCK8),
+       s5m8767_regulator_desc(BUCK9),
 };
 
 static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
 {
        struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev);
+       struct regulator_config config = { };
        struct regulator_dev **rdev;
        struct s5m8767_info *s5m8767;
        int i, ret, size;
@@ -586,6 +575,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
        s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
        s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
        s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
+       s5m8767->opmode = pdata->opmode;
 
        for (i = 0; i < 8; i++) {
                if (s5m8767->buck2_gpiodvs) {
@@ -723,8 +713,11 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
                        regulators[id].n_voltages =
                                (desc->max - desc->min) / desc->step + 1;
 
-               rdev[i] = regulator_register(&regulators[id], s5m8767->dev,
-                               pdata->regulators[i].initdata, s5m8767, NULL);
+               config.dev = s5m8767->dev;
+               config.init_data = pdata->regulators[i].initdata;
+               config.driver_data = s5m8767;
+
+               rdev[i] = regulator_register(&regulators[id], &config);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(s5m8767->dev, "regulator init failed for %d\n",
index d9278da18a9e9cede299722093977e2c572ccd3d..d840d8440a91691b0954f5cb84fd134c1118f036 100644 (file)
@@ -123,7 +123,7 @@ static struct regulator_ops tps6105x_regulator_ops = {
        .list_voltage   = tps6105x_regulator_list_voltage,
 };
 
-static struct regulator_desc tps6105x_regulator_desc = {
+static const struct regulator_desc tps6105x_regulator_desc = {
        .name           = "tps6105x-boost",
        .ops            = &tps6105x_regulator_ops,
        .type           = REGULATOR_VOLTAGE,
@@ -139,6 +139,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
 {
        struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
        struct tps6105x_platform_data *pdata = tps6105x->pdata;
+       struct regulator_config config = { };
        int ret;
 
        /* This instance is not set for regulator mode so bail out */
@@ -148,11 +149,13 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
                return 0;
        }
 
+       config.dev = &tps6105x->client->dev;
+       config.init_data = pdata->regulator_data;
+       config.driver_data = tps6105x;
+
        /* Register regulator with framework */
        tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
-                                            &tps6105x->client->dev,
-                                            pdata->regulator_data, tps6105x,
-                                            NULL);
+                                                &config);
        if (IS_ERR(tps6105x->regulator)) {
                ret = PTR_ERR(tps6105x->regulator);
                dev_err(&tps6105x->client->dev,
index e2ec73068ee2e1aac58fb0558697840d42e13f96..0657c98352de05f76041196f7abb3e36604a7dc0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * tps62360.c -- TI tps62360
  *
- * Driver for processor core supply tps62360 and tps62361B
+ * Driver for processor core supply tps62360, tps62361B, tps62362 and tps62363.
  *
  * Copyright (c) 2012, NVIDIA Corporation.
  *
@@ -46,7 +46,7 @@
 #define REG_RAMPCTRL           6
 #define REG_CHIPID             8
 
-enum chips {TPS62360, TPS62361};
+enum chips {TPS62360, TPS62361, TPS62362, TPS62363};
 
 #define TPS62360_BASE_VOLTAGE  770
 #define TPS62360_N_VOLTAGES    64
@@ -56,10 +56,8 @@ enum chips {TPS62360, TPS62361};
 
 /* tps 62360 chip information */
 struct tps62360_chip {
-       const char *name;
        struct device *dev;
        struct regulator_desc desc;
-       struct i2c_client *client;
        struct regulator_dev *rdev;
        struct regmap *regmap;
        int chip_id;
@@ -272,6 +270,7 @@ static const struct regmap_config tps62360_regmap_config = {
 static int __devinit tps62360_probe(struct i2c_client *client,
                                     const struct i2c_device_id *id)
 {
+       struct regulator_config config = { };
        struct tps62360_regulator_platform_data *pdata;
        struct regulator_dev *rdev;
        struct tps62360_chip *tps;
@@ -297,21 +296,31 @@ static int __devinit tps62360_probe(struct i2c_client *client,
        tps->en_internal_pulldn = pdata->en_internal_pulldn;
        tps->vsel0_gpio = pdata->vsel0_gpio;
        tps->vsel1_gpio = pdata->vsel1_gpio;
-       tps->client = client;
        tps->dev = &client->dev;
-       tps->name = id->name;
-       tps->voltage_base = (id->driver_data == TPS62360) ?
-                               TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE;
-       tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F;
+
+       switch (id->driver_data) {
+       case TPS62360:
+       case TPS62362:
+               tps->voltage_base = TPS62360_BASE_VOLTAGE;
+               tps->voltage_reg_mask = 0x3F;
+               tps->desc.n_voltages = TPS62360_N_VOLTAGES;
+               break;
+       case TPS62361:
+       case TPS62363:
+               tps->voltage_base = TPS62361_BASE_VOLTAGE;
+               tps->voltage_reg_mask = 0x7F;
+               tps->desc.n_voltages = TPS62361_N_VOLTAGES;
+               break;
+       default:
+               return -ENODEV;
+       }
 
        tps->desc.name = id->name;
        tps->desc.id = 0;
-       tps->desc.n_voltages = (id->driver_data == TPS62360) ?
-                               TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES;
        tps->desc.ops = &tps62360_dcdc_ops;
        tps->desc.type = REGULATOR_VOLTAGE;
        tps->desc.owner = THIS_MODULE;
-       tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config);
+       tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config);
        if (IS_ERR(tps->regmap)) {
                ret = PTR_ERR(tps->regmap);
                dev_err(&client->dev, "%s() Err: Failed to allocate register"
@@ -376,9 +385,12 @@ static int __devinit tps62360_probe(struct i2c_client *client,
                goto err_init;
        }
 
+       config.dev = &client->dev;
+       config.init_data = &pdata->reg_init_data;
+       config.driver_data = tps;
+
        /* Register the regulators */
-       rdev = regulator_register(&tps->desc, &client->dev,
-                               &pdata->reg_init_data, tps, NULL);
+       rdev = regulator_register(&tps->desc, &config);
        if (IS_ERR(rdev)) {
                dev_err(tps->dev, "%s() Err: Failed to register %s\n",
                                __func__, id->name);
@@ -396,7 +408,6 @@ err_gpio1:
        if (gpio_is_valid(tps->vsel0_gpio))
                gpio_free(tps->vsel0_gpio);
 err_gpio0:
-       regmap_exit(tps->regmap);
        return ret;
 }
 
@@ -417,7 +428,6 @@ static int __devexit tps62360_remove(struct i2c_client *client)
                gpio_free(tps->vsel0_gpio);
 
        regulator_unregister(tps->rdev);
-       regmap_exit(tps->regmap);
        return 0;
 }
 
@@ -439,6 +449,8 @@ static void tps62360_shutdown(struct i2c_client *client)
 static const struct i2c_device_id tps62360_id[] = {
        {.name = "tps62360", .driver_data = TPS62360},
        {.name = "tps62361", .driver_data = TPS62361},
+       {.name = "tps62362", .driver_data = TPS62362},
+       {.name = "tps62363", .driver_data = TPS62363},
        {},
 };
 
@@ -468,5 +480,5 @@ static void __exit tps62360_cleanup(void)
 module_exit(tps62360_cleanup);
 
 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
-MODULE_DESCRIPTION("TPS62360 voltage regulator driver");
+MODULE_DESCRIPTION("TPS6236x voltage regulator driver");
 MODULE_LICENSE("GPL v2");
index 43e4902d7af87485afbea85ace607d10e0045155..a1fd65682f4c888b018dde07bab72125b11381e0 100644 (file)
@@ -72,7 +72,7 @@
 
 /* LDO_CTRL bitfields */
 #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id)   ((ldo_id)*4)
-#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id)    (0xF0 >> ((ldo_id)*4))
+#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id)    (0x0F << ((ldo_id)*4))
 
 /* Number of step-down converters available */
 #define TPS65023_NUM_DCDC              3
@@ -139,7 +139,6 @@ struct tps_info {
 /* PMIC details */
 struct tps_pmic {
        struct regulator_desc desc[TPS65023_NUM_REGULATOR];
-       struct i2c_client *client;
        struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
        const struct tps_info *info[TPS65023_NUM_REGULATOR];
        struct regmap *regmap;
@@ -152,96 +151,6 @@ struct tps_driver_data {
        u8 core_regulator;
 };
 
-static int tps65023_dcdc_is_enabled(struct regulator_dev *dev)
-{
-       struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int data, dcdc = rdev_get_id(dev);
-       int ret;
-       u8 shift;
-
-       if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
-               return -EINVAL;
-
-       shift = TPS65023_NUM_REGULATOR - dcdc;
-       ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
-
-       if (ret != 0)
-               return ret;
-       else
-               return (data & 1<<shift) ? 1 : 0;
-}
-
-static int tps65023_ldo_is_enabled(struct regulator_dev *dev)
-{
-       struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int data, ldo = rdev_get_id(dev);
-       int ret;
-       u8 shift;
-
-       if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
-               return -EINVAL;
-
-       shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
-       ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
-
-       if (ret != 0)
-               return ret;
-       else
-               return (data & 1<<shift) ? 1 : 0;
-}
-
-static int tps65023_dcdc_enable(struct regulator_dev *dev)
-{
-       struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int dcdc = rdev_get_id(dev);
-       u8 shift;
-
-       if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
-               return -EINVAL;
-
-       shift = TPS65023_NUM_REGULATOR - dcdc;
-       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
-}
-
-static int tps65023_dcdc_disable(struct regulator_dev *dev)
-{
-       struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int dcdc = rdev_get_id(dev);
-       u8 shift;
-
-       if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
-               return -EINVAL;
-
-       shift = TPS65023_NUM_REGULATOR - dcdc;
-       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
-}
-
-static int tps65023_ldo_enable(struct regulator_dev *dev)
-{
-       struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int ldo = rdev_get_id(dev);
-       u8 shift;
-
-       if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
-               return -EINVAL;
-
-       shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
-       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
-}
-
-static int tps65023_ldo_disable(struct regulator_dev *dev)
-{
-       struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int ldo = rdev_get_id(dev);
-       u8 shift;
-
-       if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
-               return -EINVAL;
-
-       shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
-       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
-}
-
 static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
 {
        struct tps_pmic *tps = rdev_get_drvdata(dev);
@@ -261,50 +170,28 @@ static int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
                return tps->info[dcdc]->min_uV;
 }
 
-static int tps65023_dcdc_set_voltage(struct regulator_dev *dev,
-                                    int min_uV, int max_uV,
-                                    unsigned *selector)
+static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
+                                        unsigned selector)
 {
        struct tps_pmic *tps = rdev_get_drvdata(dev);
        int dcdc = rdev_get_id(dev);
-       int vsel;
        int ret;
 
        if (dcdc != tps->core_regulator)
                return -EINVAL;
-       if (min_uV < tps->info[dcdc]->min_uV
-                       || min_uV > tps->info[dcdc]->max_uV)
-               return -EINVAL;
-       if (max_uV < tps->info[dcdc]->min_uV
-                       || max_uV > tps->info[dcdc]->max_uV)
-               return -EINVAL;
-
-       for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) {
-               int mV = tps->info[dcdc]->table[vsel];
-               int uV = mV * 1000;
-
-               /* Break at the first in-range value */
-               if (min_uV <= uV && uV <= max_uV)
-                       break;
-       }
 
-       *selector = vsel;
-
-       if (vsel == tps->info[dcdc]->table_len)
-               goto failed;
-
-       ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, vsel);
+       ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, selector);
+       if (ret)
+               goto out;
 
        /* Tell the chip that we have changed the value in DEFCORE
         * and its time to update the core voltage
         */
-       regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
-                       TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
+       ret = regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
+                                TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
 
+out:
        return ret;
-
-failed:
-       return -EINVAL;
 }
 
 static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
@@ -325,42 +212,15 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
        return tps->info[ldo]->table[data] * 1000;
 }
 
-static int tps65023_ldo_set_voltage(struct regulator_dev *dev,
-                                   int min_uV, int max_uV, unsigned *selector)
+static int tps65023_ldo_set_voltage_sel(struct regulator_dev *dev,
+                                       unsigned selector)
 {
        struct tps_pmic *tps = rdev_get_drvdata(dev);
-       int data, vsel, ldo = rdev_get_id(dev);
-       int ret;
-
-       if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
-               return -EINVAL;
+       int ldo_index = rdev_get_id(dev) - TPS65023_LDO_1;
 
-       if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV)
-               return -EINVAL;
-       if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV)
-               return -EINVAL;
-
-       for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) {
-               int mV = tps->info[ldo]->table[vsel];
-               int uV = mV * 1000;
-
-               /* Break at the first in-range value */
-               if (min_uV <= uV && uV <= max_uV)
-                       break;
-       }
-
-       if (vsel == tps->info[ldo]->table_len)
-               return -EINVAL;
-
-       *selector = vsel;
-
-       ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
-       if (ret != 0)
-               return ret;
-
-       data &= TPS65023_LDO_CTRL_LDOx_MASK(ldo - TPS65023_LDO_1);
-       data |= (vsel << (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)));
-       return regmap_write(tps->regmap, TPS65023_REG_LDO_CTRL, data);
+       return regmap_update_bits(tps->regmap, TPS65023_REG_LDO_CTRL,
+                       TPS65023_LDO_CTRL_LDOx_MASK(ldo_index),
+                       selector << TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_index));
 }
 
 static int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
@@ -398,21 +258,21 @@ static int tps65023_ldo_list_voltage(struct regulator_dev *dev,
 
 /* Operations permitted on VDCDCx */
 static struct regulator_ops tps65023_dcdc_ops = {
-       .is_enabled = tps65023_dcdc_is_enabled,
-       .enable = tps65023_dcdc_enable,
-       .disable = tps65023_dcdc_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
        .get_voltage = tps65023_dcdc_get_voltage,
-       .set_voltage = tps65023_dcdc_set_voltage,
+       .set_voltage_sel = tps65023_dcdc_set_voltage_sel,
        .list_voltage = tps65023_dcdc_list_voltage,
 };
 
 /* Operations permitted on LDOx */
 static struct regulator_ops tps65023_ldo_ops = {
-       .is_enabled = tps65023_ldo_is_enabled,
-       .enable = tps65023_ldo_enable,
-       .disable = tps65023_ldo_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
        .get_voltage = tps65023_ldo_get_voltage,
-       .set_voltage = tps65023_ldo_set_voltage,
+       .set_voltage_sel = tps65023_ldo_set_voltage_sel,
        .list_voltage = tps65023_ldo_list_voltage,
 };
 
@@ -426,6 +286,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
 {
        const struct tps_driver_data *drv_data = (void *)id->driver_data;
        const struct tps_info *info = drv_data->info;
+       struct regulator_config config = { };
        struct regulator_init_data *init_data;
        struct regulator_dev *rdev;
        struct tps_pmic *tps;
@@ -443,20 +304,19 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
        if (!init_data)
                return -EIO;
 
-       tps = kzalloc(sizeof(*tps), GFP_KERNEL);
+       tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
        if (!tps)
                return -ENOMEM;
 
-       tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config);
+       tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config);
        if (IS_ERR(tps->regmap)) {
                error = PTR_ERR(tps->regmap);
                dev_err(&client->dev, "Failed to allocate register map: %d\n",
                        error);
-               goto fail_alloc;
+               return error;
        }
 
        /* common for all regulators */
-       tps->client = client;
        tps->core_regulator = drv_data->core_regulator;
 
        for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) {
@@ -471,9 +331,22 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
                tps->desc[i].type = REGULATOR_VOLTAGE;
                tps->desc[i].owner = THIS_MODULE;
 
+               tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL;
+               if (i == TPS65023_LDO_1)
+                       tps->desc[i].enable_mask = 1 << 1;
+               else if (i == TPS65023_LDO_2)
+                       tps->desc[i].enable_mask = 1 << 2;
+               else /* DCDCx */
+                       tps->desc[i].enable_mask =
+                                       1 << (TPS65023_NUM_REGULATOR - i);
+
+               config.dev = &client->dev;
+               config.init_data = init_data;
+               config.driver_data = tps;
+               config.regmap = tps->regmap;
+
                /* Register the regulators */
-               rdev = regulator_register(&tps->desc[i], &client->dev,
-                                         init_data, tps, NULL);
+               rdev = regulator_register(&tps->desc[i], &config);
                if (IS_ERR(rdev)) {
                        dev_err(&client->dev, "failed to register %s\n",
                                id->name);
@@ -496,19 +369,9 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
  fail:
        while (--i >= 0)
                regulator_unregister(tps->rdev[i]);
-
-       regmap_exit(tps->regmap);
- fail_alloc:
-       kfree(tps);
        return error;
 }
 
-/**
- * tps_65023_remove - TPS65023 driver i2c remove handler
- * @client: i2c driver client device structure
- *
- * Unregister TPS driver as an i2c client device driver
- */
 static int __devexit tps_65023_remove(struct i2c_client *client)
 {
        struct tps_pmic *tps = i2c_get_clientdata(client);
@@ -516,10 +379,6 @@ static int __devexit tps_65023_remove(struct i2c_client *client)
 
        for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
                regulator_unregister(tps->rdev[i]);
-
-       regmap_exit(tps->regmap);
-       kfree(tps);
-
        return 0;
 }
 
@@ -638,13 +497,13 @@ static struct tps_driver_data tps65020_drv_data = {
 };
 
 static struct tps_driver_data tps65021_drv_data = {
-               .info = tps65021_regs,
-               .core_regulator = TPS65023_DCDC_3,
+       .info = tps65021_regs,
+       .core_regulator = TPS65023_DCDC_3,
 };
 
 static struct tps_driver_data tps65023_drv_data = {
-               .info = tps65023_regs,
-               .core_regulator = TPS65023_DCDC_1,
+       .info = tps65023_regs,
+       .core_regulator = TPS65023_DCDC_1,
 };
 
 static const struct i2c_device_id tps_65023_id[] = {
@@ -669,22 +528,12 @@ static struct i2c_driver tps_65023_i2c_driver = {
        .id_table = tps_65023_id,
 };
 
-/**
- * tps_65023_init
- *
- * Module init function
- */
 static int __init tps_65023_init(void)
 {
        return i2c_add_driver(&tps_65023_i2c_driver);
 }
 subsys_initcall(tps_65023_init);
 
-/**
- * tps_65023_cleanup
- *
- * Module exit function
- */
 static void __exit tps_65023_cleanup(void)
 {
        i2c_del_driver(&tps_65023_i2c_driver);
index 832833fe8aad327c1a969a54aa95405c81076280..8e432004b949ca2a22ce4f64e8392446b2f51316 100644 (file)
@@ -404,6 +404,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
 {
        struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
        struct tps_info *info = &tps6507x_pmic_regs[0];
+       struct regulator_config config = { };
        struct regulator_init_data *init_data;
        struct regulator_dev *rdev;
        struct tps6507x_pmic *tps;
@@ -428,7 +429,7 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
        if (!init_data)
                return -EINVAL;
 
-       tps = kzalloc(sizeof(*tps), GFP_KERNEL);
+       tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL);
        if (!tps)
                return -ENOMEM;
 
@@ -453,8 +454,11 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
                tps->desc[i].type = REGULATOR_VOLTAGE;
                tps->desc[i].owner = THIS_MODULE;
 
-               rdev = regulator_register(&tps->desc[i],
-                                       tps6507x_dev->dev, init_data, tps, NULL);
+               config.dev = tps6507x_dev->dev;
+               config.init_data = init_data;
+               config.driver_data = tps;
+
+               rdev = regulator_register(&tps->desc[i], &config);
                if (IS_ERR(rdev)) {
                        dev_err(tps6507x_dev->dev,
                                "failed to register %s regulator\n",
@@ -475,8 +479,6 @@ static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
 fail:
        while (--i >= 0)
                regulator_unregister(tps->rdev[i]);
-
-       kfree(tps);
        return error;
 }
 
@@ -488,9 +490,6 @@ static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
 
        for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
                regulator_unregister(tps->rdev[i]);
-
-       kfree(tps);
-
        return 0;
 }
 
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c
new file mode 100644 (file)
index 0000000..661fcec
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Regulator driver for tps65090 power management chip.
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/tps65090.h>
+#include <linux/regulator/tps65090-regulator.h>
+
+struct tps65090_regulator {
+       int             id;
+       /* used by regulator core */
+       struct regulator_desc   desc;
+
+       /* Device */
+       struct device           *dev;
+};
+
+static struct regulator_ops tps65090_ops = {
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+};
+
+#define tps65090_REG(_id)                              \
+{                                                      \
+       .id             = TPS65090_ID_##_id,            \
+       .desc = {                                       \
+               .name = tps65090_rails(_id),            \
+               .id = TPS65090_ID_##_id,                \
+               .ops = &tps65090_ops,                   \
+               .type = REGULATOR_VOLTAGE,              \
+               .owner = THIS_MODULE,                   \
+               .enable_reg = (TPS65090_ID_##_id) + 12, \
+               .enable_mask = BIT(0),                  \
+       },                                              \
+}
+
+static struct tps65090_regulator TPS65090_regulator[] = {
+       tps65090_REG(DCDC1),
+       tps65090_REG(DCDC2),
+       tps65090_REG(DCDC3),
+       tps65090_REG(FET1),
+       tps65090_REG(FET2),
+       tps65090_REG(FET3),
+       tps65090_REG(FET4),
+       tps65090_REG(FET5),
+       tps65090_REG(FET6),
+       tps65090_REG(FET7),
+};
+
+static inline struct tps65090_regulator *find_regulator_info(int id)
+{
+       struct tps65090_regulator *ri;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) {
+               ri = &TPS65090_regulator[i];
+               if (ri->desc.id == id)
+                       return ri;
+       }
+       return NULL;
+}
+
+static int __devinit tps65090_regulator_probe(struct platform_device *pdev)
+{
+       struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
+       struct tps65090_regulator *ri = NULL;
+       struct regulator_config config = { };
+       struct regulator_dev *rdev;
+       struct tps65090_regulator_platform_data *tps_pdata;
+       int id = pdev->id;
+
+       dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
+
+       ri = find_regulator_info(id);
+       if (ri == NULL) {
+               dev_err(&pdev->dev, "invalid regulator ID specified\n");
+               return -EINVAL;
+       }
+       tps_pdata = pdev->dev.platform_data;
+       ri->dev = &pdev->dev;
+
+       config.dev = &pdev->dev;
+       config.init_data = &tps_pdata->regulator;
+       config.driver_data = ri;
+       config.regmap = tps65090_mfd->rmap;
+
+       rdev = regulator_register(&ri->desc, &config);
+       if (IS_ERR(rdev)) {
+               dev_err(&pdev->dev, "failed to register regulator %s\n",
+                               ri->desc.name);
+               return PTR_ERR(rdev);
+       }
+
+       platform_set_drvdata(pdev, rdev);
+       return 0;
+}
+
+static int __devexit tps65090_regulator_remove(struct platform_device *pdev)
+{
+       struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+       regulator_unregister(rdev);
+       return 0;
+}
+
+static struct platform_driver tps65090_regulator_driver = {
+       .driver = {
+               .name   = "tps65090-regulator",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = tps65090_regulator_probe,
+       .remove         = __devexit_p(tps65090_regulator_remove),
+};
+
+static int __init tps65090_regulator_init(void)
+{
+       return platform_driver_register(&tps65090_regulator_driver);
+}
+subsys_initcall(tps65090_regulator_init);
+
+static void __exit tps65090_regulator_exit(void)
+{
+       platform_driver_unregister(&tps65090_regulator_driver);
+}
+module_exit(tps65090_regulator_exit);
+
+MODULE_DESCRIPTION("tps65090 regulator driver");
+MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
+MODULE_LICENSE("GPL v2");
index e39521b427723179f192fecbbba69ee50d2d7e06..00c5c1c96d193abc303d718fdd90a5100e158162 100644 (file)
@@ -312,7 +312,7 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = {
        .list_voltage           = tps65217_pmic_list_voltage,
 };
 
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
        TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, tps65217_pmic_ops, 64),
        TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, tps65217_pmic_ops, 64),
        TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, tps65217_pmic_ops, 64),
@@ -327,13 +327,17 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
        struct regulator_dev *rdev;
        struct tps65217 *tps;
        struct tps_info *info = &tps65217_pmic_regs[pdev->id];
+       struct regulator_config config = { };
 
        /* Already set by core driver */
        tps = dev_to_tps65217(pdev->dev.parent);
        tps->info[pdev->id] = info;
 
-       rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data, tps, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = tps;
+
+       rdev = regulator_register(&regulators[pdev->id], &config);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
index 4a421be6d4f2fa7d7b700b43a24367d354b0a020..b88b3df82381dc15bb81288c32874480a3eaad94 100644 (file)
@@ -458,12 +458,10 @@ static int list_voltage(struct regulator_dev *rdev, unsigned selector)
                info->voltages[selector] : -EINVAL);
 }
 
-static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
-                      unsigned *selector)
+static int set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 {
        const struct supply_info *info;
        struct tps6524x *hw;
-       unsigned i;
 
        hw      = rdev_get_drvdata(rdev);
        info    = &supply_info[rdev_get_id(rdev)];
@@ -471,20 +469,10 @@ static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
        if (info->flags & FIXED_VOLTAGE)
                return -EINVAL;
 
-       for (i = 0; i < info->n_voltages; i++)
-               if (min_uV <= info->voltages[i] &&
-                   max_uV >= info->voltages[i])
-                       break;
-
-       if (i >= info->n_voltages)
-               i = info->n_voltages - 1;
-
-       *selector = i;
-
-       return write_field(hw, &info->voltage, i);
+       return write_field(hw, &info->voltage, selector);
 }
 
-static int get_voltage(struct regulator_dev *rdev)
+static int get_voltage_sel(struct regulator_dev *rdev)
 {
        const struct supply_info *info;
        struct tps6524x *hw;
@@ -502,7 +490,7 @@ static int get_voltage(struct regulator_dev *rdev)
        if (WARN_ON(ret >= info->n_voltages))
                return -EIO;
 
-       return info->voltages[ret];
+       return ret;
 }
 
 static int set_current_limit(struct regulator_dev *rdev, int min_uA,
@@ -587,8 +575,8 @@ static struct regulator_ops regulator_ops = {
        .is_enabled             = is_supply_enabled,
        .enable                 = enable_supply,
        .disable                = disable_supply,
-       .get_voltage            = get_voltage,
-       .set_voltage            = set_voltage,
+       .get_voltage_sel        = get_voltage_sel,
+       .set_voltage_sel        = set_voltage_sel,
        .list_voltage           = list_voltage,
        .set_current_limit      = set_current_limit,
        .get_current_limit      = get_current_limit,
@@ -607,7 +595,6 @@ static int pmic_remove(struct spi_device *spi)
                hw->rdev[i] = NULL;
        }
        spi_set_drvdata(spi, NULL);
-       kfree(hw);
        return 0;
 }
 
@@ -617,6 +604,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
        struct device *dev = &spi->dev;
        const struct supply_info *info = supply_info;
        struct regulator_init_data *init_data;
+       struct regulator_config config = { };
        int ret = 0, i;
 
        init_data = dev->platform_data;
@@ -625,7 +613,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
                return -EINVAL;
        }
 
-       hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL);
+       hw = devm_kzalloc(&spi->dev, sizeof(struct tps6524x), GFP_KERNEL);
        if (!hw) {
                dev_err(dev, "cannot allocate regulator private data\n");
                return -ENOMEM;
@@ -648,8 +636,11 @@ static int __devinit pmic_probe(struct spi_device *spi)
                if (info->flags & FIXED_VOLTAGE)
                        hw->desc[i].n_voltages = 1;
 
-               hw->rdev[i] = regulator_register(&hw->desc[i], dev,
-                                                init_data, hw, NULL);
+               config.dev = dev;
+               config.init_data = init_data;
+               config.driver_data = hw;
+
+               hw->rdev[i] = regulator_register(&hw->desc[i], &config);
                if (IS_ERR(hw->rdev[i])) {
                        ret = PTR_ERR(hw->rdev[i]);
                        hw->rdev[i] = NULL;
@@ -673,17 +664,7 @@ static struct spi_driver pmic_driver = {
        },
 };
 
-static int __init pmic_driver_init(void)
-{
-       return spi_register_driver(&pmic_driver);
-}
-module_init(pmic_driver_init);
-
-static void __exit pmic_driver_exit(void)
-{
-       spi_unregister_driver(&pmic_driver);
-}
-module_exit(pmic_driver_exit);
+module_spi_driver(pmic_driver);
 
 MODULE_DESCRIPTION("TPS6524X PMIC Driver");
 MODULE_AUTHOR("Cyril Chemparathy");
index cfc1f16f777125152678dfbdef3402d28e80c1cd..9a4029a446d3cb516c63b27a05917c62137ed35e 100644 (file)
@@ -75,8 +75,7 @@ static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev)
        return rdev_get_dev(rdev)->parent->parent;
 }
 
-static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev,
-                                    unsigned selector)
+static int tps6586x_list_voltage(struct regulator_dev *rdev, unsigned selector)
 {
        struct tps6586x_regulator *info = rdev_get_drvdata(rdev);
        int rid = rdev_get_id(rdev);
@@ -89,47 +88,34 @@ static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev,
 }
 
 
-static int __tps6586x_ldo_set_voltage(struct device *parent,
-                                     struct tps6586x_regulator *ri,
-                                     int min_uV, int max_uV,
-                                     unsigned *selector)
+static int tps6586x_set_voltage_sel(struct regulator_dev *rdev,
+                                   unsigned selector)
 {
-       int val, uV;
+       struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
+       struct device *parent = to_tps6586x_dev(rdev);
+       int ret, val, rid = rdev_get_id(rdev);
        uint8_t mask;
 
-       for (val = 0; val < ri->desc.n_voltages; val++) {
-               uV = ri->voltages[val] * 1000;
-
-               /* LDO0 has minimal voltage 1.2 rather than 1.25 */
-               if (ri->desc.id == TPS6586X_ID_LDO_0 && val == 0)
-                       uV -= 50 * 1000;
-
-               /* use the first in-range value */
-               if (min_uV <= uV && uV <= max_uV) {
-
-                       *selector = val;
+       val = selector << ri->volt_shift;
+       mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
 
-                       val <<= ri->volt_shift;
-                       mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift;
+       ret = tps6586x_update(parent, ri->volt_reg, val, mask);
+       if (ret)
+               return ret;
 
-                       return tps6586x_update(parent, ri->volt_reg, val, mask);
-               }
+       /* Update go bit for DVM regulators */
+       switch (rid) {
+       case TPS6586X_ID_LDO_2:
+       case TPS6586X_ID_LDO_4:
+       case TPS6586X_ID_SM_0:
+       case TPS6586X_ID_SM_1:
+               ret = tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
+               break;
        }
-
-       return -EINVAL;
-}
-
-static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev,
-                                   int min_uV, int max_uV, unsigned *selector)
-{
-       struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
-       struct device *parent = to_tps6586x_dev(rdev);
-
-       return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV,
-                                         selector);
+       return ret;
 }
 
-static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
+static int tps6586x_get_voltage_sel(struct regulator_dev *rdev)
 {
        struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
        struct device *parent = to_tps6586x_dev(rdev);
@@ -146,22 +132,7 @@ static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev)
        if (val >= ri->desc.n_voltages)
                BUG();
 
-       return ri->voltages[val] * 1000;
-}
-
-static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev,
-                                   int min_uV, int max_uV, unsigned *selector)
-{
-       struct tps6586x_regulator *ri = rdev_get_drvdata(rdev);
-       struct device *parent = to_tps6586x_dev(rdev);
-       int ret;
-
-       ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV,
-                                        selector);
-       if (ret)
-               return ret;
-
-       return tps6586x_set_bits(parent, ri->go_reg, 1 << ri->go_bit);
+       return val;
 }
 
 static int tps6586x_regulator_enable(struct regulator_dev *rdev)
@@ -196,20 +167,10 @@ static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev)
        return !!(reg_val & (1 << ri->enable_bit[0]));
 }
 
-static struct regulator_ops tps6586x_regulator_ldo_ops = {
-       .list_voltage = tps6586x_ldo_list_voltage,
-       .get_voltage = tps6586x_ldo_get_voltage,
-       .set_voltage = tps6586x_ldo_set_voltage,
-
-       .is_enabled = tps6586x_regulator_is_enabled,
-       .enable = tps6586x_regulator_enable,
-       .disable = tps6586x_regulator_disable,
-};
-
-static struct regulator_ops tps6586x_regulator_dvm_ops = {
-       .list_voltage = tps6586x_ldo_list_voltage,
-       .get_voltage = tps6586x_ldo_get_voltage,
-       .set_voltage = tps6586x_dvm_set_voltage,
+static struct regulator_ops tps6586x_regulator_ops = {
+       .list_voltage = tps6586x_list_voltage,
+       .get_voltage_sel = tps6586x_get_voltage_sel,
+       .set_voltage_sel = tps6586x_set_voltage_sel,
 
        .is_enabled = tps6586x_regulator_is_enabled,
        .enable = tps6586x_regulator_enable,
@@ -241,11 +202,11 @@ static int tps6586x_dvm_voltages[] = {
        1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500,
 };
 
-#define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits,       \
+#define TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits,             \
                           ereg0, ebit0, ereg1, ebit1)                  \
        .desc   = {                                                     \
                .name   = "REG-" #_id,                                  \
-               .ops    = &tps6586x_regulator_##_ops,                   \
+               .ops    = &tps6586x_regulator_ops,                      \
                .type   = REGULATOR_VOLTAGE,                            \
                .id     = TPS6586X_ID_##_id,                            \
                .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages),  \
@@ -267,14 +228,14 @@ static int tps6586x_dvm_voltages[] = {
 #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1)                        \
 {                                                                      \
-       TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits,     \
+       TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits,              \
                           ereg0, ebit0, ereg1, ebit1)                  \
 }
 
 #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1, goreg, gobit)          \
 {                                                                      \
-       TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits,     \
+       TPS6586X_REGULATOR(_id, vdata, vreg, shift, nbits,              \
                           ereg0, ebit0, ereg1, ebit1)                  \
        TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                      \
 }
@@ -384,6 +345,7 @@ static inline struct tps6586x_regulator *find_regulator_info(int id)
 static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
 {
        struct tps6586x_regulator *ri = NULL;
+       struct regulator_config config = { };
        struct regulator_dev *rdev;
        int id = pdev->id;
        int err;
@@ -400,8 +362,11 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
        if (err)
                return err;
 
-       rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdev->dev.platform_data, ri, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = ri;
+
+       rdev = regulator_register(&ri->desc, &config);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
index 4a37c2b6367fa3c6b8d926205e7719f4e4b5c4c9..43bc6c6bc8f8328cdab9d02f25b86f8b4cd5db32 100644 (file)
@@ -467,48 +467,6 @@ static int tps65911_get_ctrl_register(int id)
        }
 }
 
-static int tps65910_is_enabled(struct regulator_dev *dev)
-{
-       struct tps65910_reg *pmic = rdev_get_drvdata(dev);
-       int reg, value, id = rdev_get_id(dev);
-
-       reg = pmic->get_ctrl_reg(id);
-       if (reg < 0)
-               return reg;
-
-       value = tps65910_reg_read(pmic, reg);
-       if (value < 0)
-               return value;
-
-       return value & TPS65910_SUPPLY_STATE_ENABLED;
-}
-
-static int tps65910_enable(struct regulator_dev *dev)
-{
-       struct tps65910_reg *pmic = rdev_get_drvdata(dev);
-       struct tps65910 *mfd = pmic->mfd;
-       int reg, id = rdev_get_id(dev);
-
-       reg = pmic->get_ctrl_reg(id);
-       if (reg < 0)
-               return reg;
-
-       return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
-}
-
-static int tps65910_disable(struct regulator_dev *dev)
-{
-       struct tps65910_reg *pmic = rdev_get_drvdata(dev);
-       struct tps65910 *mfd = pmic->mfd;
-       int reg, id = rdev_get_id(dev);
-
-       reg = pmic->get_ctrl_reg(id);
-       if (reg < 0)
-               return reg;
-
-       return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
-}
-
 static int tps65910_enable_time(struct regulator_dev *dev)
 {
        struct tps65910_reg *pmic = rdev_get_drvdata(dev);
@@ -914,9 +872,9 @@ static int tps65910_set_voltage_dcdc_time_sel(struct regulator_dev *dev,
 
 /* Regulator ops (except VRTC) */
 static struct regulator_ops tps65910_ops_dcdc = {
-       .is_enabled             = tps65910_is_enabled,
-       .enable                 = tps65910_enable,
-       .disable                = tps65910_disable,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
        .enable_time            = tps65910_enable_time,
        .set_mode               = tps65910_set_mode,
        .get_mode               = tps65910_get_mode,
@@ -927,9 +885,9 @@ static struct regulator_ops tps65910_ops_dcdc = {
 };
 
 static struct regulator_ops tps65910_ops_vdd3 = {
-       .is_enabled             = tps65910_is_enabled,
-       .enable                 = tps65910_enable,
-       .disable                = tps65910_disable,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
        .enable_time            = tps65910_enable_time,
        .set_mode               = tps65910_set_mode,
        .get_mode               = tps65910_get_mode,
@@ -938,9 +896,9 @@ static struct regulator_ops tps65910_ops_vdd3 = {
 };
 
 static struct regulator_ops tps65910_ops = {
-       .is_enabled             = tps65910_is_enabled,
-       .enable                 = tps65910_enable,
-       .disable                = tps65910_disable,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
        .enable_time            = tps65910_enable_time,
        .set_mode               = tps65910_set_mode,
        .get_mode               = tps65910_get_mode,
@@ -950,9 +908,9 @@ static struct regulator_ops tps65910_ops = {
 };
 
 static struct regulator_ops tps65911_ops = {
-       .is_enabled             = tps65910_is_enabled,
-       .enable                 = tps65910_enable,
-       .disable                = tps65910_disable,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
        .enable_time            = tps65910_enable_time,
        .set_mode               = tps65910_set_mode,
        .get_mode               = tps65910_get_mode,
@@ -1097,6 +1055,7 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
 static __devinit int tps65910_probe(struct platform_device *pdev)
 {
        struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_config config = { };
        struct tps_info *info;
        struct regulator_init_data *reg_data;
        struct regulator_dev *rdev;
@@ -1108,7 +1067,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
        if (!pmic_plat_data)
                return -EINVAL;
 
-       pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
+       pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
        if (!pmic)
                return -ENOMEM;
 
@@ -1135,7 +1094,6 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
                break;
        default:
                pr_err("Invalid tps chip version\n");
-               kfree(pmic);
                return -ENODEV;
        }
 
@@ -1143,7 +1101,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
                        sizeof(struct regulator_desc), GFP_KERNEL);
        if (!pmic->desc) {
                err = -ENOMEM;
-               goto err_free_pmic;
+               goto err_out;
        }
 
        pmic->info = kcalloc(pmic->num_regulators,
@@ -1205,9 +1163,15 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
 
                pmic->desc[i].type = REGULATOR_VOLTAGE;
                pmic->desc[i].owner = THIS_MODULE;
+               pmic->desc[i].enable_reg = pmic->get_ctrl_reg(i);
+               pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED;
+
+               config.dev = tps65910->dev;
+               config.init_data = reg_data;
+               config.driver_data = pmic;
+               config.regmap = tps65910->regmap;
 
-               rdev = regulator_register(&pmic->desc[i],
-                               tps65910->dev, reg_data, pmic, NULL);
+               rdev = regulator_register(&pmic->desc[i], &config);
                if (IS_ERR(rdev)) {
                        dev_err(tps65910->dev,
                                "failed to register %s regulator\n",
@@ -1229,8 +1193,7 @@ err_free_info:
        kfree(pmic->info);
 err_free_desc:
        kfree(pmic->desc);
-err_free_pmic:
-       kfree(pmic);
+err_out:
        return err;
 }
 
@@ -1245,7 +1208,6 @@ static int __devexit tps65910_remove(struct platform_device *pdev)
        kfree(pmic->rdev);
        kfree(pmic->info);
        kfree(pmic->desc);
-       kfree(pmic);
        return 0;
 }
 
index b36799b1f530d0bf81484d471eea483c30a4914e..af335dd35903ca03a3d5bde75aa5e7d75d9d35bb 100644 (file)
@@ -372,12 +372,14 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev)
        return mode;
 }
 
-static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
-                                       unsigned selector)
+static int tps65912_list_voltage(struct regulator_dev *dev, unsigned selector)
 {
        struct tps65912_reg *pmic = rdev_get_drvdata(dev);
        int range, voltage = 0, id = rdev_get_id(dev);
 
+       if (id >= TPS65912_REG_LDO1 && id <= TPS65912_REG_LDO10)
+               return tps65912_vsel_to_uv_ldo(selector);
+
        if (id > TPS65912_REG_DCDC4)
                return -EINVAL;
 
@@ -404,7 +406,7 @@ static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
        return voltage;
 }
 
-static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
+static int tps65912_get_voltage(struct regulator_dev *dev)
 {
        struct tps65912_reg *pmic = rdev_get_drvdata(dev);
        struct tps65912 *mfd = pmic->mfd;
@@ -418,7 +420,7 @@ static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
        vsel = tps65912_reg_read(mfd, reg);
        vsel &= 0x3F;
 
-       return tps65912_list_voltage_dcdc(dev, vsel);
+       return tps65912_list_voltage(dev, vsel);
 }
 
 static int tps65912_set_voltage_sel(struct regulator_dev *dev,
@@ -436,32 +438,6 @@ static int tps65912_set_voltage_sel(struct regulator_dev *dev,
        return tps65912_reg_write(mfd, reg, selector | value);
 }
 
-static int tps65912_get_voltage_ldo(struct regulator_dev *dev)
-{
-       struct tps65912_reg *pmic = rdev_get_drvdata(dev);
-       struct tps65912 *mfd = pmic->mfd;
-       int id = rdev_get_id(dev);
-       int vsel = 0;
-       u8 reg;
-
-       reg = tps65912_get_sel_register(pmic, id);
-       vsel = tps65912_reg_read(mfd, reg);
-       vsel &= 0x3F;
-
-       return tps65912_vsel_to_uv_ldo(vsel);
-}
-
-static int tps65912_list_voltage_ldo(struct regulator_dev *dev,
-                                       unsigned selector)
-{
-       int ldo = rdev_get_id(dev);
-
-       if (ldo < TPS65912_REG_LDO1 || ldo > TPS65912_REG_LDO10)
-               return -EINVAL;
-
-       return tps65912_vsel_to_uv_ldo(selector);
-}
-
 /* Operations permitted on DCDCx */
 static struct regulator_ops tps65912_ops_dcdc = {
        .is_enabled = tps65912_reg_is_enabled,
@@ -469,9 +445,9 @@ static struct regulator_ops tps65912_ops_dcdc = {
        .disable = tps65912_reg_disable,
        .set_mode = tps65912_set_mode,
        .get_mode = tps65912_get_mode,
-       .get_voltage = tps65912_get_voltage_dcdc,
+       .get_voltage = tps65912_get_voltage,
        .set_voltage_sel = tps65912_set_voltage_sel,
-       .list_voltage = tps65912_list_voltage_dcdc,
+       .list_voltage = tps65912_list_voltage,
 };
 
 /* Operations permitted on LDOx */
@@ -479,14 +455,15 @@ static struct regulator_ops tps65912_ops_ldo = {
        .is_enabled = tps65912_reg_is_enabled,
        .enable = tps65912_reg_enable,
        .disable = tps65912_reg_disable,
-       .get_voltage = tps65912_get_voltage_ldo,
+       .get_voltage = tps65912_get_voltage,
        .set_voltage_sel = tps65912_set_voltage_sel,
-       .list_voltage = tps65912_list_voltage_ldo,
+       .list_voltage = tps65912_list_voltage,
 };
 
 static __devinit int tps65912_probe(struct platform_device *pdev)
 {
        struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_config config = { };
        struct tps_info *info;
        struct regulator_init_data *reg_data;
        struct regulator_dev *rdev;
@@ -500,7 +477,7 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
 
        reg_data = pmic_plat_data->tps65912_pmic_init_data;
 
-       pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
+       pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
        if (!pmic)
                return -ENOMEM;
 
@@ -524,8 +501,12 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
                pmic->desc[i].type = REGULATOR_VOLTAGE;
                pmic->desc[i].owner = THIS_MODULE;
                range = tps65912_get_range(pmic, i);
-               rdev = regulator_register(&pmic->desc[i],
-                                       tps65912->dev, reg_data, pmic, NULL);
+
+               config.dev = tps65912->dev;
+               config.init_data = reg_data;
+               config.driver_data = pmic;
+
+               rdev = regulator_register(&pmic->desc[i], &config);
                if (IS_ERR(rdev)) {
                        dev_err(tps65912->dev,
                                "failed to register %s regulator\n",
@@ -542,8 +523,6 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
 err:
        while (--i >= 0)
                regulator_unregister(pmic->rdev[i]);
-
-       kfree(pmic);
        return err;
 }
 
@@ -554,8 +533,6 @@ static int __devexit tps65912_remove(struct platform_device *pdev)
 
        for (i = 0; i < TPS65912_NUM_REGULATOR; i++)
                regulator_unregister(tps65912_reg->rdev[i]);
-
-       kfree(tps65912_reg);
        return 0;
 }
 
index 9cdfc389ca26d0819cd1a7a559d9700166bd9848..7385b273a10fe6dae293970cf33b003c5de82e73 100644 (file)
@@ -175,15 +175,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
        int                     grp = 0, val;
 
-       if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
-               grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
-       if (grp < 0)
-               return grp;
-
-       if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+       if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS))) {
+               grp = twlreg_grp(rdev);
+               if (grp < 0)
+                       return grp;
                grp &= P1_GRP_6030;
-       else
+       } else {
                grp = 1;
+       }
 
        val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
        val = TWL6030_CFG_STATE_APP(val);
@@ -197,7 +196,7 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
        int                     grp;
        int                     ret;
 
-       grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+       grp = twlreg_grp(rdev);
        if (grp < 0)
                return grp;
 
@@ -205,8 +204,6 @@ static int twl4030reg_enable(struct regulator_dev *rdev)
 
        ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
 
-       udelay(info->delay);
-
        return ret;
 }
 
@@ -217,17 +214,28 @@ static int twl6030reg_enable(struct regulator_dev *rdev)
        int                     ret;
 
        if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
-               grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+               grp = twlreg_grp(rdev);
        if (grp < 0)
                return grp;
 
        ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
                        grp << TWL6030_CFG_STATE_GRP_SHIFT |
                        TWL6030_CFG_STATE_ON);
+       return ret;
+}
 
-       udelay(info->delay);
+static int twl4030reg_enable_time(struct regulator_dev *rdev)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
 
-       return ret;
+       return info->delay;
+}
+
+static int twl6030reg_enable_time(struct regulator_dev *rdev)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+
+       return info->delay;
 }
 
 static int twl4030reg_disable(struct regulator_dev *rdev)
@@ -236,7 +244,7 @@ static int twl4030reg_disable(struct regulator_dev *rdev)
        int                     grp;
        int                     ret;
 
-       grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+       grp = twlreg_grp(rdev);
        if (grp < 0)
                return grp;
 
@@ -348,7 +356,7 @@ static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
        int val;
 
        if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
-               grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+               grp = twlreg_grp(rdev);
 
        if (grp < 0)
                return grp;
@@ -473,31 +481,12 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
 }
 
 static int
-twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
-                      unsigned *selector)
+twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int                     vsel;
 
-       for (vsel = 0; vsel < info->table_len; vsel++) {
-               int mV = info->table[vsel];
-               int uV;
-
-               if (IS_UNSUP(mV))
-                       continue;
-               uV = LDO_MV(mV) * 1000;
-
-               /* REVISIT for VAUX2, first match may not be best/lowest */
-
-               /* use the first in-range value */
-               if (min_uV <= uV && uV <= max_uV) {
-                       *selector = vsel;
-                       return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
-                                                       VREG_VOLTAGE, vsel);
-               }
-       }
-
-       return -EDOM;
+       return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
+                           selector);
 }
 
 static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
@@ -516,12 +505,13 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
 static struct regulator_ops twl4030ldo_ops = {
        .list_voltage   = twl4030ldo_list_voltage,
 
-       .set_voltage    = twl4030ldo_set_voltage,
+       .set_voltage_sel = twl4030ldo_set_voltage_sel,
        .get_voltage    = twl4030ldo_get_voltage,
 
        .enable         = twl4030reg_enable,
        .disable        = twl4030reg_disable,
        .is_enabled     = twl4030reg_is_enabled,
+       .enable_time    = twl4030reg_enable_time,
 
        .set_mode       = twl4030reg_set_mode,
 
@@ -642,6 +632,7 @@ static struct regulator_ops twl6030ldo_ops = {
        .enable         = twl6030reg_enable,
        .disable        = twl6030reg_disable,
        .is_enabled     = twl6030reg_is_enabled,
+       .enable_time    = twl6030reg_enable_time,
 
        .set_mode       = twl6030reg_set_mode,
 
@@ -675,6 +666,7 @@ static struct regulator_ops twl4030fixed_ops = {
        .enable         = twl4030reg_enable,
        .disable        = twl4030reg_disable,
        .is_enabled     = twl4030reg_is_enabled,
+       .enable_time    = twl4030reg_enable_time,
 
        .set_mode       = twl4030reg_set_mode,
 
@@ -689,6 +681,7 @@ static struct regulator_ops twl6030fixed_ops = {
        .enable         = twl6030reg_enable,
        .disable        = twl6030reg_disable,
        .is_enabled     = twl6030reg_is_enabled,
+       .enable_time    = twl6030reg_enable_time,
 
        .set_mode       = twl6030reg_set_mode,
 
@@ -699,6 +692,7 @@ static struct regulator_ops twl6030_fixed_resource = {
        .enable         = twl6030reg_enable,
        .disable        = twl6030reg_disable,
        .is_enabled     = twl6030reg_is_enabled,
+       .enable_time    = twl6030reg_enable_time,
        .get_status     = twl6030reg_get_status,
 };
 
@@ -806,10 +800,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
                        vsel = 0;
                else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
                        int calc_uV;
-                       vsel = (min_uV - 600000) / 125;
-                       if (vsel % 100)
-                               vsel += 100;
-                       vsel /= 100;
+                       vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
                        vsel++;
                        calc_uV = twl6030smps_list_voltage(rdev, vsel);
                        if (calc_uV > max_uV)
@@ -836,10 +827,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
                        vsel = 0;
                else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
                        int calc_uV;
-                       vsel = (min_uV - 700000) / 125;
-                       if (vsel % 100)
-                               vsel += 100;
-                       vsel /= 100;
+                       vsel = DIV_ROUND_UP(min_uV - 700000, 12500);
                        vsel++;
                        calc_uV = twl6030smps_list_voltage(rdev, vsel);
                        if (calc_uV > max_uV)
@@ -862,24 +850,18 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
                        return -EINVAL;
                break;
        case SMPS_EXTENDED_EN:
-               if (min_uV == 0)
+               if (min_uV == 0) {
                        vsel = 0;
-               else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
-                       vsel = (min_uV - 1852000) / 386;
-                       if (vsel % 100)
-                               vsel += 100;
-                       vsel /= 100;
+               } else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
+                       vsel = DIV_ROUND_UP(min_uV - 1852000, 38600);
                        vsel++;
                }
                break;
        case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
-               if (min_uV == 0)
+               if (min_uV == 0) {
                        vsel = 0;
-               else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
-                       vsel = (min_uV - 2161000) / 386;
-                       if (vsel % 100)
-                               vsel += 100;
-                       vsel /= 100;
+               } else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
+                       vsel = DIV_ROUND_UP(min_uV - 2161000, 38600);
                        vsel++;
                }
                break;
@@ -907,6 +889,7 @@ static struct regulator_ops twlsmps_ops = {
        .enable                 = twl6030reg_enable,
        .disable                = twl6030reg_disable,
        .is_enabled             = twl6030reg_is_enabled,
+       .enable_time            = twl6030reg_enable_time,
 
        .set_mode               = twl6030reg_set_mode,
 
@@ -1194,6 +1177,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
        struct regulator_dev            *rdev;
        struct twl_regulator_driver_data        *drvdata;
        const struct of_device_id       *match;
+       struct regulator_config         config = { };
 
        match = of_match_device(twl_of_match, &pdev->dev);
        if (match) {
@@ -1207,10 +1191,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
                initdata = pdev->dev.platform_data;
                for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
                        info = twl_of_match[i].data;
-                       if (!info || info->desc.id != id)
-                               continue;
-                       break;
+                       if (info && info->desc.id == id)
+                               break;
                }
+               if (i == ARRAY_SIZE(twl_of_match))
+                       return -ENODEV;
+
                drvdata = initdata->driver_data;
                if (!drvdata)
                        return -EINVAL;
@@ -1273,8 +1259,12 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
                break;
        }
 
-       rdev = regulator_register(&info->desc, &pdev->dev, initdata, info,
-                                                       pdev->dev.of_node);
+       config.dev = &pdev->dev;
+       config.init_data = initdata;
+       config.driver_data = info;
+       config.of_node = pdev->dev.of_node;
+
+       rdev = regulator_register(&info->desc, &config);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "can't register %s, %ld\n",
                                info->desc.name, PTR_ERR(rdev));
index ff810e787eac52931933eb400784a17df8d7bced..318b9631155c145dc413b1c53f7c70dad63029f9 100644 (file)
@@ -60,41 +60,6 @@ struct wm831x_dcdc {
        int dvs_vsel;
 };
 
-static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
-{
-       struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = dcdc->wm831x;
-       int mask = 1 << rdev_get_id(rdev);
-       int reg;
-
-       reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
-       if (reg < 0)
-               return reg;
-
-       if (reg & mask)
-               return 1;
-       else
-               return 0;
-}
-
-static int wm831x_dcdc_enable(struct regulator_dev *rdev)
-{
-       struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = dcdc->wm831x;
-       int mask = 1 << rdev_get_id(rdev);
-
-       return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
-}
-
-static int wm831x_dcdc_disable(struct regulator_dev *rdev)
-{
-       struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = dcdc->wm831x;
-       int mask = 1 << rdev_get_id(rdev);
-
-       return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
-}
-
 static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)
 
 {
@@ -414,9 +379,9 @@ static struct regulator_ops wm831x_buckv_ops = {
        .set_current_limit = wm831x_buckv_set_current_limit,
        .get_current_limit = wm831x_buckv_get_current_limit,
 
-       .is_enabled = wm831x_dcdc_is_enabled,
-       .enable = wm831x_dcdc_enable,
-       .disable = wm831x_dcdc_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
        .get_status = wm831x_dcdc_get_status,
        .get_mode = wm831x_dcdc_get_mode,
        .set_mode = wm831x_dcdc_set_mode,
@@ -498,6 +463,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id;
        struct wm831x_dcdc *dcdc;
        struct resource *res;
@@ -511,9 +477,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
 
-       if (pdata == NULL || pdata->dcdc[id] == NULL)
-               return -ENODEV;
-
        dcdc = devm_kzalloc(&pdev->dev,  sizeof(struct wm831x_dcdc),
                            GFP_KERNEL);
        if (dcdc == NULL) {
@@ -538,6 +501,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
        dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
        dcdc->desc.ops = &wm831x_buckv_ops;
        dcdc->desc.owner = THIS_MODULE;
+       dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
+       dcdc->desc.enable_mask = 1 << id;
 
        ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
        if (ret < 0) {
@@ -556,8 +521,13 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
        if (pdata->dcdc[id])
                wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
 
-       dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->dcdc[id], dcdc, NULL);
+       config.dev = pdev->dev.parent;
+       if (pdata)
+               config.init_data = pdata->dcdc[id];
+       config.driver_data = dcdc;
+       config.regmap = wm831x->regmap;
+
+       dcdc->regulator = regulator_register(&dcdc->desc, &config);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -675,29 +645,15 @@ static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
        return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV, &selector);
 }
 
-static int wm831x_buckp_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = dcdc->wm831x;
-       u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
-       int val;
-
-       val = wm831x_reg_read(wm831x, reg);
-       if (val < 0)
-               return val;
-
-       return val & WM831X_DC3_ON_VSEL_MASK;
-}
-
 static struct regulator_ops wm831x_buckp_ops = {
        .set_voltage = wm831x_buckp_set_voltage,
-       .get_voltage_sel = wm831x_buckp_get_voltage_sel,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .list_voltage = wm831x_buckp_list_voltage,
        .set_suspend_voltage = wm831x_buckp_set_suspend_voltage,
 
-       .is_enabled = wm831x_dcdc_is_enabled,
-       .enable = wm831x_dcdc_enable,
-       .disable = wm831x_dcdc_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
        .get_status = wm831x_dcdc_get_status,
        .get_mode = wm831x_dcdc_get_mode,
        .set_mode = wm831x_dcdc_set_mode,
@@ -708,6 +664,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id;
        struct wm831x_dcdc *dcdc;
        struct resource *res;
@@ -721,9 +678,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
 
-       if (pdata == NULL || pdata->dcdc[id] == NULL)
-               return -ENODEV;
-
        dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc),
                            GFP_KERNEL);
        if (dcdc == NULL) {
@@ -748,9 +702,18 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
        dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1;
        dcdc->desc.ops = &wm831x_buckp_ops;
        dcdc->desc.owner = THIS_MODULE;
-
-       dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->dcdc[id], dcdc, NULL);
+       dcdc->desc.vsel_reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+       dcdc->desc.vsel_mask = WM831X_DC3_ON_VSEL_MASK;
+       dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
+       dcdc->desc.enable_mask = 1 << id;
+
+       config.dev = pdev->dev.parent;
+       if (pdata)
+               config.init_data = pdata->dcdc[id];
+       config.driver_data = dcdc;
+       config.regmap = wm831x->regmap;
+
+       dcdc->regulator = regulator_register(&dcdc->desc, &config);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -832,15 +795,16 @@ static int wm831x_boostp_get_status(struct regulator_dev *rdev)
 static struct regulator_ops wm831x_boostp_ops = {
        .get_status = wm831x_boostp_get_status,
 
-       .is_enabled = wm831x_dcdc_is_enabled,
-       .enable = wm831x_dcdc_enable,
-       .disable = wm831x_dcdc_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
 };
 
 static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
        struct wm831x_dcdc *dcdc;
        struct resource *res;
@@ -851,7 +815,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
        if (pdata == NULL || pdata->dcdc[id] == NULL)
                return -ENODEV;
 
-       dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
+       dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL);
        if (dcdc == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
                return -ENOMEM;
@@ -873,9 +837,15 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
        dcdc->desc.type = REGULATOR_VOLTAGE;
        dcdc->desc.ops = &wm831x_boostp_ops;
        dcdc->desc.owner = THIS_MODULE;
+       dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
+       dcdc->desc.enable_mask = 1 << id;
 
-       dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->dcdc[id], dcdc, NULL);
+       config.dev = pdev->dev.parent;
+       config.init_data = pdata->dcdc[id];
+       config.driver_data = dcdc;
+       config.regmap = wm831x->regmap;
+
+       dcdc->regulator = regulator_register(&dcdc->desc, &config);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -900,7 +870,6 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
 err_regulator:
        regulator_unregister(dcdc->regulator);
 err:
-       kfree(dcdc);
        return ret;
 }
 
@@ -912,7 +881,6 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
 
        free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
        regulator_unregister(dcdc->regulator);
-       kfree(dcdc);
 
        return 0;
 }
@@ -936,9 +904,9 @@ static struct platform_driver wm831x_boostp_driver = {
 #define WM831X_EPE_BASE 6
 
 static struct regulator_ops wm831x_epe_ops = {
-       .is_enabled = wm831x_dcdc_is_enabled,
-       .enable = wm831x_dcdc_enable,
-       .disable = wm831x_dcdc_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
        .get_status = wm831x_dcdc_get_status,
 };
 
@@ -946,16 +914,14 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id = pdev->id % ARRAY_SIZE(pdata->epe);
        struct wm831x_dcdc *dcdc;
        int ret;
 
        dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);
 
-       if (pdata == NULL || pdata->epe[id] == NULL)
-               return -ENODEV;
-
-       dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
+       dcdc = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_dcdc), GFP_KERNEL);
        if (dcdc == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
                return -ENOMEM;
@@ -972,9 +938,16 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
        dcdc->desc.ops = &wm831x_epe_ops;
        dcdc->desc.type = REGULATOR_VOLTAGE;
        dcdc->desc.owner = THIS_MODULE;
+       dcdc->desc.enable_reg = WM831X_DCDC_ENABLE;
+       dcdc->desc.enable_mask = 1 << dcdc->desc.id;
 
-       dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->epe[id], dcdc, NULL);
+       config.dev = pdev->dev.parent;
+       if (pdata)
+               config.init_data = pdata->epe[id];
+       config.driver_data = dcdc;
+       config.regmap = wm831x->regmap;
+
+       dcdc->regulator = regulator_register(&dcdc->desc, &config);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
@@ -987,7 +960,6 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
        return 0;
 
 err:
-       kfree(dcdc);
        return ret;
 }
 
@@ -996,9 +968,7 @@ static __devexit int wm831x_epe_remove(struct platform_device *pdev)
        struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
        platform_set_drvdata(pdev, NULL);
-
        regulator_unregister(dcdc->regulator);
-       kfree(dcdc);
 
        return 0;
 }
index b414e09c56200c16aa5b191bf1fa10b93ad7426f..b50ab778b098274965667a0408ead22253efe8d2 100644 (file)
@@ -154,6 +154,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
        struct wm831x_isink *isink;
        int id = pdev->id % ARRAY_SIZE(pdata->isink);
+       struct regulator_config config = { };
        struct resource *res;
        int ret, irq;
 
@@ -189,8 +190,11 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
        isink->desc.type = REGULATOR_CURRENT;
        isink->desc.owner = THIS_MODULE;
 
-       isink->regulator = regulator_register(&isink->desc, &pdev->dev,
-                                            pdata->isink[id], isink, NULL);
+       config.dev = pdev->dev.parent;
+       config.init_data = pdata->isink[id];
+       config.driver_data = isink;
+
+       isink->regulator = regulator_register(&isink->desc, &config);
        if (IS_ERR(isink->regulator)) {
                ret = PTR_ERR(isink->regulator);
                dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",
index 641e9f6499d1ba30874811a1dd23eb759e1fb481..74cd1f24b892377589be7bc33bbfb290f10c0766 100644 (file)
@@ -46,41 +46,6 @@ struct wm831x_ldo {
  * Shared
  */
 
-static int wm831x_ldo_is_enabled(struct regulator_dev *rdev)
-{
-       struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = ldo->wm831x;
-       int mask = 1 << rdev_get_id(rdev);
-       int reg;
-
-       reg = wm831x_reg_read(wm831x, WM831X_LDO_ENABLE);
-       if (reg < 0)
-               return reg;
-
-       if (reg & mask)
-               return 1;
-       else
-               return 0;
-}
-
-static int wm831x_ldo_enable(struct regulator_dev *rdev)
-{
-       struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = ldo->wm831x;
-       int mask = 1 << rdev_get_id(rdev);
-
-       return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, mask);
-}
-
-static int wm831x_ldo_disable(struct regulator_dev *rdev)
-{
-       struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = ldo->wm831x;
-       int mask = 1 << rdev_get_id(rdev);
-
-       return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, 0);
-}
-
 static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
 {
        struct wm831x_ldo *ldo = data;
@@ -105,7 +70,7 @@ static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev,
        /* 0.9-1.6V in 50mV steps */
        if (selector <= WM831X_GP_LDO_SELECTOR_LOW)
                return 900000 + (selector * 50000);
-       /* 1.7-3.3V in 50mV steps */
+       /* 1.7-3.3V in 100mV steps */
        if (selector <= WM831X_GP_LDO_MAX_SELECTOR)
                return 1600000 + ((selector - WM831X_GP_LDO_SELECTOR_LOW)
                                  * 100000);
@@ -160,22 +125,6 @@ static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
        return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV, &selector);
 }
 
-static int wm831x_gp_ldo_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = ldo->wm831x;
-       int reg = ldo->base + WM831X_LDO_ON_CONTROL;
-       int ret;
-
-       ret = wm831x_reg_read(wm831x, reg);
-       if (ret < 0)
-               return ret;
-
-       ret &= WM831X_LDO1_ON_VSEL_MASK;
-
-       return ret;
-}
-
 static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
 {
        struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
@@ -293,7 +242,7 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
 
 static struct regulator_ops wm831x_gp_ldo_ops = {
        .list_voltage = wm831x_gp_ldo_list_voltage,
-       .get_voltage_sel = wm831x_gp_ldo_get_voltage_sel,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage = wm831x_gp_ldo_set_voltage,
        .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage,
        .get_mode = wm831x_gp_ldo_get_mode,
@@ -301,15 +250,16 @@ static struct regulator_ops wm831x_gp_ldo_ops = {
        .get_status = wm831x_gp_ldo_get_status,
        .get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
 
-       .is_enabled = wm831x_ldo_is_enabled,
-       .enable = wm831x_ldo_enable,
-       .disable = wm831x_ldo_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
 };
 
 static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id;
        struct wm831x_ldo *ldo;
        struct resource *res;
@@ -323,9 +273,6 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
 
-       if (pdata == NULL || pdata->ldo[id] == NULL)
-               return -ENODEV;
-
        ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
        if (ldo == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
@@ -349,9 +296,18 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
        ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1;
        ldo->desc.ops = &wm831x_gp_ldo_ops;
        ldo->desc.owner = THIS_MODULE;
-
-       ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-                                            pdata->ldo[id], ldo, NULL);
+       ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
+       ldo->desc.vsel_mask = WM831X_LDO1_ON_VSEL_MASK;
+       ldo->desc.enable_reg = WM831X_LDO_ENABLE;
+       ldo->desc.enable_mask = 1 << id;
+
+       config.dev = pdev->dev.parent;
+       if (pdata)
+               config.init_data = pdata->ldo[id];
+       config.driver_data = ldo;
+       config.regmap = wm831x->regmap;
+
+       ldo->regulator = regulator_register(&ldo->desc, &config);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -414,7 +370,7 @@ static int wm831x_aldo_list_voltage(struct regulator_dev *rdev,
        /* 1-1.6V in 50mV steps */
        if (selector <= WM831X_ALDO_SELECTOR_LOW)
                return 1000000 + (selector * 50000);
-       /* 1.7-3.5V in 50mV steps */
+       /* 1.7-3.5V in 100mV steps */
        if (selector <= WM831X_ALDO_MAX_SELECTOR)
                return 1600000 + ((selector - WM831X_ALDO_SELECTOR_LOW)
                                  * 100000);
@@ -468,22 +424,6 @@ static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
        return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV, &selector);
 }
 
-static int wm831x_aldo_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = ldo->wm831x;
-       int reg = ldo->base + WM831X_LDO_ON_CONTROL;
-       int ret;
-
-       ret = wm831x_reg_read(wm831x, reg);
-       if (ret < 0)
-               return ret;
-
-       ret &= WM831X_LDO7_ON_VSEL_MASK;
-
-       return ret;
-}
-
 static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev)
 {
        struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
@@ -559,22 +499,23 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
 
 static struct regulator_ops wm831x_aldo_ops = {
        .list_voltage = wm831x_aldo_list_voltage,
-       .get_voltage_sel = wm831x_aldo_get_voltage_sel,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage = wm831x_aldo_set_voltage,
        .set_suspend_voltage = wm831x_aldo_set_suspend_voltage,
        .get_mode = wm831x_aldo_get_mode,
        .set_mode = wm831x_aldo_set_mode,
        .get_status = wm831x_aldo_get_status,
 
-       .is_enabled = wm831x_ldo_is_enabled,
-       .enable = wm831x_ldo_enable,
-       .disable = wm831x_ldo_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
 };
 
 static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id;
        struct wm831x_ldo *ldo;
        struct resource *res;
@@ -588,9 +529,6 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
 
-       if (pdata == NULL || pdata->ldo[id] == NULL)
-               return -ENODEV;
-
        ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
        if (ldo == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
@@ -614,9 +552,18 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
        ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1;
        ldo->desc.ops = &wm831x_aldo_ops;
        ldo->desc.owner = THIS_MODULE;
-
-       ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-                                            pdata->ldo[id], ldo, NULL);
+       ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
+       ldo->desc.vsel_mask = WM831X_LDO7_ON_VSEL_MASK;
+       ldo->desc.enable_reg = WM831X_LDO_ENABLE;
+       ldo->desc.enable_mask = 1 << id;
+
+       config.dev = pdev->dev.parent;
+       if (pdata)
+               config.init_data = pdata->ldo[id];
+       config.driver_data = ldo;
+       config.regmap = wm831x->regmap;
+
+       ldo->regulator = regulator_register(&ldo->desc, &config);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -720,22 +667,6 @@ static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev,
        return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV, &selector);
 }
 
-static int wm831x_alive_ldo_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
-       struct wm831x *wm831x = ldo->wm831x;
-       int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
-       int ret;
-
-       ret = wm831x_reg_read(wm831x, reg);
-       if (ret < 0)
-               return ret;
-
-       ret &= WM831X_LDO11_ON_VSEL_MASK;
-
-       return ret;
-}
-
 static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
 {
        struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
@@ -755,20 +686,21 @@ static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
 
 static struct regulator_ops wm831x_alive_ldo_ops = {
        .list_voltage = wm831x_alive_ldo_list_voltage,
-       .get_voltage_sel = wm831x_alive_ldo_get_voltage_sel,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
        .set_voltage = wm831x_alive_ldo_set_voltage,
        .set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage,
        .get_status = wm831x_alive_ldo_get_status,
 
-       .is_enabled = wm831x_ldo_is_enabled,
-       .enable = wm831x_ldo_enable,
-       .disable = wm831x_ldo_disable,
+       .is_enabled = regulator_is_enabled_regmap,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
 };
 
 static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
 {
        struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
        struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+       struct regulator_config config = { };
        int id;
        struct wm831x_ldo *ldo;
        struct resource *res;
@@ -783,9 +715,6 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
 
-       if (pdata == NULL || pdata->ldo[id] == NULL)
-               return -ENODEV;
-
        ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
        if (ldo == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
@@ -809,9 +738,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
        ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1;
        ldo->desc.ops = &wm831x_alive_ldo_ops;
        ldo->desc.owner = THIS_MODULE;
-
-       ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-                                            pdata->ldo[id], ldo, NULL);
+       ldo->desc.vsel_reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
+       ldo->desc.vsel_mask = WM831X_LDO11_ON_VSEL_MASK;
+       ldo->desc.enable_reg = WM831X_LDO_ENABLE;
+       ldo->desc.enable_mask = 1 << id;
+
+       config.dev = pdev->dev.parent;
+       if (pdata)
+               config.init_data = pdata->ldo[id];
+       config.driver_data = ldo;
+       config.regmap = wm831x->regmap;
+
+       ldo->regulator = regulator_register(&ldo->desc, &config);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
index 05ecfb872319c605bb3166c547c7020c5f57c0e7..94e550dc70b64a6ef5042a68d2aa8dfef445bec2 100644 (file)
@@ -1269,7 +1269,7 @@ static struct regulator_ops wm8350_isink_ops = {
        .enable_time = wm8350_isink_enable_time,
 };
 
-static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
+static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
        {
                .name = "DCDC1",
                .id = WM8350_DCDC_1,
@@ -1398,6 +1398,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
 static int wm8350_regulator_probe(struct platform_device *pdev)
 {
        struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
+       struct regulator_config config = { };
        struct regulator_dev *rdev;
        int ret;
        u16 val;
@@ -1425,10 +1426,12 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
                break;
        }
 
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = dev_get_drvdata(&pdev->dev);
+
        /* register regulator */
-       rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data,
-                                 dev_get_drvdata(&pdev->dev), NULL);
+       rdev = regulator_register(&wm8350_reg[pdev->id], &config);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register %s\n",
                        wm8350_reg[pdev->id].name);
index 8477153780b637b3fc8218f82334563c55216cca..4408b7802e751fe9a9d1018abbd26b759c197701 100644 (file)
@@ -323,11 +323,14 @@ static struct regulator_desc regulators[] = {
 static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
 {
        struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
+       struct regulator_config config = { };
        struct regulator_dev *rdev;
 
-       rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data, wm8400, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdev->dev.platform_data;
+       config.driver_data = wm8400;
 
+       rdev = regulator_register(&regulators[pdev->id], &config);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
index 75ed402d9f43587553790bdf9b17f7aa15fc56b6..e07972fbf44faeb42c4f5e4f2c165768d66b02eb 100644 (file)
@@ -86,36 +86,6 @@ static int wm8994_ldo1_list_voltage(struct regulator_dev *rdev,
        return (selector * 100000) + 2400000;
 }
 
-static int wm8994_ldo1_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
-       int val;
-
-       val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_1);
-       if (val < 0)
-               return val;
-
-       return (val & WM8994_LDO1_VSEL_MASK) >> WM8994_LDO1_VSEL_SHIFT;
-}
-
-static int wm8994_ldo1_set_voltage(struct regulator_dev *rdev,
-                                  int min_uV, int max_uV, unsigned *s)
-{
-       struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
-       int selector, v;
-
-       selector = (min_uV - 2400000) / 100000;
-       v = wm8994_ldo1_list_voltage(rdev, selector);
-       if (v < 0 || v > max_uV)
-               return -EINVAL;
-
-       *s = selector;
-       selector <<= WM8994_LDO1_VSEL_SHIFT;
-
-       return wm8994_set_bits(ldo->wm8994, WM8994_LDO_1,
-                              WM8994_LDO1_VSEL_MASK, selector);
-}
-
 static struct regulator_ops wm8994_ldo1_ops = {
        .enable = wm8994_ldo_enable,
        .disable = wm8994_ldo_disable,
@@ -123,8 +93,8 @@ static struct regulator_ops wm8994_ldo1_ops = {
        .enable_time = wm8994_ldo_enable_time,
 
        .list_voltage = wm8994_ldo1_list_voltage,
-       .get_voltage_sel = wm8994_ldo1_get_voltage_sel,
-       .set_voltage = wm8994_ldo1_set_voltage,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
 };
 
 static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
@@ -153,51 +123,6 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
        }
 }
 
-static int wm8994_ldo2_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
-       int val;
-
-       val = wm8994_reg_read(ldo->wm8994, WM8994_LDO_2);
-       if (val < 0)
-               return val;
-
-       return (val & WM8994_LDO2_VSEL_MASK) >> WM8994_LDO2_VSEL_SHIFT;
-}
-
-static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
-                                  int min_uV, int max_uV, unsigned *s)
-{
-       struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
-       int selector, v;
-
-       switch (ldo->wm8994->type) {
-       case WM8994:
-               selector = (min_uV - 900000) / 100000;
-               break;
-       case WM8958:
-               selector = (min_uV - 1000000) / 100000;
-               break;
-       case WM1811:
-               selector = (min_uV - 950000) / 100000;
-               if (selector == 0)
-                       selector = 1;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       v = wm8994_ldo2_list_voltage(rdev, selector);
-       if (v < 0 || v > max_uV)
-               return -EINVAL;
-
-       *s = selector;
-       selector <<= WM8994_LDO2_VSEL_SHIFT;
-
-       return wm8994_set_bits(ldo->wm8994, WM8994_LDO_2,
-                              WM8994_LDO2_VSEL_MASK, selector);
-}
-
 static struct regulator_ops wm8994_ldo2_ops = {
        .enable = wm8994_ldo_enable,
        .disable = wm8994_ldo_disable,
@@ -205,16 +130,18 @@ static struct regulator_ops wm8994_ldo2_ops = {
        .enable_time = wm8994_ldo_enable_time,
 
        .list_voltage = wm8994_ldo2_list_voltage,
-       .get_voltage_sel = wm8994_ldo2_get_voltage_sel,
-       .set_voltage = wm8994_ldo2_set_voltage,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
 };
 
-static struct regulator_desc wm8994_ldo_desc[] = {
+static const struct regulator_desc wm8994_ldo_desc[] = {
        {
                .name = "LDO1",
                .id = 1,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
+               .vsel_reg = WM8994_LDO_1,
+               .vsel_mask = WM8994_LDO1_VSEL_MASK,
                .ops = &wm8994_ldo1_ops,
                .owner = THIS_MODULE,
        },
@@ -223,6 +150,8 @@ static struct regulator_desc wm8994_ldo_desc[] = {
                .id = 2,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
+               .vsel_reg = WM8994_LDO_2,
+               .vsel_mask = WM8994_LDO2_VSEL_MASK,
                .ops = &wm8994_ldo2_ops,
                .owner = THIS_MODULE,
        },
@@ -233,6 +162,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
        struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
        struct wm8994_pdata *pdata = wm8994->dev->platform_data;
        int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+       struct regulator_config config = { };
        struct wm8994_ldo *ldo;
        int ret;
 
@@ -268,8 +198,12 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
        } else
                ldo->is_enabled = true;
 
-       ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
-                                            pdata->ldo[id].init_data, ldo, NULL);
+       config.dev = &pdev->dev;
+       config.init_data = pdata->ldo[id].init_data;
+       config.driver_data = ldo;
+       config.regmap = wm8994->regmap;
+
+       ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
index 0b64b19d81abf9e89e3d609f020e10e2ac9952b6..c42fe92a727dad134fadfbc7ee7bb661f8de5738 100644 (file)
@@ -250,6 +250,26 @@ enum {
        RC5T583_EXT_PWRREQ2_CONTROL = 0x2,
 };
 
+enum {
+       RC5T583_REGULATOR_DC0,
+       RC5T583_REGULATOR_DC1,
+       RC5T583_REGULATOR_DC2,
+       RC5T583_REGULATOR_DC3,
+       RC5T583_REGULATOR_LDO0,
+       RC5T583_REGULATOR_LDO1,
+       RC5T583_REGULATOR_LDO2,
+       RC5T583_REGULATOR_LDO3,
+       RC5T583_REGULATOR_LDO4,
+       RC5T583_REGULATOR_LDO5,
+       RC5T583_REGULATOR_LDO6,
+       RC5T583_REGULATOR_LDO7,
+       RC5T583_REGULATOR_LDO8,
+       RC5T583_REGULATOR_LDO9,
+
+       /* Should be last entry */
+       RC5T583_REGULATOR_MAX,
+};
+
 struct rc5t583 {
        struct device   *dev;
        struct regmap   *regmap;
@@ -273,11 +293,20 @@ struct rc5t583 {
  * The board specific data is provided through this structure.
  * @irq_base: Irq base number on which this device registers their interrupts.
  * @enable_shutdown: Enable shutdown through the input pin "shutdown".
+ * @regulator_deepsleep_slot: The slot number on which device goes to sleep
+ *             in device sleep mode.
+ * @regulator_ext_pwr_control: External power request regulator control. The
+ *             regulator output enable/disable is controlled by the external
+ *             power request input state.
+ * @reg_init_data: Regulator init data.
  */
 
 struct rc5t583_platform_data {
        int             irq_base;
        bool            enable_shutdown;
+       int             regulator_deepsleep_slot[RC5T583_REGULATOR_MAX];
+       unsigned long   regulator_ext_pwr_control[RC5T583_REGULATOR_MAX];
+       struct regulator_init_data *reg_init_data[RC5T583_REGULATOR_MAX];
 };
 
 static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val)
index a7480b57f92defb99bdb0b9f9d6b80315073c2ec..21603b42f22fb150f73a5be185e6c1d615de6329 100644 (file)
@@ -335,6 +335,7 @@ extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask);
 
 struct s5m_platform_data {
        struct s5m_regulator_data       *regulators;
+       struct s5m_opmode_data          *opmode;
        int                             device_type;
        int                             num_regulators;
 
index a72a5d27e62e6b3b170d10223e3e44477876e4c3..7c719f20f58ab7a98340917faf80f42c65bce6de 100644 (file)
@@ -58,6 +58,8 @@ enum s5m8767_regulators {
        S5M8767_REG_MAX,
 };
 
+#define S5M8767_ENCTRL_SHIFT  6
+
 /* S5M8763 regulator ids */
 enum s5m8763_regulators {
        S5M8763_LDO1,
@@ -97,4 +99,31 @@ struct s5m_regulator_data {
        struct regulator_init_data      *initdata;
 };
 
+/*
+ * s5m_opmode_data - regulator operation mode data
+ * @id: regulator id
+ * @mode: regulator operation mode
+ */
+struct s5m_opmode_data {
+       int id;
+       int mode;
+};
+
+/*
+ * s5m regulator operation mode
+ * S5M_OPMODE_OFF      Regulator always OFF
+ * S5M_OPMODE_ON       Regulator always ON
+ * S5M_OPMODE_LOWPOWER  Regulator is on in low-power mode
+ * S5M_OPMODE_SUSPEND   Regulator is changed by PWREN pin
+ *                     If PWREN is high, regulator is on
+ *                     If PWREN is low, regulator is off
+ */
+
+enum s5m_opmode {
+       S5M_OPMODE_OFF,
+       S5M_OPMODE_ON,
+       S5M_OPMODE_LOWPOWER,
+       S5M_OPMODE_SUSPEND,
+};
+
 #endif /*  __LINUX_MFD_S5M_PMIC_H */
index 38e31c55adbbdcbaea975a84c31f665ebab4341e..6bc31d854626b26f62994f0810a143ee00027e17 100644 (file)
 #ifndef __LINUX_MFD_TPS65090_H
 #define __LINUX_MFD_TPS65090_H
 
+#include <linux/irq.h>
+
+struct tps65090 {
+       struct mutex            lock;
+       struct device           *dev;
+       struct i2c_client       *client;
+       struct regmap           *rmap;
+       struct irq_chip         irq_chip;
+       struct mutex            irq_lock;
+       int                     irq_base;
+       unsigned int            id;
+};
+
 struct tps65090_subdev_info {
        int             id;
        const char      *name;
index fa8b55b8191c980de60c32b5e1b3fe1d3016340f..8160bc87be28e15c40aa68e1762c8848d51d5e94 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/notifier.h>
 #include <linux/regulator/consumer.h>
 
+struct regmap;
 struct regulator_dev;
 struct regulator_init_data;
 
@@ -148,10 +149,12 @@ enum regulator_type {
 };
 
 /**
- * struct regulator_desc - Regulator descriptor
+ * struct regulator_desc - Static regulator descriptor
  *
- * Each regulator registered with the core is described with a structure of
- * this type.
+ * Each regulator registered with the core is described with a
+ * structure of this type and a struct regulator_config.  This
+ * structure contains the non-varying parts of the regulator
+ * description.
  *
  * @name: Identifying name for the regulator.
  * @supply_name: Identifying the regulator supply
@@ -161,6 +164,11 @@ enum regulator_type {
  * @irq: Interrupt number for the regulator.
  * @type: Indicates if the regulator is a voltage or current regulator.
  * @owner: Module providing the regulator, used for refcounting.
+
+ * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
+ * @vsel_mask: Mask for register bitfield used for selector
+ * @enable_reg: Register for control when using regmap enable/disable ops
+ * @enable_mask: Mask for control when using regmap enable/disable ops
  */
 struct regulator_desc {
        const char *name;
@@ -171,6 +179,33 @@ struct regulator_desc {
        int irq;
        enum regulator_type type;
        struct module *owner;
+
+       unsigned int vsel_reg;
+       unsigned int vsel_mask;
+       unsigned int enable_reg;
+       unsigned int enable_mask;
+};
+
+/**
+ * struct regulator_config - Dynamic regulator descriptor
+ *
+ * Each regulator registered with the core is described with a
+ * structure of this type and a struct regulator_desc.  This structure
+ * contains the runtime variable parts of the regulator description.
+ *
+ * @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
+ * @driver_data: private regulator data
+ * @of_node: OpenFirmware node to parse for device tree bindings (may be
+ *           NULL).
+ * @regmap: regmap to use for core regmap helpers
+ */
+struct regulator_config {
+       struct device *dev;
+       const struct regulator_init_data *init_data;
+       void *driver_data;
+       struct device_node *of_node;
+       struct regmap *regmap;
 };
 
 /*
@@ -184,7 +219,7 @@ struct regulator_desc {
  * no other direct access).
  */
 struct regulator_dev {
-       struct regulator_desc *desc;
+       const struct regulator_desc *desc;
        int exclusive;
        u32 use_count;
        u32 open_count;
@@ -201,6 +236,7 @@ struct regulator_dev {
        struct device dev;
        struct regulation_constraints *constraints;
        struct regulator *supply;       /* for tree */
+       struct regmap *regmap;
 
        struct delayed_work disable_work;
        int deferred_disables;
@@ -210,9 +246,9 @@ struct regulator_dev {
        struct dentry *debugfs;
 };
 
-struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
-       struct device *dev, const struct regulator_init_data *init_data,
-       void *driver_data, struct device_node *of_node);
+struct regulator_dev *
+regulator_register(const struct regulator_desc *regulator_desc,
+                  const struct regulator_config *config);
 void regulator_unregister(struct regulator_dev *rdev);
 
 int regulator_notifier_call_chain(struct regulator_dev *rdev,
@@ -224,6 +260,12 @@ int rdev_get_id(struct regulator_dev *rdev);
 
 int regulator_mode_to_status(unsigned int);
 
+int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev);
+int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel);
+int regulator_is_enabled_regmap(struct regulator_dev *rdev);
+int regulator_enable_regmap(struct regulator_dev *rdev);
+int regulator_disable_regmap(struct regulator_dev *rdev);
+
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
 
 #endif
index 936a7d8c11a927791aaa77e8694a4e9460d65f5b..f83f7440b4885656f171f904e8a1a150141cef36 100644 (file)
@@ -26,6 +26,12 @@ struct regulator_init_data;
  * @gpio:              GPIO to use for enable control
  *                     set to -EINVAL if not used
  * @startup_delay:     Start-up time in microseconds
+ * @gpio_is_open_drain: Gpio pin is open drain or normal type.
+ *                     If it is open drain type then HIGH will be set
+ *                     through PULL-UP with setting gpio as input
+ *                     and low will be set as gpio-output with driven
+ *                     to low. For non-open-drain case, the gpio will
+ *                     will be in output and drive to low/high accordingly.
  * @enable_high:       Polarity of enable GPIO
  *                     1 = Active high, 0 = Active low
  * @enabled_at_boot:   Whether regulator has been enabled at
@@ -43,6 +49,7 @@ struct fixed_voltage_config {
        int microvolts;
        int gpio;
        unsigned startup_delay;
+       unsigned gpio_is_open_drain:1;
        unsigned enable_high:1;
        unsigned enabled_at_boot:1;
        struct regulator_init_data *init_data;
diff --git a/include/linux/regulator/tps65090-regulator.h b/include/linux/regulator/tps65090-regulator.h
new file mode 100644 (file)
index 0000000..0fa04b6
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Regulator driver interface for TI TPS65090 PMIC family
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __REGULATOR_TPS65090_H
+#define __REGULATOR_TPS65090_H
+
+#include <linux/regulator/machine.h>
+
+#define tps65090_rails(_name) "tps65090_"#_name
+
+enum {
+       TPS65090_ID_DCDC1,
+       TPS65090_ID_DCDC2,
+       TPS65090_ID_DCDC3,
+       TPS65090_ID_FET1,
+       TPS65090_ID_FET2,
+       TPS65090_ID_FET3,
+       TPS65090_ID_FET4,
+       TPS65090_ID_FET5,
+       TPS65090_ID_FET6,
+       TPS65090_ID_FET7,
+};
+
+/*
+ * struct tps65090_regulator_platform_data
+ *
+ * @regulator: The regulator init data.
+ * @slew_rate_uV_per_us: Slew rate microvolt per microsec.
+ */
+
+struct tps65090_regulator_platform_data {
+       struct regulator_init_data regulator;
+};
+
+#endif /* __REGULATOR_TPS65090_H */
index 8e92fb88ed090e594002407850e1275df4078577..c395ec370445d61bfa7ce766331f8dd47a7b6139 100644 (file)
@@ -809,6 +809,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
 {
        struct ldo_regulator *ldo;
        struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
+       struct regulator_config config = { };
 
        ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL);
 
@@ -832,8 +833,11 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
        ldo->codec_data = codec;
        ldo->voltage = voltage;
 
-       ldo->dev = regulator_register(&ldo->desc, codec->dev,
-                                         init_data, ldo, NULL);
+       config.dev = codec->dev;
+       config.driver_data = ldo;
+       config.init_data = init_data;
+
+       ldo->dev = regulator_register(&ldo->desc, &config);
        if (IS_ERR(ldo->dev)) {
                int ret = PTR_ERR(ldo->dev);