Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Jan 2012 18:20:34 +0000 (10:20 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 10 Jan 2012 18:20:34 +0000 (10:20 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (40 commits)
  regulator: set constraints.apply_uV to 0 in of_get_fixed_voltage_config
  regulator: max8925: fix enabled/disabled judgement mistake
  regulator: add regulator_bulk_force_disable function
  regulator: pass regulator_register of_node in fixed voltage driver
  regulator: add regulator_force_disable() definition for !CONFIG_REGULATOR
  regulator: Enable supply regulator if child rail is enabled.
  regulator: mc13892: Convert to devm_kzalloc()
  regulator: mc13783: Convert to devm_kzalloc()
  regulator: Fix checking return value of create_regulator
  regulator: Fix the error handling if create_regulator fails
  regulator: Export regulator_is_supported_voltage()
  regulator: mc13892: add device tree probe support
  regulator: mc13892: remove the unnecessary prefix from regulator name
  regulator: Convert wm831x regulator drivers to devm_kzalloc()
  regulator: da9052: Staticize non-exported symbols
  regulator: Replace kzalloc with devm_kzalloc and if-else with a switch-case for da9052-regulator
  regulator: Update da9052-regulator for DT changes
  regulator: DA9052/53 Regulator support
  regulator: pass device_node to of_get_regulator_init_data()
  regulator: If a single voltage is set with device tree then set apply_uV
  ...

57 files changed:
Documentation/devicetree/bindings/regulator/fixed-regulator.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/regulator.txt [new file with mode: 0644]
Documentation/power/regulator/regulator.txt
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/bq24022.c
drivers/regulator/core.c
drivers/regulator/da903x.c
drivers/regulator/da9052-regulator.c [new file with mode: 0644]
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/of_regulator.c [new file with mode: 0644]
drivers/regulator/pcap-regulator.c
drivers/regulator/pcf50633-regulator.c
drivers/regulator/tps6105x-regulator.c
drivers/regulator/tps65023-regulator.c
drivers/regulator/tps6507x-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/userspace-consumer.c
drivers/regulator/virtual.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/mc13xxx.h
include/linux/mfd/tps65910.h
include/linux/regulator/consumer.h
include/linux/regulator/driver.h
include/linux/regulator/of_regulator.h [new file with mode: 0644]
sound/soc/codecs/sgtl5000.c

diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.txt b/Documentation/devicetree/bindings/regulator/fixed-regulator.txt
new file mode 100644 (file)
index 0000000..9cf57fd
--- /dev/null
@@ -0,0 +1,29 @@
+Fixed Voltage regulators
+
+Required properties:
+- compatible: Must be "regulator-fixed";
+
+Optional properties:
+- gpio: gpio to use for enable control
+- startup-delay-us: startup time in microseconds
+- enable-active-high: Polarity of GPIO is Active high
+If this property is missing, the default assumed is Active low.
+
+Any property defined as part of the core regulator
+binding, defined in regulator.txt, can also be used.
+However a fixed voltage regulator is expected to have the
+regulator-min-microvolt and regulator-max-microvolt
+to be the same.
+
+Example:
+
+       abc: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-supply";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpio = <&gpio1 16 0>;
+               startup-delay-us = <70000>;
+               enable-active-high;
+               regulator-boot-on
+       };
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
new file mode 100644 (file)
index 0000000..5b7a408
--- /dev/null
@@ -0,0 +1,54 @@
+Voltage/Current Regulators
+
+Optional properties:
+- regulator-name: A string used as a descriptive name for regulator outputs
+- regulator-min-microvolt: smallest voltage consumers may set
+- regulator-max-microvolt: largest voltage consumers may set
+- regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops
+- regulator-min-microamp: smallest current consumers may set
+- regulator-max-microamp: largest current consumers may set
+- regulator-always-on: boolean, regulator should never be disabled
+- regulator-boot-on: bootloader/firmware enabled regulator
+- <name>-supply: phandle to the parent supply/regulator node
+
+Example:
+
+       xyzreg: regulator@0 {
+               regulator-min-microvolt = <1000000>;
+               regulator-max-microvolt = <2500000>;
+               regulator-always-on;
+               vin-supply = <&vin>;
+       };
+
+Regulator Consumers:
+Consumer nodes can reference one or more of its supplies/
+regulators using the below bindings.
+
+- <name>-supply: phandle to the regulator node
+
+These are the same bindings that a regulator in the above
+example used to reference its own supply, in which case
+its just seen as a special case of a regulator being a
+consumer itself.
+
+Example of a consumer device node (mmc) referencing two
+regulators (twl_reg1 and twl_reg2),
+
+       twl_reg1: regulator@0 {
+               ...
+               ...
+               ...
+       };
+
+       twl_reg2: regulator@1 {
+               ...
+               ...
+               ...
+       };
+
+       mmc: mmc@0x0 {
+               ...
+               ...
+               vmmc-supply = <&twl_reg1>;
+               vmmcaux-supply = <&twl_reg2>;
+       };
index 3f8b528f237e17626142dfba88f955dfee7a11b3..e272d9909e393dd4091575555a82173e90694fdc 100644 (file)
@@ -12,7 +12,7 @@ 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);
+       void *driver_data, struct device_node *of_node);
 
 This will register the regulators capabilities and operations to the regulator
 core.
index ca0d608f8248c4b29dc599f2c7048f9f45d8c21a..df33530cec4a458d0cf51be33ce60d81943116c3 100644 (file)
@@ -427,7 +427,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 
        /* replace driver_data with info */
        info->regulator = regulator_register(&info->desc, &pdev->dev,
-                                            pdata, info);
+                                            pdata, info, NULL);
        if (IS_ERR(info->regulator)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                        info->desc.name);
index 9713b1b860cb70a88f9fc51805f087a2919f0ef2..7a61b17ddd04700325ea69b1b801d13408a95aa6 100644 (file)
@@ -93,6 +93,7 @@ config REGULATOR_MAX1586
 config REGULATOR_MAX8649
        tristate "Maxim 8649 voltage regulator"
        depends on I2C
+       select REGMAP_I2C
        help
          This driver controls a Maxim 8649 voltage output regulator via
          I2C bus.
@@ -177,6 +178,13 @@ config REGULATOR_DA903X
          Say y here to support the BUCKs and LDOs regulators found on
          Dialog Semiconductor DA9030/DA9034 PMIC.
 
+config REGULATOR_DA9052
+       tristate "Dialog DA9052/DA9053 regulators"
+       depends on PMIC_DA9052
+       help
+         This driver supports the voltage regulators of DA9052-BC and
+         DA9053-AA/Bx PMIC.
+
 config REGULATOR_PCF50633
        tristate "PCF50633 regulator driver"
         depends on MFD_PCF50633
index 93a6318f5328eabaa73af83c877aee2a3edac876..503bac87715ede60b0d0f5ae8124df6059c824fc 100644 (file)
@@ -4,6 +4,7 @@
 
 
 obj-$(CONFIG_REGULATOR) += core.o dummy.o
+obj-$(CONFIG_OF) += of_regulator.o
 obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
+obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
 obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
index 298c6c6a279574561eb24f329b115fe134d274a1..685ad43b074973f40e579fe4896ad5e0e595c041 100644 (file)
@@ -63,7 +63,7 @@ static int aat2870_ldo_set_voltage_sel(struct regulator_dev *rdev,
        struct aat2870_data *aat2870 = dev_get_drvdata(ri->pdev->dev.parent);
 
        return aat2870->update(aat2870, ri->voltage_addr, ri->voltage_mask,
-                       (selector << ri->voltage_shift) & ri->voltage_mask);
+                              selector << ri->voltage_shift);
 }
 
 static int aat2870_ldo_get_voltage_sel(struct regulator_dev *rdev)
@@ -188,7 +188,7 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
        ri->pdev = pdev;
 
        rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdev->dev.platform_data, ri);
+                                 pdev->dev.platform_data, ri, NULL);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "Failed to register regulator %s\n",
                        ri->desc.name);
index 585e4946fe0a7157b6ccaf6ae59465f788505a38..042271aace6a65b8a2f40cdc3be75934ae081ff4 100644 (file)
@@ -634,7 +634,7 @@ static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
                rdev = regulator_register(&ab3100_regulator_desc[i],
                                          &pdev->dev,
                                          &plfdata->reg_constraints[i],
-                                         reg);
+                                         reg, NULL);
 
                if (IS_ERR(rdev)) {
                        err = PTR_ERR(rdev);
index 6e1ae69646b396778660a8d3cf665f40e0d8e07e..e91b8ddc2793120b9e4e3697aa6912ab4358d2e2 100644 (file)
@@ -822,7 +822,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);
+                               &pdata->regulator[i], info, NULL);
                if (IS_ERR(info->regulator)) {
                        err = PTR_ERR(info->regulator);
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
index a4be41614eebd41fa5733c09a7e9645c64c72c59..483c80930852f08de0a4130968afbce5c87f9a39 100644 (file)
@@ -233,7 +233,7 @@ static int __devinit ad5398_probe(struct i2c_client *client,
        chip->current_mask = (chip->current_level - 1) << chip->current_offset;
 
        chip->rdev = regulator_register(&ad5398_reg, &client->dev,
-                                       init_data, chip);
+                                       init_data, chip, NULL);
        if (IS_ERR(chip->rdev)) {
                ret = PTR_ERR(chip->rdev);
                dev_err(&client->dev, "failed to register %s %s\n",
index e24d1b7d97a84c4f5ded6aaf672ba3f317be838c..9fab6d1bbe80d28a1f388e8bc2bdb14589c8702e 100644 (file)
@@ -107,7 +107,7 @@ static int __init bq24022_probe(struct platform_device *pdev)
        ret = gpio_direction_output(pdata->gpio_nce, 1);
 
        bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
-                                    pdata->init_data, pdata);
+                                    pdata->init_data, pdata, NULL);
        if (IS_ERR(bq24022)) {
                dev_dbg(&pdev->dev, "couldn't register regulator\n");
                ret = PTR_ERR(bq24022);
index 938398f3e869c57814fc130b9133ac435118214e..ca86f39a0fdc824fba463f0eb30157ce933bbe9c 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/mutex.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
@@ -132,6 +134,33 @@ static struct regulator *get_device_regulator(struct device *dev)
        return NULL;
 }
 
+/**
+ * of_get_regulator - get a regulator device node based on supply name
+ * @dev: Device pointer for the consumer (of regulator) device
+ * @supply: regulator supply name
+ *
+ * Extract the regulator device node corresponding to the supply name.
+ * retruns the device node corresponding to the regulator if found, else
+ * returns NULL.
+ */
+static struct device_node *of_get_regulator(struct device *dev, const char *supply)
+{
+       struct device_node *regnode = NULL;
+       char prop_name[32]; /* 32 is max size of property name */
+
+       dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
+
+       snprintf(prop_name, 32, "%s-supply", supply);
+       regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+
+       if (!regnode) {
+               dev_warn(dev, "%s property in node %s references invalid phandle",
+                               prop_name, dev->of_node->full_name);
+               return NULL;
+       }
+       return regnode;
+}
+
 /* Platform voltage constraint check */
 static int regulator_check_voltage(struct regulator_dev *rdev,
                                   int *min_uV, int *max_uV)
@@ -883,8 +912,12 @@ static int set_machine_constraints(struct regulator_dev *rdev,
        int ret = 0;
        struct regulator_ops *ops = rdev->desc->ops;
 
-       rdev->constraints = kmemdup(constraints, sizeof(*constraints),
-                                   GFP_KERNEL);
+       if (constraints)
+               rdev->constraints = kmemdup(constraints, sizeof(*constraints),
+                                           GFP_KERNEL);
+       else
+               rdev->constraints = kzalloc(sizeof(*constraints),
+                                           GFP_KERNEL);
        if (!rdev->constraints)
                return -ENOMEM;
 
@@ -893,7 +926,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
                goto out;
 
        /* do we need to setup our suspend state */
-       if (constraints->initial_state) {
+       if (rdev->constraints->initial_state) {
                ret = suspend_prepare(rdev, rdev->constraints->initial_state);
                if (ret < 0) {
                        rdev_err(rdev, "failed to set suspend state\n");
@@ -901,7 +934,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
                }
        }
 
-       if (constraints->initial_mode) {
+       if (rdev->constraints->initial_mode) {
                if (!ops->set_mode) {
                        rdev_err(rdev, "no set_mode operation\n");
                        ret = -EINVAL;
@@ -952,9 +985,8 @@ static int set_supply(struct regulator_dev *rdev,
        rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
 
        rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
-       if (IS_ERR(rdev->supply)) {
-               err = PTR_ERR(rdev->supply);
-               rdev->supply = NULL;
+       if (rdev->supply == NULL) {
+               err = -ENOMEM;
                return err;
        }
 
@@ -1148,6 +1180,30 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
        return rdev->desc->ops->enable_time(rdev);
 }
 
+static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+                                                        const char *supply)
+{
+       struct regulator_dev *r;
+       struct device_node *node;
+
+       /* first do a dt based lookup */
+       if (dev && dev->of_node) {
+               node = of_get_regulator(dev, supply);
+               if (node)
+                       list_for_each_entry(r, &regulator_list, list)
+                               if (r->dev.parent &&
+                                       node == r->dev.of_node)
+                                       return r;
+       }
+
+       /* if not found, try doing it non-dt way */
+       list_for_each_entry(r, &regulator_list, list)
+               if (strcmp(rdev_get_name(r), supply) == 0)
+                       return r;
+
+       return NULL;
+}
+
 /* Internal regulator request function */
 static struct regulator *_regulator_get(struct device *dev, const char *id,
                                        int exclusive)
@@ -1168,6 +1224,10 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 
        mutex_lock(&regulator_list_mutex);
 
+       rdev = regulator_dev_lookup(dev, id);
+       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 &&
@@ -1221,6 +1281,7 @@ found:
        if (regulator == NULL) {
                regulator = ERR_PTR(-ENOMEM);
                module_put(rdev->owner);
+               goto out;
        }
 
        rdev->open_count++;
@@ -1726,6 +1787,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(regulator_is_supported_voltage);
 
 static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                                     int min_uV, int max_uV)
@@ -2428,6 +2490,43 @@ err:
 }
 EXPORT_SYMBOL_GPL(regulator_bulk_disable);
 
+/**
+ * regulator_bulk_force_disable - force disable multiple regulator consumers
+ *
+ * @num_consumers: Number of consumers
+ * @consumers:     Consumer data; clients are stored here.
+ * @return         0 on success, an errno on failure
+ *
+ * This convenience API allows consumers to forcibly disable multiple regulator
+ * clients in a single API call.
+ * NOTE: This should be used for situations when device damage will
+ * likely occur if the regulators are not disabled (e.g. over temp).
+ * Although regulator_force_disable function call for some consumers can
+ * return error numbers, the function is called for all consumers.
+ */
+int regulator_bulk_force_disable(int num_consumers,
+                          struct regulator_bulk_data *consumers)
+{
+       int i;
+       int ret;
+
+       for (i = 0; i < num_consumers; i++)
+               consumers[i].ret =
+                           regulator_force_disable(consumers[i].consumer);
+
+       for (i = 0; i < num_consumers; i++) {
+               if (consumers[i].ret != 0) {
+                       ret = consumers[i].ret;
+                       goto out;
+               }
+       }
+
+       return 0;
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_bulk_force_disable);
+
 /**
  * regulator_bulk_free - free multiple regulator consumers
  *
@@ -2503,7 +2602,8 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
        int                     status = 0;
 
        /* some attributes need specific methods to be displayed */
-       if (ops->get_voltage || ops->get_voltage_sel) {
+       if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
+           (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0)) {
                status = device_create_file(dev, &dev_attr_microvolts);
                if (status < 0)
                        return status;
@@ -2637,11 +2737,13 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
  */
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        struct device *dev, const struct regulator_init_data *init_data,
-       void *driver_data)
+       void *driver_data, struct device_node *of_node)
 {
+       const struct regulation_constraints *constraints = NULL;
        static atomic_t regulator_no = ATOMIC_INIT(0);
        struct regulator_dev *rdev;
        int ret, i;
+       const char *supply = NULL;
 
        if (regulator_desc == NULL)
                return ERR_PTR(-EINVAL);
@@ -2653,9 +2755,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
            regulator_desc->type != REGULATOR_CURRENT)
                return ERR_PTR(-EINVAL);
 
-       if (!init_data)
-               return ERR_PTR(-EINVAL);
-
        /* Only one of each should be implemented */
        WARN_ON(regulator_desc->ops->get_voltage &&
                regulator_desc->ops->get_voltage_sel);
@@ -2688,7 +2787,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
 
        /* preform any regulator specific init */
-       if (init_data->regulator_init) {
+       if (init_data && init_data->regulator_init) {
                ret = init_data->regulator_init(rdev->reg_data);
                if (ret < 0)
                        goto clean;
@@ -2696,6 +2795,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.parent = dev;
        dev_set_name(&rdev->dev, "regulator.%d",
                     atomic_inc_return(&regulator_no) - 1);
@@ -2708,7 +2808,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        dev_set_drvdata(&rdev->dev, rdev);
 
        /* set regulator constraints */
-       ret = set_machine_constraints(rdev, &init_data->constraints);
+       if (init_data)
+               constraints = &init_data->constraints;
+
+       ret = set_machine_constraints(rdev, constraints);
        if (ret < 0)
                goto scrub;
 
@@ -2717,21 +2820,18 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        if (ret < 0)
                goto scrub;
 
-       if (init_data->supply_regulator) {
+       if (init_data && init_data->supply_regulator)
+               supply = init_data->supply_regulator;
+       else if (regulator_desc->supply_name)
+               supply = regulator_desc->supply_name;
+
+       if (supply) {
                struct regulator_dev *r;
-               int found = 0;
 
-               list_for_each_entry(r, &regulator_list, list) {
-                       if (strcmp(rdev_get_name(r),
-                                  init_data->supply_regulator) == 0) {
-                               found = 1;
-                               break;
-                       }
-               }
+               r = regulator_dev_lookup(dev, supply);
 
-               if (!found) {
-                       dev_err(dev, "Failed to find supply %s\n",
-                               init_data->supply_regulator);
+               if (!r) {
+                       dev_err(dev, "Failed to find supply %s\n", supply);
                        ret = -ENODEV;
                        goto scrub;
                }
@@ -2739,18 +2839,28 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
                ret = set_supply(rdev, r);
                if (ret < 0)
                        goto scrub;
+
+               /* Enable supply if rail is enabled */
+               if (rdev->desc->ops->is_enabled &&
+                               rdev->desc->ops->is_enabled(rdev)) {
+                       ret = regulator_enable(rdev->supply);
+                       if (ret < 0)
+                               goto scrub;
+               }
        }
 
        /* add consumers devices */
-       for (i = 0; i < init_data->num_consumer_supplies; i++) {
-               ret = set_consumer_device_supply(rdev,
-                       init_data->consumer_supplies[i].dev,
-                       init_data->consumer_supplies[i].dev_name,
-                       init_data->consumer_supplies[i].supply);
-               if (ret < 0) {
-                       dev_err(dev, "Failed to set supply %s\n",
+       if (init_data) {
+               for (i = 0; i < init_data->num_consumer_supplies; i++) {
+                       ret = set_consumer_device_supply(rdev,
+                               init_data->consumer_supplies[i].dev,
+                               init_data->consumer_supplies[i].dev_name,
                                init_data->consumer_supplies[i].supply);
-                       goto unset_supplies;
+                       if (ret < 0) {
+                               dev_err(dev, "Failed to set supply %s\n",
+                                       init_data->consumer_supplies[i].supply);
+                               goto unset_supplies;
+                       }
                }
        }
 
index e23ddfa8b2c6d2f2241e6813e2d6ff660dfeff02..8dbc54da7d7078004ff61eddd1d1f82a71f0f257 100644 (file)
@@ -537,7 +537,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
                ri->desc.ops = &da9030_regulator_ldo1_15_ops;
 
        rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdev->dev.platform_data, ri);
+                                 pdev->dev.platform_data, ri, NULL);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c
new file mode 100644 (file)
index 0000000..3767364
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+* da9052-regulator.c: Regulator driver for DA9052
+*
+* Copyright(c) 2011 Dialog Semiconductor Ltd.
+*
+* Author: David Dajun Chen <dchen@diasemi.com>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+*/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+#include <linux/mfd/da9052/pdata.h>
+
+/* Buck step size */
+#define DA9052_BUCK_PERI_3uV_STEP              100000
+#define DA9052_BUCK_PERI_REG_MAP_UPTO_3uV      24
+#define DA9052_CONST_3uV                       3000000
+
+#define DA9052_MIN_UA          0
+#define DA9052_MAX_UA          3
+#define DA9052_CURRENT_RANGE   4
+
+/* Bit masks */
+#define DA9052_BUCK_ILIM_MASK_EVEN     0x0c
+#define DA9052_BUCK_ILIM_MASK_ODD      0xc0
+
+static const u32 da9052_current_limits[3][4] = {
+       {700000, 800000, 1000000, 1200000},     /* DA9052-BC BUCKs */
+       {1600000, 2000000, 2400000, 3000000},   /* DA9053-AA/Bx BUCK-CORE */
+       {800000, 1000000, 1200000, 1500000},    /* DA9053-AA/Bx BUCK-PRO,
+                                                * BUCK-MEM and BUCK-PERI
+                                               */
+};
+
+struct da9052_regulator_info {
+       struct regulator_desc reg_desc;
+       int step_uV;
+       int min_uV;
+       int max_uV;
+       unsigned char volt_shift;
+       unsigned char en_bit;
+       unsigned char activate_bit;
+};
+
+struct da9052_regulator {
+       struct da9052 *da9052;
+       struct da9052_regulator_info *info;
+       struct regulator_dev *rdev;
+};
+
+static int verify_range(struct da9052_regulator_info *info,
+                        int min_uV, int max_uV)
+{
+       if (min_uV > info->max_uV || max_uV < info->min_uV)
+               return -EINVAL;
+
+       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);
+       int offset = rdev_get_id(rdev);
+       int ret, row = 2;
+
+       ret = da9052_reg_read(regulator->da9052, DA9052_BUCKA_REG + offset/2);
+       if (ret < 0)
+               return ret;
+
+       /* Determine the even or odd position of the buck current limit
+        * register field
+       */
+       if (offset % 2 == 0)
+               ret = (ret & DA9052_BUCK_ILIM_MASK_EVEN) >> 2;
+       else
+               ret = (ret & DA9052_BUCK_ILIM_MASK_ODD) >> 6;
+
+       /* Select the appropriate current limit range */
+       if (regulator->da9052->chip_id == DA9052)
+               row = 0;
+       else if (offset == 0)
+               row = 1;
+
+       return da9052_current_limits[row][ret];
+}
+
+static int da9052_dcdc_set_current_limit(struct regulator_dev *rdev, int min_uA,
+                                         int max_uA)
+{
+       struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
+       int offset = rdev_get_id(rdev);
+       int reg_val = 0;
+       int i, row = 2;
+
+       /* Select the appropriate current limit range */
+       if (regulator->da9052->chip_id == DA9052)
+               row = 0;
+       else if (offset == 0)
+               row = 1;
+
+       if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] ||
+           max_uA < da9052_current_limits[row][DA9052_MIN_UA])
+               return -EINVAL;
+
+       for (i = 0; i < DA9052_CURRENT_RANGE; i++) {
+               if (min_uA <= da9052_current_limits[row][i]) {
+                       reg_val = i;
+                       break;
+               }
+       }
+
+       /* Determine the even or odd position of the buck current limit
+        * register field
+       */
+       if (offset % 2 == 0)
+               return da9052_reg_update(regulator->da9052,
+                                        DA9052_BUCKA_REG + offset/2,
+                                        DA9052_BUCK_ILIM_MASK_EVEN,
+                                        reg_val << 2);
+       else
+               return da9052_reg_update(regulator->da9052,
+                                        DA9052_BUCKA_REG + offset/2,
+                                        DA9052_BUCK_ILIM_MASK_ODD,
+                                        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 volt_uV;
+
+       volt_uV = info->min_uV + info->step_uV * selector;
+
+       if (volt_uV > info->max_uV)
+               return -EINVAL;
+
+       return volt_uV;
+}
+
+static int da9052_regulator_set_voltage_int(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;
+
+       *selector = (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, 0,
+                                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, 0,
+                                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 +
+                           ((min_uV - DA9052_CONST_3uV) /
+                           (DA9052_BUCK_PERI_3uV_STEP));
+       else
+               *selector = (min_uV - info->min_uV) / info->step_uV;
+
+       ret = da9052_list_buckperi_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);
+       if (ret < 0)
+               return ret;
+
+       ret &= ((1 << info->volt_shift) - 1);
+
+       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,
+       .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,
+};
+
+static struct regulator_ops da9052_ldo_ops = {
+       .set_voltage = da9052_set_ldo_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,
+};
+
+#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,\
+               .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,\
+               .ops = &da9052_ldo_ops,\
+               .type = REGULATOR_VOLTAGE,\
+               .id = _id,\
+               .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_DCDC(_id, step, min, max, sbits, ebits, abits) \
+{\
+       .reg_desc = {\
+               .name = "BUCK" #_id,\
+               .ops = &da9052_dcdc_ops,\
+               .type = REGULATOR_VOLTAGE,\
+               .id = _id,\
+               .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_BUCKPERI(_id, step, min, max, sbits, ebits, abits) \
+{\
+       .reg_desc = {\
+               .name = "BUCK" #_id,\
+               .ops = &da9052_buckperi_ops,\
+               .type = REGULATOR_VOLTAGE,\
+               .id = _id,\
+               .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),
+};
+
+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),
+};
+
+static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id,
+                                                                int id)
+{
+       struct da9052_regulator_info *info;
+       int i;
+
+       switch (chip_id) {
+       case DA9052:
+               for (i = 0; i < ARRAY_SIZE(da9052_regulator_info); i++) {
+                       info = &da9052_regulator_info[i];
+                       if (info->reg_desc.id == id)
+                               return info;
+               }
+               break;
+       case DA9053_AA:
+       case DA9053_BA:
+       case DA9053_BB:
+               for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) {
+                       info = &da9053_regulator_info[i];
+                       if (info->reg_desc.id == id)
+                               return info;
+               }
+               break;
+       }
+
+       return NULL;
+}
+
+static int __devinit da9052_regulator_probe(struct platform_device *pdev)
+{
+       struct da9052_regulator *regulator;
+       struct da9052 *da9052;
+       struct da9052_pdata *pdata;
+       int ret;
+
+       regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9052_regulator),
+                                GFP_KERNEL);
+       if (!regulator)
+               return -ENOMEM;
+
+       da9052 = dev_get_drvdata(pdev->dev.parent);
+       pdata = da9052->dev->platform_data;
+       regulator->da9052 = da9052;
+
+       regulator->info = find_regulator_info(regulator->da9052->chip_id,
+                                             pdev->id);
+       if (regulator->info == NULL) {
+               dev_err(&pdev->dev, "invalid regulator ID specified\n");
+               ret = -EINVAL;
+               goto err;
+       }
+       regulator->rdev = regulator_register(&regulator->info->reg_desc,
+                                            &pdev->dev,
+                                            pdata->regulators[pdev->id],
+                                            regulator, NULL);
+       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;
+       }
+
+       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)
+{
+       struct da9052_regulator *regulator = platform_get_drvdata(pdev);
+
+       regulator_unregister(regulator->rdev);
+       devm_kfree(&pdev->dev, regulator);
+
+       return 0;
+}
+
+static struct platform_driver da9052_regulator_driver = {
+       .probe = da9052_regulator_probe,
+       .remove = __devexit_p(da9052_regulator_remove),
+       .driver = {
+               .name = "da9052-regulator",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init da9052_regulator_init(void)
+{
+       return platform_driver_register(&da9052_regulator_driver);
+}
+subsys_initcall(da9052_regulator_init);
+
+static void __exit da9052_regulator_exit(void)
+{
+       platform_driver_unregister(&da9052_regulator_driver);
+}
+module_exit(da9052_regulator_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-regulator");
index 78329751af542dc36d80fc58d0c085ab24b99401..515443fcd26b09ecd6616b6f2084069c3b407912 100644 (file)
@@ -486,7 +486,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
 
                /* register with the regulator framework */
                info->rdev = regulator_register(&info->desc, &pdev->dev,
-                               init_data, info);
+                               init_data, info, NULL);
                if (IS_ERR(info->rdev)) {
                        err = PTR_ERR(info->rdev);
                        dev_err(&pdev->dev, "failed to register %s: err %i\n",
index b8f520513ce74b47beac3ed234fda7ad17cbb50c..0ee00de4be72867e38febb48ae35d4f8f115bc4f 100644 (file)
@@ -42,7 +42,7 @@ static int __devinit dummy_regulator_probe(struct platform_device *pdev)
        int ret;
 
        dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
-                                                 &dummy_initdata, NULL);
+                                                 &dummy_initdata, NULL, NULL);
        if (IS_ERR(dummy_regulator_rdev)) {
                ret = PTR_ERR(dummy_regulator_rdev);
                pr_err("Failed to register regulator: %d\n", ret);
index 21ecf212a5227643abcad804c855f699be32f338..e24e3a174c4b343b0dfbf32a52d69dceee60fb10 100644 (file)
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/machine.h>
 
 struct fixed_voltage_data {
        struct regulator_desc desc;
@@ -38,6 +42,58 @@ struct fixed_voltage_data {
        bool is_enabled;
 };
 
+
+/**
+ * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
+ * @dev: device requesting for fixed_voltage_config
+ *
+ * Populates fixed_voltage_config structure by extracting data from device
+ * tree node, returns a pointer to the populated structure of NULL if memory
+ * alloc fails.
+ */
+static struct fixed_voltage_config *
+of_get_fixed_voltage_config(struct device *dev)
+{
+       struct fixed_voltage_config *config;
+       struct device_node *np = dev->of_node;
+       const __be32 *delay;
+       struct regulator_init_data *init_data;
+
+       config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
+                                                                GFP_KERNEL);
+       if (!config)
+               return NULL;
+
+       config->init_data = of_get_regulator_init_data(dev, dev->of_node);
+       if (!config->init_data)
+               return NULL;
+
+       init_data = config->init_data;
+       init_data->constraints.apply_uV = 0;
+
+       config->supply_name = init_data->constraints.name;
+       if (init_data->constraints.min_uV == init_data->constraints.max_uV) {
+               config->microvolts = init_data->constraints.min_uV;
+       } else {
+               dev_err(dev,
+                        "Fixed regulator specified with variable voltages\n");
+               return NULL;
+       }
+
+       if (init_data->constraints.boot_on)
+               config->enabled_at_boot = true;
+
+       config->gpio = of_get_named_gpio(np, "gpio", 0);
+       delay = of_get_property(np, "startup-delay-us", NULL);
+       if (delay)
+               config->startup_delay = be32_to_cpu(*delay);
+
+       if (of_find_property(np, "enable-active-high", NULL))
+               config->enable_high = true;
+
+       return config;
+}
+
 static int fixed_voltage_is_enabled(struct regulator_dev *dev)
 {
        struct fixed_voltage_data *data = rdev_get_drvdata(dev);
@@ -80,7 +136,10 @@ static int fixed_voltage_get_voltage(struct regulator_dev *dev)
 {
        struct fixed_voltage_data *data = rdev_get_drvdata(dev);
 
-       return data->microvolts;
+       if (data->microvolts)
+               return data->microvolts;
+       else
+               return -EINVAL;
 }
 
 static int fixed_voltage_list_voltage(struct regulator_dev *dev,
@@ -105,10 +164,18 @@ static struct regulator_ops fixed_voltage_ops = {
 
 static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
 {
-       struct fixed_voltage_config *config = pdev->dev.platform_data;
+       struct fixed_voltage_config *config;
        struct fixed_voltage_data *drvdata;
        int ret;
 
+       if (pdev->dev.of_node)
+               config = of_get_fixed_voltage_config(&pdev->dev);
+       else
+               config = pdev->dev.platform_data;
+
+       if (!config)
+               return -ENOMEM;
+
        drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
        if (drvdata == NULL) {
                dev_err(&pdev->dev, "Failed to allocate device data\n");
@@ -180,7 +247,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
        }
 
        drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
-                                         config->init_data, drvdata);
+                                         config->init_data, drvdata,
+                                         pdev->dev.of_node);
        if (IS_ERR(drvdata->dev)) {
                ret = PTR_ERR(drvdata->dev);
                dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
@@ -217,12 +285,23 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
        return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id fixed_of_match[] __devinitconst = {
+       { .compatible = "regulator-fixed", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, fixed_of_match);
+#else
+#define fixed_of_match NULL
+#endif
+
 static struct platform_driver regulator_fixed_voltage_driver = {
        .probe          = reg_fixed_voltage_probe,
        .remove         = __devexit_p(reg_fixed_voltage_remove),
        .driver         = {
                .name           = "reg-fixed-voltage",
                .owner          = THIS_MODULE,
+               .of_match_table = fixed_of_match,
        },
 };
 
index f0acf52498bd4e312aee97fda6711ec0e498291e..42e1cb1835e54e9534ced30aa7aaf49f2897bf38 100644 (file)
@@ -284,7 +284,7 @@ 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);
+                                         config->init_data, drvdata, NULL);
        if (IS_ERR(drvdata->dev)) {
                ret = PTR_ERR(drvdata->dev);
                dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
index e4b3592e81767856cdadd4543a6e25bb001d695d..c1a456c4257c1b5f3b23a553ee87a1a67f939a00 100644 (file)
@@ -170,7 +170,7 @@ static int __devinit isl6271a_probe(struct i2c_client *i2c,
 
        for (i = 0; i < 3; i++) {
                pmic->rdev[i] = regulator_register(&isl_rd[i], &i2c->dev,
-                                               init_data, pmic);
+                                               init_data, pmic, NULL);
                if (IS_ERR(pmic->rdev[i])) {
                        dev_err(&i2c->dev, "failed to register %s\n", id->name);
                        err = PTR_ERR(pmic->rdev[i]);
index 72b16b5f3db6fca2f7a2ded2ce55344256ba327f..0cfabd318a59faa015b21226ebe9417f91ac7f12 100644 (file)
@@ -451,7 +451,7 @@ static int __devinit setup_regulators(struct lp3971 *lp3971,
        for (i = 0; i < pdata->num_regulators; i++) {
                struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
                lp3971->rdev[i] = regulator_register(&regulators[reg->id],
-                                       lp3971->dev, reg->initdata, lp3971);
+                               lp3971->dev, reg->initdata, lp3971, NULL);
 
                if (IS_ERR(lp3971->rdev[i])) {
                        err = PTR_ERR(lp3971->rdev[i]);
index fbc5e3741befffc8dbd097e0653881ff3c149459..49a15eefe5fe25390bdaf52cd0455675565cb516 100644 (file)
@@ -555,7 +555,7 @@ static int __devinit setup_regulators(struct lp3972 *lp3972,
        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);
+                               lp3972->dev, reg->initdata, lp3972, NULL);
 
                if (IS_ERR(lp3972->rdev[i])) {
                        err = PTR_ERR(lp3972->rdev[i]);
index 3f49512c513488583f1a58103f6df508614635f9..40e7a4db28534268a746dcf54db3564c8b9ab098 100644 (file)
@@ -214,7 +214,7 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
                }
                rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
                                             pdata->subdevs[i].platform_data,
-                                            max1586);
+                                            max1586, NULL);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(&client->dev, "failed to register %s\n",
index 1062cf9f02dc3303a7fae53a23203dd21a7707a8..b06a2399587c0e08fec38c8c827da6859130840f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/regulator/driver.h>
 #include <linux/slab.h>
 #include <linux/regulator/max8649.h>
+#include <linux/regmap.h>
 
 #define MAX8649_DCDC_VMIN      750000          /* uV */
 #define MAX8649_DCDC_VMAX      1380000         /* uV */
@@ -49,9 +50,8 @@
 
 struct max8649_regulator_info {
        struct regulator_dev    *regulator;
-       struct i2c_client       *i2c;
        struct device           *dev;
-       struct mutex            io_lock;
+       struct regmap           *regmap;
 
        int             vol_reg;
        unsigned        mode:2; /* bit[1:0] = VID1, VID0 */
@@ -63,71 +63,6 @@ struct max8649_regulator_info {
 
 /* I2C operations */
 
-static inline int max8649_read_device(struct i2c_client *i2c,
-                                     int reg, int bytes, void *dest)
-{
-       unsigned char data;
-       int ret;
-
-       data = (unsigned char)reg;
-       ret = i2c_master_send(i2c, &data, 1);
-       if (ret < 0)
-               return ret;
-       ret = i2c_master_recv(i2c, dest, bytes);
-       if (ret < 0)
-               return ret;
-       return 0;
-}
-
-static inline int max8649_write_device(struct i2c_client *i2c,
-                                      int reg, int bytes, void *src)
-{
-       unsigned char buf[bytes + 1];
-       int ret;
-
-       buf[0] = (unsigned char)reg;
-       memcpy(&buf[1], src, bytes);
-
-       ret = i2c_master_send(i2c, buf, bytes + 1);
-       if (ret < 0)
-               return ret;
-       return 0;
-}
-
-static int max8649_reg_read(struct i2c_client *i2c, int reg)
-{
-       struct max8649_regulator_info *info = i2c_get_clientdata(i2c);
-       unsigned char data;
-       int ret;
-
-       mutex_lock(&info->io_lock);
-       ret = max8649_read_device(i2c, reg, 1, &data);
-       mutex_unlock(&info->io_lock);
-
-       if (ret < 0)
-               return ret;
-       return (int)data;
-}
-
-static int max8649_set_bits(struct i2c_client *i2c, int reg,
-                           unsigned char mask, unsigned char data)
-{
-       struct max8649_regulator_info *info = i2c_get_clientdata(i2c);
-       unsigned char value;
-       int ret;
-
-       mutex_lock(&info->io_lock);
-       ret = max8649_read_device(i2c, reg, 1, &value);
-       if (ret < 0)
-               goto out;
-       value &= ~mask;
-       value |= data;
-       ret = max8649_write_device(i2c, reg, 1, &value);
-out:
-       mutex_unlock(&info->io_lock);
-       return ret;
-}
-
 static inline int check_range(int min_uV, int max_uV)
 {
        if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX)
@@ -144,13 +79,14 @@ static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index)
 static int max8649_get_voltage(struct regulator_dev *rdev)
 {
        struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+       unsigned int val;
        unsigned char data;
        int ret;
 
-       ret = max8649_reg_read(info->i2c, info->vol_reg);
-       if (ret < 0)
+       ret = regmap_read(info->regmap, info->vol_reg, &val);
+       if (ret != 0)
                return ret;
-       data = (unsigned char)ret & MAX8649_VOL_MASK;
+       data = (unsigned char)val & MAX8649_VOL_MASK;
        return max8649_list_voltage(rdev, data);
 }
 
@@ -170,14 +106,14 @@ static int max8649_set_voltage(struct regulator_dev *rdev,
        mask = MAX8649_VOL_MASK;
        *selector = data & mask;
 
-       return max8649_set_bits(info->i2c, info->vol_reg, mask, data);
+       return regmap_update_bits(info->regmap, info->vol_reg, mask, data);
 }
 
 /* EN_PD means pulldown on EN input */
 static int max8649_enable(struct regulator_dev *rdev)
 {
        struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
-       return max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_EN_PD, 0);
+       return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD, 0);
 }
 
 /*
@@ -187,38 +123,40 @@ static int max8649_enable(struct regulator_dev *rdev)
 static int max8649_disable(struct regulator_dev *rdev)
 {
        struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
-       return max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_EN_PD,
+       return regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_EN_PD,
                                MAX8649_EN_PD);
 }
 
 static int max8649_is_enabled(struct regulator_dev *rdev)
 {
        struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+       unsigned int val;
        int ret;
 
-       ret = max8649_reg_read(info->i2c, MAX8649_CONTROL);
-       if (ret < 0)
+       ret = regmap_read(info->regmap, MAX8649_CONTROL, &val);
+       if (ret != 0)
                return ret;
-       return !((unsigned char)ret & MAX8649_EN_PD);
+       return !((unsigned char)val & MAX8649_EN_PD);
 }
 
 static int max8649_enable_time(struct regulator_dev *rdev)
 {
        struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
        int voltage, rate, ret;
+       unsigned int val;
 
        /* get voltage */
-       ret = max8649_reg_read(info->i2c, info->vol_reg);
-       if (ret < 0)
+       ret = regmap_read(info->regmap, info->vol_reg, &val);
+       if (ret != 0)
                return ret;
-       ret &= MAX8649_VOL_MASK;
+       val &= MAX8649_VOL_MASK;
        voltage = max8649_list_voltage(rdev, (unsigned char)ret); /* uV */
 
        /* get rate */
-       ret = max8649_reg_read(info->i2c, MAX8649_RAMP);
-       if (ret < 0)
+       ret = regmap_read(info->regmap, MAX8649_RAMP, &val);
+       if (ret != 0)
                return ret;
-       ret = (ret & MAX8649_RAMP_MASK) >> 5;
+       ret = (val & MAX8649_RAMP_MASK) >> 5;
        rate = (32 * 1000) >> ret;      /* uV/uS */
 
        return DIV_ROUND_UP(voltage, rate);
@@ -230,12 +168,12 @@ static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
 
        switch (mode) {
        case REGULATOR_MODE_FAST:
-               max8649_set_bits(info->i2c, info->vol_reg, MAX8649_FORCE_PWM,
-                                MAX8649_FORCE_PWM);
+               regmap_update_bits(info->regmap, info->vol_reg, MAX8649_FORCE_PWM,
+                                  MAX8649_FORCE_PWM);
                break;
        case REGULATOR_MODE_NORMAL:
-               max8649_set_bits(info->i2c, info->vol_reg,
-                                MAX8649_FORCE_PWM, 0);
+               regmap_update_bits(info->regmap, info->vol_reg,
+                                  MAX8649_FORCE_PWM, 0);
                break;
        default:
                return -EINVAL;
@@ -246,10 +184,13 @@ static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
 static unsigned int max8649_get_mode(struct regulator_dev *rdev)
 {
        struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
+       unsigned int val;
        int ret;
 
-       ret = max8649_reg_read(info->i2c, info->vol_reg);
-       if (ret & MAX8649_FORCE_PWM)
+       ret = regmap_read(info->regmap, info->vol_reg, &val);
+       if (ret != 0)
+               return ret;
+       if (val & MAX8649_FORCE_PWM)
                return REGULATOR_MODE_FAST;
        return REGULATOR_MODE_NORMAL;
 }
@@ -275,11 +216,17 @@ static struct regulator_desc dcdc_desc = {
        .owner          = THIS_MODULE,
 };
 
+static struct regmap_config max8649_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
 static int __devinit max8649_regulator_probe(struct i2c_client *client,
                                             const struct i2c_device_id *id)
 {
        struct max8649_platform_data *pdata = client->dev.platform_data;
        struct max8649_regulator_info *info = NULL;
+       unsigned int val;
        unsigned char data;
        int ret;
 
@@ -289,9 +236,14 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
                return -ENOMEM;
        }
 
-       info->i2c = client;
+       info->regmap = 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;
+       }
+
        info->dev = &client->dev;
-       mutex_init(&info->io_lock);
        i2c_set_clientdata(client, info);
 
        info->mode = pdata->mode;
@@ -312,8 +264,8 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
                break;
        }
 
-       ret = max8649_reg_read(info->i2c, MAX8649_CHIP_ID1);
-       if (ret < 0) {
+       ret = regmap_read(info->regmap, MAX8649_CHIP_ID1, &val);
+       if (ret != 0) {
                dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
                        ret);
                goto out;
@@ -321,33 +273,33 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
        dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret);
 
        /* enable VID0 & VID1 */
-       max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
+       regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
 
        /* enable/disable external clock synchronization */
        info->extclk = pdata->extclk;
        data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0;
-       max8649_set_bits(info->i2c, info->vol_reg, MAX8649_SYNC_EXTCLK, data);
+       regmap_update_bits(info->regmap, info->vol_reg, MAX8649_SYNC_EXTCLK, data);
        if (info->extclk) {
                /* set external clock frequency */
                info->extclk_freq = pdata->extclk_freq;
-               max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK,
-                                info->extclk_freq << 6);
+               regmap_update_bits(info->regmap, MAX8649_SYNC, MAX8649_EXT_MASK,
+                                  info->extclk_freq << 6);
        }
 
        if (pdata->ramp_timing) {
                info->ramp_timing = pdata->ramp_timing;
-               max8649_set_bits(info->i2c, MAX8649_RAMP, MAX8649_RAMP_MASK,
-                                info->ramp_timing << 5);
+               regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_MASK,
+                                  info->ramp_timing << 5);
        }
 
        info->ramp_down = pdata->ramp_down;
        if (info->ramp_down) {
-               max8649_set_bits(info->i2c, MAX8649_RAMP, MAX8649_RAMP_DOWN,
-                                MAX8649_RAMP_DOWN);
+               regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_DOWN,
+                                  MAX8649_RAMP_DOWN);
        }
 
        info->regulator = regulator_register(&dcdc_desc, &client->dev,
-                                            pdata->regulator, info);
+                                            pdata->regulator, info, NULL);
        if (IS_ERR(info->regulator)) {
                dev_err(info->dev, "failed to register regulator %s\n",
                        dcdc_desc.name);
@@ -358,6 +310,8 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
        dev_info(info->dev, "Max8649 regulator device is detected.\n");
        return 0;
 out:
+       regmap_exit(info->regmap);
+fail:
        kfree(info);
        return ret;
 }
@@ -369,6 +323,7 @@ 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);
        }
 
index 33f5d9a492efa809b3177ce1034bef633c32c037..a838e664569f26f7fb13c7974cc8c20abee2f567 100644 (file)
@@ -449,7 +449,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
 
                rdev[i] = regulator_register(&max8660_reg[id], &client->dev,
                                             pdata->subdevs[i].platform_data,
-                                            max8660);
+                                            max8660, NULL);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(&client->dev, "failed to register %s\n",
index cc9ec0e0327183bb58aa81a69343905e2765db02..cc290d37c463c3059b19cd9f061b430802f8c491 100644 (file)
 #define SD1_DVM_SHIFT          5               /* SDCTL1 bit5 */
 #define SD1_DVM_EN             6               /* SDV1 bit 6 */
 
-/* bit definitions in SD & LDO control registers */
-#define OUT_ENABLE             0x1f            /* Power U/D sequence as I2C */
-#define OUT_DISABLE            0x1e            /* Power U/D sequence as I2C */
+/* bit definitions in LDO control registers */
+#define LDO_SEQ_I2C            0x7             /* Power U/D by i2c */
+#define LDO_SEQ_MASK           0x7             /* Power U/D sequence mask */
+#define LDO_SEQ_SHIFT          2               /* Power U/D sequence offset */
+#define LDO_I2C_EN             0x1             /* Enable by i2c */
+#define LDO_I2C_EN_MASK                0x1             /* Enable mask by i2c */
+#define LDO_I2C_EN_SHIFT       0               /* Enable offset by i2c */
 
 struct max8925_regulator_info {
        struct regulator_desc   desc;
@@ -40,7 +44,6 @@ struct max8925_regulator_info {
        int     vol_reg;
        int     vol_shift;
        int     vol_nbits;
-       int     enable_bit;
        int     enable_reg;
 };
 
@@ -98,8 +101,10 @@ static int max8925_enable(struct regulator_dev *rdev)
        struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
 
        return max8925_set_bits(info->i2c, info->enable_reg,
-                               OUT_ENABLE << info->enable_bit,
-                               OUT_ENABLE << info->enable_bit);
+                               LDO_SEQ_MASK << LDO_SEQ_SHIFT |
+                               LDO_I2C_EN_MASK << LDO_I2C_EN_SHIFT,
+                               LDO_SEQ_I2C << LDO_SEQ_SHIFT |
+                               LDO_I2C_EN << LDO_I2C_EN_SHIFT);
 }
 
 static int max8925_disable(struct regulator_dev *rdev)
@@ -107,20 +112,24 @@ static int max8925_disable(struct regulator_dev *rdev)
        struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
 
        return max8925_set_bits(info->i2c, info->enable_reg,
-                               OUT_ENABLE << info->enable_bit,
-                               OUT_DISABLE << info->enable_bit);
+                               LDO_SEQ_MASK << LDO_SEQ_SHIFT |
+                               LDO_I2C_EN_MASK << LDO_I2C_EN_SHIFT,
+                               LDO_SEQ_I2C << LDO_SEQ_SHIFT);
 }
 
 static int max8925_is_enabled(struct regulator_dev *rdev)
 {
        struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
-       int ret;
+       int ldo_seq, ret;
 
        ret = max8925_reg_read(info->i2c, info->enable_reg);
        if (ret < 0)
                return ret;
-
-       return ret & (1 << info->enable_bit);
+       ldo_seq = (ret >> LDO_SEQ_SHIFT) & LDO_SEQ_MASK;
+       if (ldo_seq != LDO_SEQ_I2C)
+               return 1;
+       else
+               return ret & (LDO_I2C_EN_MASK << LDO_I2C_EN_SHIFT);
 }
 
 static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
@@ -188,7 +197,6 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
        .vol_shift      = 0,                                    \
        .vol_nbits      = 6,                                    \
        .enable_reg     = MAX8925_SDCTL##_id,                   \
-       .enable_bit     = 0,                                    \
 }
 
 #define MAX8925_LDO(_id, min, max, step)                       \
@@ -207,7 +215,6 @@ static struct regulator_ops max8925_regulator_ldo_ops = {
        .vol_shift      = 0,                                    \
        .vol_nbits      = 6,                                    \
        .enable_reg     = MAX8925_LDOCTL##_id,                  \
-       .enable_bit     = 0,                                    \
 }
 
 static struct max8925_regulator_info max8925_regulator_info[] = {
@@ -266,7 +273,7 @@ static int __devinit max8925_regulator_probe(struct platform_device *pdev)
        ri->chip = chip;
 
        rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdata->regulator[pdev->id], ri);
+                                 pdata->regulator[pdev->id], ri, NULL);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
index 3883d85c5b8864835c41b2b5b74b919696bd02d8..75d89400c1234db391556ec14e0ced14775580ac 100644 (file)
@@ -208,7 +208,7 @@ static int __devinit max8952_pmic_probe(struct i2c_client *client,
        max8952->pdata = pdata;
 
        max8952->rdev = regulator_register(&regulator, max8952->dev,
-                       &pdata->reg_data, max8952);
+                       &pdata->reg_data, max8952, NULL);
 
        if (IS_ERR(max8952->rdev)) {
                ret = PTR_ERR(max8952->rdev);
index 6176129a27e531e20c8921537798648c723f78ec..d26e8646277b3eeb8cd7bd1a0d436a04c8d3a21c 100644 (file)
@@ -1146,7 +1146,7 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
                        regulators[id].n_voltages = 16;
 
                rdev[i] = regulator_register(&regulators[id], max8997->dev,
-                               pdata->regulators[i].initdata, max8997);
+                               pdata->regulators[i].initdata, max8997, NULL);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(max8997->dev, "regulator init failed for %d\n",
index 41a1495eec2bc28c5d58a9b68b8c2ef2f7b558a3..2d38c2493a070c4ee6b409266f51dc6704ca4993 100644 (file)
@@ -847,7 +847,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
                        regulators[index].n_voltages = count;
                }
                rdev[i] = regulator_register(&regulators[index], max8998->dev,
-                               pdata->regulators[i].initdata, max8998);
+                               pdata->regulators[i].initdata, max8998, NULL);
                if (IS_ERR(rdev[i])) {
                        ret = PTR_ERR(rdev[i]);
                        dev_err(max8998->dev, "regulator init failed\n");
index 8479082e1aeaaafa1d0ca5780101855c00863df7..8e9b90ad88ae35cea58ef488c41ba1383da918e2 100644 (file)
@@ -344,7 +344,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
 
-       priv = kzalloc(sizeof(*priv) +
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv) +
                        pdata->num_regulators * sizeof(priv->regulators[0]),
                        GFP_KERNEL);
        if (!priv)
@@ -357,7 +357,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
                init_data = &pdata->regulators[i];
                priv->regulators[i] = regulator_register(
                                &mc13783_regulators[init_data->id].desc,
-                               &pdev->dev, init_data->init_data, priv);
+                               &pdev->dev, init_data->init_data, priv, NULL);
 
                if (IS_ERR(priv->regulators[i])) {
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -374,8 +374,6 @@ err:
        while (--i >= 0)
                regulator_unregister(priv->regulators[i]);
 
-       kfree(priv);
-
        return ret;
 }
 
@@ -391,7 +389,6 @@ static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
        for (i = 0; i < pdata->num_regulators; i++)
                regulator_unregister(priv->regulators[i]);
 
-       kfree(priv);
        return 0;
 }
 
index 023d17d022cf7ba329068b61a7d3b69695c44a82..e8cfc99dd8f066eb4a4ab3bc99007b70cf358bbc 100644 (file)
@@ -527,18 +527,27 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
        struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
        struct mc13xxx_regulator_platform_data *pdata =
                dev_get_platdata(&pdev->dev);
-       struct mc13xxx_regulator_init_data *init_data;
+       struct mc13xxx_regulator_init_data *mc13xxx_data;
        int i, ret;
+       int num_regulators = 0;
        u32 val;
 
-       priv = kzalloc(sizeof(*priv) +
-               pdata->num_regulators * sizeof(priv->regulators[0]),
+       num_regulators = mc13xxx_get_num_regulators_dt(pdev);
+       if (num_regulators <= 0 && pdata)
+               num_regulators = pdata->num_regulators;
+       if (num_regulators <= 0)
+               return -EINVAL;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv) +
+               num_regulators * sizeof(priv->regulators[0]),
                GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
+       priv->num_regulators = num_regulators;
        priv->mc13xxx_regulators = mc13892_regulators;
        priv->mc13xxx = mc13892;
+       platform_set_drvdata(pdev, priv);
 
        mc13xxx_lock(mc13892);
        ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val);
@@ -569,11 +578,27 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
                = mc13892_vcam_set_mode;
        mc13892_regulators[MC13892_VCAM].desc.ops->get_mode
                = mc13892_vcam_get_mode;
-       for (i = 0; i < pdata->num_regulators; i++) {
-               init_data = &pdata->regulators[i];
+
+       mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators,
+                                       ARRAY_SIZE(mc13892_regulators));
+       for (i = 0; i < num_regulators; i++) {
+               struct regulator_init_data *init_data;
+               struct regulator_desc *desc;
+               struct device_node *node = NULL;
+               int id;
+
+               if (mc13xxx_data) {
+                       id = mc13xxx_data[i].id;
+                       init_data = mc13xxx_data[i].init_data;
+                       node = mc13xxx_data[i].node;
+               } else {
+                       id = pdata->regulators[i].id;
+                       init_data = pdata->regulators[i].init_data;
+               }
+               desc = &mc13892_regulators[id].desc;
+
                priv->regulators[i] = regulator_register(
-                       &mc13892_regulators[init_data->id].desc,
-                       &pdev->dev, init_data->init_data, priv);
+                       desc, &pdev->dev, init_data, priv, node);
 
                if (IS_ERR(priv->regulators[i])) {
                        dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -583,8 +608,6 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
                }
        }
 
-       platform_set_drvdata(pdev, priv);
-
        return 0;
 err:
        while (--i >= 0)
@@ -592,7 +615,6 @@ err:
 
 err_free:
        mc13xxx_unlock(mc13892);
-       kfree(priv);
 
        return ret;
 }
@@ -600,16 +622,13 @@ err_free:
 static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
 {
        struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
-       struct mc13xxx_regulator_platform_data *pdata =
-               dev_get_platdata(&pdev->dev);
        int i;
 
        platform_set_drvdata(pdev, NULL);
 
-       for (i = 0; i < pdata->num_regulators; i++)
+       for (i = 0; i < priv->num_regulators; i++)
                regulator_unregister(priv->regulators[i]);
 
-       kfree(priv);
        return 0;
 }
 
index 6532853a6ef5e2e92beb3174c13f1b430e071dc5..80ecafef1bc38b217abe30f1aa0537ca64d9b3d4 100644 (file)
 #include <linux/mfd/mc13xxx.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include "mc13xxx.h"
 
 static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
@@ -236,6 +238,61 @@ int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev)
 }
 EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled);
 
+#ifdef CONFIG_OF
+int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
+{
+       struct device_node *parent, *child;
+       int num = 0;
+
+       of_node_get(pdev->dev.parent->of_node);
+       parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
+       if (!parent)
+               return -ENODEV;
+
+       for_each_child_of_node(parent, child)
+               num++;
+
+       return num;
+}
+
+struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
+       struct platform_device *pdev, struct mc13xxx_regulator *regulators,
+       int num_regulators)
+{
+       struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
+       struct mc13xxx_regulator_init_data *data, *p;
+       struct device_node *parent, *child;
+       int i;
+
+       of_node_get(pdev->dev.parent->of_node);
+       parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators");
+       if (!parent)
+               return NULL;
+
+       data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators,
+                           GFP_KERNEL);
+       if (!data)
+               return NULL;
+       p = data;
+
+       for_each_child_of_node(parent, child) {
+               for (i = 0; i < num_regulators; i++) {
+                       if (!of_node_cmp(child->name,
+                                        regulators[i].desc.name)) {
+                               p->id = i;
+                               p->init_data = of_get_regulator_init_data(
+                                                       &pdev->dev, child);
+                               p->node = child;
+                               p++;
+                               break;
+                       }
+               }
+       }
+
+       return data;
+}
+#endif
+
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
 MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
index 27758267e12298858c6af4a4d66bb0a76be9df33..b3961c658b0594a8c728f780f1c49fd7830e4959 100644 (file)
@@ -29,6 +29,7 @@ struct mc13xxx_regulator_priv {
        struct mc13xxx *mc13xxx;
        u32 powermisc_pwgt_state;
        struct mc13xxx_regulator *mc13xxx_regulators;
+       int num_regulators;
        struct regulator_dev *regulators[];
 };
 
@@ -42,13 +43,32 @@ extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
                int min_uV, int max_uV, unsigned *selector);
 extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev);
 
+#ifdef CONFIG_OF
+extern int mc13xxx_get_num_regulators_dt(struct platform_device *pdev);
+extern struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
+       struct platform_device *pdev, struct mc13xxx_regulator *regulators,
+       int num_regulators);
+#else
+static inline int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
+{
+       return -ENODEV;
+}
+
+static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
+       struct platform_device *pdev, struct mc13xxx_regulator *regulators,
+       int num_regulators)
+{
+       return NULL;
+}
+#endif
+
 extern struct regulator_ops mc13xxx_regulator_ops;
 extern struct regulator_ops mc13xxx_fixed_regulator_ops;
 
 #define MC13xxx_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages, _ops)        \
        [prefix ## _name] = {                           \
                .desc = {                                               \
-                       .name = #prefix "_" #_name,                     \
+                       .name = #_name,                                 \
                        .n_voltages = ARRAY_SIZE(_voltages),            \
                        .ops = &_ops,                   \
                        .type = REGULATOR_VOLTAGE,                      \
@@ -66,7 +86,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops;
 #define MC13xxx_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops)     \
        [prefix ## _name] = {                           \
                .desc = {                                               \
-                       .name = #prefix "_" #_name,                     \
+                       .name = #_name,                                 \
                        .n_voltages = ARRAY_SIZE(_voltages),            \
                        .ops = &_ops,           \
                        .type = REGULATOR_VOLTAGE,                      \
@@ -81,7 +101,7 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops;
 #define MC13xxx_GPO_DEFINE(prefix, _name, _reg,  _voltages, _ops)      \
        [prefix ## _name] = {                           \
                .desc = {                                               \
-                       .name = #prefix "_" #_name,                     \
+                       .name = #_name,                                 \
                        .n_voltages = ARRAY_SIZE(_voltages),            \
                        .ops = &_ops,           \
                        .type = REGULATOR_VOLTAGE,                      \
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
new file mode 100644 (file)
index 0000000..f1651eb
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * OF helpers for regulator framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/regulator/machine.h>
+
+static void of_get_regulation_constraints(struct device_node *np,
+                                       struct regulator_init_data **init_data)
+{
+       const __be32 *min_uV, *max_uV, *uV_offset;
+       const __be32 *min_uA, *max_uA;
+       struct regulation_constraints *constraints = &(*init_data)->constraints;
+
+       constraints->name = of_get_property(np, "regulator-name", NULL);
+
+       min_uV = of_get_property(np, "regulator-min-microvolt", NULL);
+       if (min_uV)
+               constraints->min_uV = be32_to_cpu(*min_uV);
+       max_uV = of_get_property(np, "regulator-max-microvolt", NULL);
+       if (max_uV)
+               constraints->max_uV = be32_to_cpu(*max_uV);
+
+       /* Voltage change possible? */
+       if (constraints->min_uV != constraints->max_uV)
+               constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
+       /* Only one voltage?  Then make sure it's set. */
+       if (constraints->min_uV == constraints->max_uV)
+               constraints->apply_uV = true;
+
+       uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL);
+       if (uV_offset)
+               constraints->uV_offset = be32_to_cpu(*uV_offset);
+       min_uA = of_get_property(np, "regulator-min-microamp", NULL);
+       if (min_uA)
+               constraints->min_uA = be32_to_cpu(*min_uA);
+       max_uA = of_get_property(np, "regulator-max-microamp", NULL);
+       if (max_uA)
+               constraints->max_uA = be32_to_cpu(*max_uA);
+
+       /* Current change possible? */
+       if (constraints->min_uA != constraints->max_uA)
+               constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
+
+       if (of_find_property(np, "regulator-boot-on", NULL))
+               constraints->boot_on = true;
+
+       if (of_find_property(np, "regulator-always-on", NULL))
+               constraints->always_on = true;
+       else /* status change should be possible if not always on. */
+               constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;
+}
+
+/**
+ * of_get_regulator_init_data - extract regulator_init_data structure info
+ * @dev: device requesting for regulator_init_data
+ *
+ * Populates regulator_init_data structure by extracting data from device
+ * tree node, returns a pointer to the populated struture or NULL if memory
+ * alloc fails.
+ */
+struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
+                                               struct device_node *node)
+{
+       struct regulator_init_data *init_data;
+
+       if (!node)
+               return NULL;
+
+       init_data = devm_kzalloc(dev, sizeof(*init_data), GFP_KERNEL);
+       if (!init_data)
+               return NULL; /* Out of memory? */
+
+       of_get_regulation_constraints(node, &init_data);
+       return init_data;
+}
+EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
index 31f6e11a7f16f6c1621e99bcc2b3b8d4704cd224..a5aab1b08bcf6f246255b42600a3a355fc7de5a5 100644 (file)
@@ -277,7 +277,7 @@ static int __devinit pcap_regulator_probe(struct platform_device *pdev)
        void *pcap = dev_get_drvdata(pdev->dev.parent);
 
        rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev,
-                               pdev->dev.platform_data, pcap);
+                               pdev->dev.platform_data, pcap, NULL);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
index 69a11d9dd87f8388ccb88e4787cefe518888b78e..1d1c310562975a7204db2c30d7de230c6bec1514 100644 (file)
@@ -320,7 +320,7 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
        pcf = dev_to_pcf50633(pdev->dev.parent);
 
        rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data, pcf);
+                                 pdev->dev.platform_data, pcf, NULL);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
index 1011873896dc9205b4844aed9531de8cd9051531..d9278da18a9e9cede299722093977e2c572ccd3d 100644 (file)
@@ -151,7 +151,8 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
        /* Register regulator with framework */
        tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
                                             &tps6105x->client->dev,
-                                            pdata->regulator_data, tps6105x);
+                                            pdata->regulator_data, tps6105x,
+                                            NULL);
        if (IS_ERR(tps6105x->regulator)) {
                ret = PTR_ERR(tps6105x->regulator);
                dev_err(&tps6105x->client->dev,
index 9fb4c7b81753d99ff8effaa781f2d8b5930261d8..18d61a0529a9476d6aa9a2368f7b6df53b258387 100644 (file)
@@ -152,48 +152,21 @@ struct tps_driver_data {
        u8 core_regulator;
 };
 
-static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask)
-{
-       return regmap_update_bits(tps->regmap, reg, mask, mask);
-}
-
-static int tps_65023_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask)
-{
-       return regmap_update_bits(tps->regmap, reg, mask, 0);
-}
-
-static int tps_65023_reg_read(struct tps_pmic *tps, u8 reg)
-{
-       unsigned int val;
-       int ret;
-
-       ret = regmap_read(tps->regmap, reg, &val);
-
-       if (ret != 0)
-               return ret;
-       else
-               return val;
-}
-
-static int tps_65023_reg_write(struct tps_pmic *tps, u8 reg, u8 val)
-{
-       return regmap_write(tps->regmap, reg, val);
-}
-
 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;
-       data = tps_65023_reg_read(tps, TPS65023_REG_REG_CTRL);
+       ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
 
-       if (data < 0)
-               return data;
+       if (ret != 0)
+               return ret;
        else
                return (data & 1<<shift) ? 1 : 0;
 }
@@ -202,16 +175,17 @@ 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);
-       data = tps_65023_reg_read(tps, TPS65023_REG_REG_CTRL);
+       ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
 
-       if (data < 0)
-               return data;
+       if (ret != 0)
+               return ret;
        else
                return (data & 1<<shift) ? 1 : 0;
 }
@@ -226,7 +200,7 @@ static int tps65023_dcdc_enable(struct regulator_dev *dev)
                return -EINVAL;
 
        shift = TPS65023_NUM_REGULATOR - dcdc;
-       return tps_65023_set_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift);
+       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
 }
 
 static int tps65023_dcdc_disable(struct regulator_dev *dev)
@@ -239,7 +213,7 @@ static int tps65023_dcdc_disable(struct regulator_dev *dev)
                return -EINVAL;
 
        shift = TPS65023_NUM_REGULATOR - dcdc;
-       return tps_65023_clear_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift);
+       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
 }
 
 static int tps65023_ldo_enable(struct regulator_dev *dev)
@@ -252,7 +226,7 @@ static int tps65023_ldo_enable(struct regulator_dev *dev)
                return -EINVAL;
 
        shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
-       return tps_65023_set_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift);
+       return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
 }
 
 static int tps65023_ldo_disable(struct regulator_dev *dev)
@@ -265,21 +239,22 @@ static int tps65023_ldo_disable(struct regulator_dev *dev)
                return -EINVAL;
 
        shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
-       return tps_65023_clear_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift);
+       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);
+       int ret;
        int data, dcdc = rdev_get_id(dev);
 
        if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
                return -EINVAL;
 
        if (dcdc == tps->core_regulator) {
-               data = tps_65023_reg_read(tps, TPS65023_REG_DEF_CORE);
-               if (data < 0)
-                       return data;
+               ret = regmap_read(tps->regmap, TPS65023_REG_DEF_CORE, &data);
+               if (ret != 0)
+                       return ret;
                data &= (tps->info[dcdc]->table_len - 1);
                return tps->info[dcdc]->table[data] * 1000;
        } else
@@ -318,13 +293,13 @@ static int tps65023_dcdc_set_voltage(struct regulator_dev *dev,
        if (vsel == tps->info[dcdc]->table_len)
                goto failed;
 
-       ret = tps_65023_reg_write(tps, TPS65023_REG_DEF_CORE, vsel);
+       ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, vsel);
 
        /* Tell the chip that we have changed the value in DEFCORE
         * and its time to update the core voltage
         */
-       tps_65023_set_bits(tps, TPS65023_REG_CON_CTRL2,
-                                               TPS65023_REG_CTRL2_GO);
+       regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
+                       TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
 
        return ret;
 
@@ -336,13 +311,14 @@ static int tps65023_ldo_get_voltage(struct regulator_dev *dev)
 {
        struct tps_pmic *tps = rdev_get_drvdata(dev);
        int data, ldo = rdev_get_id(dev);
+       int ret;
 
        if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
                return -EINVAL;
 
-       data = tps_65023_reg_read(tps, TPS65023_REG_LDO_CTRL);
-       if (data < 0)
-               return data;
+       ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
+       if (ret != 0)
+               return ret;
 
        data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1));
        data &= (tps->info[ldo]->table_len - 1);
@@ -354,6 +330,7 @@ static int tps65023_ldo_set_voltage(struct regulator_dev *dev,
 {
        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;
@@ -377,13 +354,13 @@ static int tps65023_ldo_set_voltage(struct regulator_dev *dev,
 
        *selector = vsel;
 
-       data = tps_65023_reg_read(tps, TPS65023_REG_LDO_CTRL);
-       if (data < 0)
-               return data;
+       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 tps_65023_reg_write(tps, TPS65023_REG_LDO_CTRL, data);
+       return regmap_write(tps->regmap, TPS65023_REG_LDO_CTRL, data);
 }
 
 static int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
@@ -496,7 +473,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
 
                /* Register the regulators */
                rdev = regulator_register(&tps->desc[i], &client->dev,
-                                         init_data, tps);
+                                         init_data, tps, NULL);
                if (IS_ERR(rdev)) {
                        dev_err(&client->dev, "failed to register %s\n",
                                id->name);
@@ -511,12 +488,12 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
        i2c_set_clientdata(client, tps);
 
        /* Enable setting output voltage by I2C */
-       tps_65023_clear_bits(tps, TPS65023_REG_CON_CTRL2,
-                                               TPS65023_REG_CTRL2_CORE_ADJ);
+       regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
+                       TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
 
        /* Enable setting output voltage by I2C */
-       tps_65023_clear_bits(tps, TPS65023_REG_CON_CTRL2,
-                                               TPS65023_REG_CTRL2_CORE_ADJ);
+       regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
+                       TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
 
        return 0;
 
index bdef70365f52b5c1c01ae30cd66d194d31c820ac..0b63ef71a5fe9810a7b2c3aec40909cd8785035d 100644 (file)
@@ -599,7 +599,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
                tps->desc[i].owner = THIS_MODULE;
 
                rdev = regulator_register(&tps->desc[i],
-                                       tps6507x_dev->dev, init_data, tps);
+                                       tps6507x_dev->dev, init_data, tps, NULL);
                if (IS_ERR(rdev)) {
                        dev_err(tps6507x_dev->dev,
                                "failed to register %s regulator\n",
index 9166aa0a9df71c582425d89a7d6517bd22f01072..70b7b1f4f000e1f779ecdb2c2dbfaf3de4b11274 100644 (file)
@@ -651,7 +651,7 @@ static int __devinit pmic_probe(struct spi_device *spi)
                        hw->desc[i].n_voltages = 1;
 
                hw->rdev[i] = regulator_register(&hw->desc[i], dev,
-                                                init_data, hw);
+                                                init_data, hw, NULL);
                if (IS_ERR(hw->rdev[i])) {
                        ret = PTR_ERR(hw->rdev[i]);
                        hw->rdev[i] = NULL;
index 14b9389dd52abf719552d7e084b5776d791d45c6..c75fb20faa579486b4cfe31cbfd97b2ea43b9320 100644 (file)
@@ -396,7 +396,7 @@ static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
                return err;
 
        rdev = regulator_register(&ri->desc, &pdev->dev,
-                                 pdev->dev.platform_data, ri);
+                                 pdev->dev.platform_data, ri, NULL);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
index b552aae55b417c7cd9aa97fba33bd61ad0b7e787..5c15ba01e9c729bb6139b9d14fb52cb38f5337e8 100644 (file)
 #include <linux/gpio.h>
 #include <linux/mfd/tps65910.h>
 
-#define TPS65910_REG_VRTC              0
-#define TPS65910_REG_VIO               1
-#define TPS65910_REG_VDD1              2
-#define TPS65910_REG_VDD2              3
-#define TPS65910_REG_VDD3              4
-#define TPS65910_REG_VDIG1             5
-#define TPS65910_REG_VDIG2             6
-#define TPS65910_REG_VPLL              7
-#define TPS65910_REG_VDAC              8
-#define TPS65910_REG_VAUX1             9
-#define TPS65910_REG_VAUX2             10
-#define TPS65910_REG_VAUX33            11
-#define TPS65910_REG_VMMC              12
-
-#define TPS65911_REG_VDDCTRL           4
-#define TPS65911_REG_LDO1              5
-#define TPS65911_REG_LDO2              6
-#define TPS65911_REG_LDO3              7
-#define TPS65911_REG_LDO4              8
-#define TPS65911_REG_LDO5              9
-#define TPS65911_REG_LDO6              10
-#define TPS65911_REG_LDO7              11
-#define TPS65911_REG_LDO8              12
-
 #define TPS65910_SUPPLY_STATE_ENABLED  0x1
 
 /* supported VIO voltages in milivolts */
@@ -885,8 +861,6 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
        if (!pmic_plat_data)
                return -EINVAL;
 
-       reg_data = pmic_plat_data->tps65910_pmic_init_data;
-
        pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
        if (!pmic)
                return -ENOMEM;
@@ -937,7 +911,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
                goto err_free_info;
        }
 
-       for (i = 0; i < pmic->num_regulators; i++, info++, reg_data++) {
+       for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS;
+                       i++, info++) {
+
+               reg_data = pmic_plat_data->tps65910_pmic_init_data[i];
+
+               /* Regulator API handles empty constraints but not NULL
+                * constraints */
+               if (!reg_data)
+                       continue;
+
                /* Register the regulators */
                pmic->info[i] = info;
 
@@ -965,7 +948,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
                pmic->desc[i].owner = THIS_MODULE;
 
                rdev = regulator_register(&pmic->desc[i],
-                               tps65910->dev, reg_data, pmic);
+                               tps65910->dev, reg_data, pmic, NULL);
                if (IS_ERR(rdev)) {
                        dev_err(tps65910->dev,
                                "failed to register %s regulator\n",
index 39d4a1749e71a78b3ad73907e407bb8d02435df3..da00d88f94b7921b89384134d96a0d176cbfe999 100644 (file)
@@ -727,7 +727,7 @@ static __devinit int tps65912_probe(struct platform_device *pdev)
                pmic->desc[i].owner = THIS_MODULE;
                range = tps65912_get_range(pmic, i);
                rdev = regulator_register(&pmic->desc[i],
-                                       tps65912->dev, reg_data, pmic);
+                                       tps65912->dev, reg_data, pmic, NULL);
                if (IS_ERR(rdev)) {
                        dev_err(tps65912->dev,
                                "failed to register %s regulator\n",
index 11cc308d66e925db83fa8c50697e734608aac1b8..181a2cfe180cf42a4364a12ba194e099cd00dc9e 100644 (file)
@@ -1112,7 +1112,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
                break;
        }
 
-       rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+       rdev = regulator_register(&info->desc, &pdev->dev, initdata, info, NULL);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "can't register %s, %ld\n",
                                info->desc.name, PTR_ERR(rdev));
index fc66551469996a6fa05775fa1d1d1decbae38f8a..518667ef9a0d7e132b57fa92cb37397b6c799d9c 100644 (file)
@@ -185,18 +185,7 @@ static struct platform_driver regulator_userspace_consumer_driver = {
        },
 };
 
-
-static int __init regulator_userspace_consumer_init(void)
-{
-       return platform_driver_register(&regulator_userspace_consumer_driver);
-}
-module_init(regulator_userspace_consumer_init);
-
-static void __exit regulator_userspace_consumer_exit(void)
-{
-       platform_driver_unregister(&regulator_userspace_consumer_driver);
-}
-module_exit(regulator_userspace_consumer_exit);
+module_platform_driver(regulator_userspace_consumer_driver);
 
 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 MODULE_DESCRIPTION("Userspace consumer for voltage and current regulators");
index 858c1f861ba596d134c253d74ba7d06d330ea0ff..ee0b161c998fd64ad276e228615ab47cefb178e3 100644 (file)
@@ -352,17 +352,7 @@ static struct platform_driver regulator_virtual_consumer_driver = {
        },
 };
 
-static int __init regulator_virtual_consumer_init(void)
-{
-       return platform_driver_register(&regulator_virtual_consumer_driver);
-}
-module_init(regulator_virtual_consumer_init);
-
-static void __exit regulator_virtual_consumer_exit(void)
-{
-       platform_driver_unregister(&regulator_virtual_consumer_driver);
-}
-module_exit(regulator_virtual_consumer_exit);
+module_platform_driver(regulator_virtual_consumer_driver);
 
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Virtual regulator consumer");
index bd3531d8b2ac9364fb48c182c4947a00696d7c34..4904a40b0d46f6b3b870155a535312623e72a831 100644 (file)
@@ -511,7 +511,8 @@ static __devinit int wm831x_buckv_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;
@@ -553,7 +554,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
                wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
 
        dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->dcdc[id], dcdc);
+                                            pdata->dcdc[id], dcdc, NULL);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -590,7 +591,6 @@ err_regulator:
 err:
        if (dcdc->dvs_gpio)
                gpio_free(dcdc->dvs_gpio);
-       kfree(dcdc);
        return ret;
 }
 
@@ -605,7 +605,6 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
        regulator_unregister(dcdc->regulator);
        if (dcdc->dvs_gpio)
                gpio_free(dcdc->dvs_gpio);
-       kfree(dcdc);
 
        return 0;
 }
@@ -722,7 +721,8 @@ static __devinit int wm831x_buckp_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;
@@ -747,7 +747,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
        dcdc->desc.owner = THIS_MODULE;
 
        dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->dcdc[id], dcdc);
+                                            pdata->dcdc[id], dcdc, NULL);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -771,7 +771,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
 err_regulator:
        regulator_unregister(dcdc->regulator);
 err:
-       kfree(dcdc);
        return ret;
 }
 
@@ -783,7 +782,6 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
 
        free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
        regulator_unregister(dcdc->regulator);
-       kfree(dcdc);
 
        return 0;
 }
@@ -874,7 +872,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
        dcdc->desc.owner = THIS_MODULE;
 
        dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->dcdc[id], dcdc);
+                                            pdata->dcdc[id], dcdc, NULL);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@@ -973,7 +971,7 @@ static __devinit int wm831x_epe_probe(struct platform_device *pdev)
        dcdc->desc.owner = THIS_MODULE;
 
        dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
-                                            pdata->epe[id], dcdc);
+                                            pdata->epe[id], dcdc, NULL);
        if (IS_ERR(dcdc->regulator)) {
                ret = PTR_ERR(dcdc->regulator);
                dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
index 01f27c7f4236bca00615e2f4521126f3ce87b702..634aac3f2d5f86c511bc4390777437997b369f87 100644 (file)
@@ -162,7 +162,8 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
        if (pdata == NULL || pdata->isink[id] == NULL)
                return -ENODEV;
 
-       isink = kzalloc(sizeof(struct wm831x_isink), GFP_KERNEL);
+       isink = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_isink),
+                            GFP_KERNEL);
        if (isink == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
                return -ENOMEM;
@@ -189,7 +190,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
        isink->desc.owner = THIS_MODULE;
 
        isink->regulator = regulator_register(&isink->desc, &pdev->dev,
-                                            pdata->isink[id], isink);
+                                            pdata->isink[id], isink, NULL);
        if (IS_ERR(isink->regulator)) {
                ret = PTR_ERR(isink->regulator);
                dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",
@@ -213,7 +214,6 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
 err_regulator:
        regulator_unregister(isink->regulator);
 err:
-       kfree(isink);
        return ret;
 }
 
@@ -226,7 +226,6 @@ static __devexit int wm831x_isink_remove(struct platform_device *pdev)
        free_irq(platform_get_irq(pdev, 0), isink);
 
        regulator_unregister(isink->regulator);
-       kfree(isink);
 
        return 0;
 }
index 6709710a059e6e78c2267c376903b04ea26820fa..f1e4ab0f9fda8e02d6857c705f8fc1032fc7f23b 100644 (file)
@@ -326,7 +326,7 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
        if (pdata == NULL || pdata->ldo[id] == NULL)
                return -ENODEV;
 
-       ldo = kzalloc(sizeof(struct wm831x_ldo), GFP_KERNEL);
+       ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
        if (ldo == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
                return -ENOMEM;
@@ -351,7 +351,7 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
        ldo->desc.owner = THIS_MODULE;
 
        ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-                                            pdata->ldo[id], ldo);
+                                            pdata->ldo[id], ldo, NULL);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -376,7 +376,6 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
 err_regulator:
        regulator_unregister(ldo->regulator);
 err:
-       kfree(ldo);
        return ret;
 }
 
@@ -388,7 +387,6 @@ static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev)
 
        free_irq(platform_get_irq_byname(pdev, "UV"), ldo);
        regulator_unregister(ldo->regulator);
-       kfree(ldo);
 
        return 0;
 }
@@ -596,7 +594,7 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
        if (pdata == NULL || pdata->ldo[id] == NULL)
                return -ENODEV;
 
-       ldo = kzalloc(sizeof(struct wm831x_ldo), GFP_KERNEL);
+       ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
        if (ldo == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
                return -ENOMEM;
@@ -621,7 +619,7 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
        ldo->desc.owner = THIS_MODULE;
 
        ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-                                            pdata->ldo[id], ldo);
+                                            pdata->ldo[id], ldo, NULL);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -645,7 +643,6 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
 err_regulator:
        regulator_unregister(ldo->regulator);
 err:
-       kfree(ldo);
        return ret;
 }
 
@@ -655,7 +652,6 @@ static __devexit int wm831x_aldo_remove(struct platform_device *pdev)
 
        free_irq(platform_get_irq_byname(pdev, "UV"), ldo);
        regulator_unregister(ldo->regulator);
-       kfree(ldo);
 
        return 0;
 }
@@ -793,7 +789,7 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
        if (pdata == NULL || pdata->ldo[id] == NULL)
                return -ENODEV;
 
-       ldo = kzalloc(sizeof(struct wm831x_ldo), GFP_KERNEL);
+       ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_ldo), GFP_KERNEL);
        if (ldo == NULL) {
                dev_err(&pdev->dev, "Unable to allocate private data\n");
                return -ENOMEM;
@@ -818,7 +814,7 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
        ldo->desc.owner = THIS_MODULE;
 
        ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
-                                            pdata->ldo[id], ldo);
+                                            pdata->ldo[id], ldo, NULL);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@@ -831,7 +827,6 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
        return 0;
 
 err:
-       kfree(ldo);
        return ret;
 }
 
@@ -840,7 +835,6 @@ static __devexit int wm831x_alive_ldo_remove(struct platform_device *pdev)
        struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
 
        regulator_unregister(ldo->regulator);
-       kfree(ldo);
 
        return 0;
 }
index 1bcb22c440953b6dcab42609361c150e0857fb23..6894009d815aa8fea3e4b9b220d4e48a9fb74ca0 100644 (file)
@@ -1428,7 +1428,7 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
        /* register regulator */
        rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
                                  pdev->dev.platform_data,
-                                 dev_get_drvdata(&pdev->dev));
+                                 dev_get_drvdata(&pdev->dev), NULL);
        if (IS_ERR(rdev)) {
                dev_err(&pdev->dev, "failed to register %s\n",
                        wm8350_reg[pdev->id].name);
index 71632ddc37813a2cd3ba4b9a107781456335ae81..706f39563a7b76f149173503e17baae77905d198 100644 (file)
@@ -326,7 +326,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
        struct regulator_dev *rdev;
 
        rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-                                 pdev->dev.platform_data, wm8400);
+                                 pdev->dev.platform_data, wm8400, NULL);
 
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
index b87bf5c841f8216a8867db35b23bab5acd0acce2..435e335d6e67ae372054bcb697e773684ab40d3d 100644 (file)
@@ -269,7 +269,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
                ldo->is_enabled = true;
 
        ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
-                                            pdata->ldo[id].init_data, ldo);
+                                            pdata->ldo[id].init_data, ldo, NULL);
        if (IS_ERR(ldo->regulator)) {
                ret = PTR_ERR(ldo->regulator);
                dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
index 3816c2fac0ad66d48b42669063c4efcf2264e700..a98e2a316d1f2e4235cc628e52b44058112ab976 100644 (file)
@@ -69,6 +69,7 @@ struct regulator_init_data;
 struct mc13xxx_regulator_init_data {
        int id;
        struct regulator_init_data *init_data;
+       struct device_node *node;
 };
 
 struct mc13xxx_regulator_platform_data {
index 8bf2cb9502dd7ba492680d371279577392c6d3fe..d0cb12eba402638d33490f71663ef8d0bcf086a1 100644 (file)
 #define TPS65910_GPIO_STS                              BIT(1)
 #define TPS65910_GPIO_SET                              BIT(0)
 
+/* Regulator Index Definitions */
+#define TPS65910_REG_VRTC                              0
+#define TPS65910_REG_VIO                               1
+#define TPS65910_REG_VDD1                              2
+#define TPS65910_REG_VDD2                              3
+#define TPS65910_REG_VDD3                              4
+#define TPS65910_REG_VDIG1                             5
+#define TPS65910_REG_VDIG2                             6
+#define TPS65910_REG_VPLL                              7
+#define TPS65910_REG_VDAC                              8
+#define TPS65910_REG_VAUX1                             9
+#define TPS65910_REG_VAUX2                             10
+#define TPS65910_REG_VAUX33                            11
+#define TPS65910_REG_VMMC                              12
+
+#define TPS65911_REG_VDDCTRL                           4
+#define TPS65911_REG_LDO1                              5
+#define TPS65911_REG_LDO2                              6
+#define TPS65911_REG_LDO3                              7
+#define TPS65911_REG_LDO4                              8
+#define TPS65911_REG_LDO5                              9
+#define TPS65911_REG_LDO6                              10
+#define TPS65911_REG_LDO7                              11
+#define TPS65911_REG_LDO8                              12
+
+/* Max number of TPS65910/11 regulators */
+#define TPS65910_NUM_REGS                              13
+
 /**
  * struct tps65910_board
  * Board platform data may be used to initialize regulators.
@@ -751,7 +779,7 @@ struct tps65910_board {
        int irq_base;
        int vmbch_threshold;
        int vmbch2_threshold;
-       struct regulator_init_data *tps65910_pmic_init_data;
+       struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];
 };
 
 /**
index f7756d146c6164560fd919f16699b0d601a09f26..f2698a0edfc44486a95bd8379b1fa40dd56e1e70 100644 (file)
@@ -149,6 +149,8 @@ int regulator_bulk_enable(int num_consumers,
                          struct regulator_bulk_data *consumers);
 int regulator_bulk_disable(int num_consumers,
                           struct regulator_bulk_data *consumers);
+int regulator_bulk_force_disable(int num_consumers,
+                          struct regulator_bulk_data *consumers);
 void regulator_bulk_free(int num_consumers,
                         struct regulator_bulk_data *consumers);
 
@@ -212,6 +214,11 @@ static inline int regulator_disable(struct regulator *regulator)
        return 0;
 }
 
+static inline int regulator_force_disable(struct regulator *regulator)
+{
+       return 0;
+}
+
 static inline int regulator_disable_deferred(struct regulator *regulator,
                                             int ms)
 {
@@ -242,6 +249,12 @@ static inline int regulator_bulk_disable(int num_consumers,
        return 0;
 }
 
+static inline int regulator_bulk_force_disable(int num_consumers,
+                                       struct regulator_bulk_data *consumers)
+{
+       return 0;
+}
+
 static inline void regulator_bulk_free(int num_consumers,
                                       struct regulator_bulk_data *consumers)
 {
index 52c89ae32f64c8829dd68162d65b3dc2ae135afd..4214b9a9d1c968d05714a37c7d15cbdab905bf44 100644 (file)
@@ -154,6 +154,7 @@ enum regulator_type {
  * this type.
  *
  * @name: Identifying name for the regulator.
+ * @supply_name: Identifying the regulator supply
  * @id: Numerical identifier for the regulator.
  * @n_voltages: Number of selectors available for ops.list_voltage().
  * @ops: Regulator operations table.
@@ -163,6 +164,7 @@ enum regulator_type {
  */
 struct regulator_desc {
        const char *name;
+       const char *supply_name;
        int id;
        unsigned n_voltages;
        struct regulator_ops *ops;
@@ -212,7 +214,7 @@ struct regulator_dev {
 
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
        struct device *dev, const struct regulator_init_data *init_data,
-       void *driver_data);
+       void *driver_data, struct device_node *of_node);
 void regulator_unregister(struct regulator_dev *rdev);
 
 int regulator_notifier_call_chain(struct regulator_dev *rdev,
diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h
new file mode 100644 (file)
index 0000000..769704f
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * OpenFirmware regulator support routines
+ *
+ */
+
+#ifndef __LINUX_OF_REG_H
+#define __LINUX_OF_REG_H
+
+#if defined(CONFIG_OF)
+extern struct regulator_init_data
+       *of_get_regulator_init_data(struct device *dev,
+                                   struct device_node *node);
+#else
+static inline struct regulator_init_data
+       *of_get_regulator_init_data(struct device *dev,
+                                   struct device_node *node)
+{
+       return NULL;
+}
+#endif /* CONFIG_OF */
+
+#endif /* __LINUX_OF_REG_H */
index bbcf921166f7470fad24577d2aa52d1cf85258f4..f6b6551940ab29b80ec2a806f720801e6a72b10c 100644 (file)
@@ -833,7 +833,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec,
        ldo->voltage = voltage;
 
        ldo->dev = regulator_register(&ldo->desc, codec->dev,
-                                         init_data, ldo);
+                                         init_data, ldo, NULL);
        if (IS_ERR(ldo->dev)) {
                int ret = PTR_ERR(ldo->dev);