Merge remote-tracking branches 'regulator/topic/discharge', 'regulator/topic/fan53555...
authorMark Brown <broonie@kernel.org>
Sun, 13 Mar 2016 08:19:35 +0000 (15:19 +0700)
committerMark Brown <broonie@kernel.org>
Sun, 13 Mar 2016 08:19:35 +0000 (15:19 +0700)
15 files changed:
Documentation/devicetree/bindings/regulator/hisilicon,hi655x-regulator.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/lp872x.txt
Documentation/devicetree/bindings/regulator/regulator.txt
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/core.c
drivers/regulator/fan53555.c
drivers/regulator/gpio-regulator.c
drivers/regulator/helpers.c
drivers/regulator/hi655x-regulator.c [new file with mode: 0644]
drivers/regulator/lp872x.c
drivers/regulator/of_regulator.c
include/linux/regulator/driver.h
include/linux/regulator/lp872x.h
include/linux/regulator/machine.h

diff --git a/Documentation/devicetree/bindings/regulator/hisilicon,hi655x-regulator.txt b/Documentation/devicetree/bindings/regulator/hisilicon,hi655x-regulator.txt
new file mode 100644 (file)
index 0000000..14cfdc5
--- /dev/null
@@ -0,0 +1,29 @@
+Hisilicon Hi655x Voltage regulators
+
+Note:
+The Hi655x regulator control is managed by Hi655x PMIC.
+So the node of this regulator must be child node of Hi655x
+PMIC node.
+
+The driver uses the regulator core framework, so please also
+take the bindings of regulator.txt for reference.
+
+The valid names for regulators are:
+
+LDO2_2V8 LDO7_SDIO LDO10_2V85 LDO13_1V8 LDO14_2V8
+LDO15_1V8 LDO17_2V5 LDO19_3V0 LDO21_1V8 LDO22_1V2
+
+Example:
+        pmic: pmic@f8000000 {
+                compatible = "hisilicon,hi655x-pmic";
+               ...
+               regulators {
+                       ldo2: LDO2@a21 {
+                               regulator-name = "LDO2_2V8";
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3200000>;
+                               regulator-enable-ramp-delay = <120>;
+                       };
+                       ...
+               }
+       }
index 7818318..ca58a68 100644 (file)
@@ -28,6 +28,7 @@ Optional properties:
   - ti,dvs-gpio: GPIO specifier for external DVS pin control of LP872x devices.
   - ti,dvs-vsel: DVS selector. 0 = SEL_V1, 1 = SEL_V2.
   - ti,dvs-state: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH.
+  - enable-gpios: GPIO specifier for EN pin control of LP872x devices.
 
   Sub nodes for regulator_init_data
     LP8720 has maximum 6 nodes. (child name: ldo1 ~ 5 and buck)
index 1d112fc..ecfc593 100644 (file)
@@ -44,6 +44,11 @@ Optional properties:
   any consumer request.
 - regulator-pull-down: Enable pull down resistor when the regulator is disabled.
 - regulator-over-current-protection: Enable over current protection.
+- regulator-active-discharge: tristate, enable/disable active discharge of
+  regulators. The values are:
+       0: Disable active discharge.
+       1: Enable active discharge.
+       Absence of this property will leave configuration to default.
 
 Deprecated properties:
 - regulator-compatible: If a regulator chip contains multiple
index 74a6354..39b422b 100644 (file)
@@ -270,6 +270,14 @@ config REGULATOR_HI6421
          21 general purpose LDOs, 3 dedicated LDOs, and 5 BUCKs. All
          of them come with support to either ECO (idle) or sleep mode.
 
+config REGULATOR_HI655X
+       tristate "Hisilicon HI655X PMIC regulators support"
+       depends on ARCH_HISI || COMPILE_TEST
+       depends on MFD_HI655X_PMIC && OF
+       help
+         This driver provides support for the voltage regulators of the
+         Hisilicon Hi655x PMIC device.
+
 config REGULATOR_ISL9305
        tristate "Intersil ISL9305 regulator"
        depends on I2C
index 348cfd7..bba7b70 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
 obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
 obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
 obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o
+obj-$(CONFIG_REGULATOR_HI655X) += hi655x-regulator.o
 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
 obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o
 obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o
index 055f8c1..1cff112 100644 (file)
@@ -1139,6 +1139,17 @@ static int set_machine_constraints(struct regulator_dev *rdev,
                }
        }
 
+       if (rdev->constraints->active_discharge && ops->set_active_discharge) {
+               bool ad_state = (rdev->constraints->active_discharge ==
+                             REGULATOR_ACTIVE_DISCHARGE_ENABLE) ? true : false;
+
+               ret = ops->set_active_discharge(rdev, ad_state);
+               if (ret < 0) {
+                       rdev_err(rdev, "failed to set active discharge\n");
+                       return ret;
+               }
+       }
+
        print_constraints(rdev);
        return 0;
 }
index 4940e82..2cb5cc3 100644 (file)
@@ -114,6 +114,22 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
        return 0;
 }
 
+static int fan53555_set_suspend_enable(struct regulator_dev *rdev)
+{
+       struct fan53555_device_info *di = rdev_get_drvdata(rdev);
+
+       return regmap_update_bits(di->regmap, di->sleep_reg,
+                                 VSEL_BUCK_EN, VSEL_BUCK_EN);
+}
+
+static int fan53555_set_suspend_disable(struct regulator_dev *rdev)
+{
+       struct fan53555_device_info *di = rdev_get_drvdata(rdev);
+
+       return regmap_update_bits(di->regmap, di->sleep_reg,
+                                 VSEL_BUCK_EN, 0);
+}
+
 static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
 {
        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
@@ -192,6 +208,8 @@ static struct regulator_ops fan53555_regulator_ops = {
        .set_mode = fan53555_set_mode,
        .get_mode = fan53555_get_mode,
        .set_ramp_delay = fan53555_set_ramp,
+       .set_suspend_enable = fan53555_set_suspend_enable,
+       .set_suspend_disable = fan53555_set_suspend_disable,
 };
 
 static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
index 7bba8b7..a8718e9 100644 (file)
@@ -283,8 +283,10 @@ static int gpio_regulator_probe(struct platform_device *pdev)
                drvdata->nr_gpios = config->nr_gpios;
                ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
                if (ret) {
-                       dev_err(&pdev->dev,
-                       "Could not obtain regulator setting GPIOs: %d\n", ret);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(&pdev->dev,
+                                       "Could not obtain regulator setting GPIOs: %d\n",
+                                       ret);
                        goto err_memstate;
                }
        }
index 3bbb326..b1e32e7 100644 (file)
@@ -465,3 +465,26 @@ int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
        return 0;
 }
 EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
+
+/**
+ * regulator_set_active_discharge_regmap - Default set_active_discharge()
+ *                                        using regmap
+ *
+ * @rdev: device to operate on.
+ * @enable: state to set, 0 to disable and 1 to enable.
+ */
+int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
+                                         bool enable)
+{
+       unsigned int val;
+
+       if (enable)
+               val = rdev->desc->active_discharge_on;
+       else
+               val = rdev->desc->active_discharge_off;
+
+       return regmap_update_bits(rdev->regmap,
+                                 rdev->desc->active_discharge_reg,
+                                 rdev->desc->active_discharge_mask, val);
+}
+EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c
new file mode 100644 (file)
index 0000000..aca1846
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Device driver for regulators in Hi655x IC
+ *
+ * Copyright (c) 2016 Hisilicon.
+ *
+ * Authors:
+ * Chen Feng <puck.chen@hisilicon.com>
+ * Fei  Wang <w.f@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/mfd/hi655x-pmic.h>
+
+struct hi655x_regulator {
+       unsigned int disable_reg;
+       unsigned int status_reg;
+       unsigned int ctrl_regs;
+       unsigned int ctrl_mask;
+       struct regulator_desc rdesc;
+};
+
+/* LDO7 & LDO10 */
+static const unsigned int ldo7_voltages[] = {
+       1800000, 1850000, 2850000, 2900000,
+       3000000, 3100000, 3200000, 3300000,
+};
+
+static const unsigned int ldo19_voltages[] = {
+       1800000, 1850000, 1900000, 1750000,
+       2800000, 2850000, 2900000, 3000000,
+};
+
+static const unsigned int ldo22_voltages[] = {
+        900000, 1000000, 1050000, 1100000,
+       1150000, 1175000, 1185000, 1200000,
+};
+
+enum hi655x_regulator_id {
+       HI655X_LDO0,
+       HI655X_LDO1,
+       HI655X_LDO2,
+       HI655X_LDO3,
+       HI655X_LDO4,
+       HI655X_LDO5,
+       HI655X_LDO6,
+       HI655X_LDO7,
+       HI655X_LDO8,
+       HI655X_LDO9,
+       HI655X_LDO10,
+       HI655X_LDO11,
+       HI655X_LDO12,
+       HI655X_LDO13,
+       HI655X_LDO14,
+       HI655X_LDO15,
+       HI655X_LDO16,
+       HI655X_LDO17,
+       HI655X_LDO18,
+       HI655X_LDO19,
+       HI655X_LDO20,
+       HI655X_LDO21,
+       HI655X_LDO22,
+};
+
+static int hi655x_is_enabled(struct regulator_dev *rdev)
+{
+       unsigned int value = 0;
+
+       struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
+
+       regmap_read(rdev->regmap, regulator->status_reg, &value);
+       return (value & BIT(regulator->ctrl_mask));
+}
+
+static int hi655x_disable(struct regulator_dev *rdev)
+{
+       int ret = 0;
+
+       struct hi655x_regulator *regulator = rdev_get_drvdata(rdev);
+
+       ret = regmap_write(rdev->regmap, regulator->disable_reg,
+                          BIT(regulator->ctrl_mask));
+       return ret;
+}
+
+static struct regulator_ops hi655x_regulator_ops = {
+       .enable = regulator_enable_regmap,
+       .disable = hi655x_disable,
+       .is_enabled = hi655x_is_enabled,
+       .list_voltage = regulator_list_voltage_table,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+};
+
+static struct regulator_ops hi655x_ldo_linear_ops = {
+       .enable = regulator_enable_regmap,
+       .disable = hi655x_disable,
+       .is_enabled = hi655x_is_enabled,
+       .list_voltage = regulator_list_voltage_linear,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+};
+
+#define HI655X_LDO(_ID, vreg, vmask, ereg, dreg,                 \
+                  sreg, cmask, vtable) {                        \
+       .rdesc = {                                               \
+               .name            = #_ID,                         \
+               .of_match        = of_match_ptr(#_ID),           \
+               .ops             = &hi655x_regulator_ops,        \
+               .regulators_node = of_match_ptr("regulators"),   \
+               .type            = REGULATOR_VOLTAGE,            \
+               .id              = HI655X_##_ID,                 \
+               .owner           = THIS_MODULE,                  \
+               .n_voltages      = ARRAY_SIZE(vtable),           \
+               .volt_table      = vtable,                       \
+               .vsel_reg        = HI655X_BUS_ADDR(vreg),        \
+               .vsel_mask       = vmask,                        \
+               .enable_reg      = HI655X_BUS_ADDR(ereg),        \
+               .enable_mask     = BIT(cmask),                   \
+       },                                                       \
+       .disable_reg = HI655X_BUS_ADDR(dreg),                    \
+       .status_reg = HI655X_BUS_ADDR(sreg),                     \
+       .ctrl_mask = cmask,                                      \
+}
+
+#define HI655X_LDO_LINEAR(_ID, vreg, vmask, ereg, dreg,          \
+                         sreg, cmask, minv, nvolt, vstep) {     \
+       .rdesc = {                                               \
+               .name            = #_ID,                         \
+               .of_match        = of_match_ptr(#_ID),           \
+               .ops             = &hi655x_ldo_linear_ops,       \
+               .regulators_node = of_match_ptr("regulators"),   \
+               .type            = REGULATOR_VOLTAGE,            \
+               .id              = HI655X_##_ID,                 \
+               .owner           = THIS_MODULE,                  \
+               .min_uV          = minv,                         \
+               .n_voltages      = nvolt,                        \
+               .uV_step         = vstep,                        \
+               .vsel_reg        = HI655X_BUS_ADDR(vreg),        \
+               .vsel_mask       = vmask,                        \
+               .enable_reg      = HI655X_BUS_ADDR(ereg),        \
+               .enable_mask     = BIT(cmask),                   \
+       },                                                       \
+       .disable_reg = HI655X_BUS_ADDR(dreg),                    \
+       .status_reg = HI655X_BUS_ADDR(sreg),                     \
+       .ctrl_mask = cmask,                                      \
+}
+
+static struct hi655x_regulator regulators[] = {
+       HI655X_LDO_LINEAR(LDO2, 0x72, 0x07, 0x29, 0x2a, 0x2b, 0x01,
+                         2500000, 8, 100000),
+       HI655X_LDO(LDO7, 0x78, 0x07, 0x29, 0x2a, 0x2b, 0x06, ldo7_voltages),
+       HI655X_LDO(LDO10, 0x78, 0x07, 0x29, 0x2a, 0x2b, 0x01, ldo7_voltages),
+       HI655X_LDO_LINEAR(LDO13, 0x7e, 0x07, 0x2c, 0x2d, 0x2e, 0x04,
+                         1600000, 8, 50000),
+       HI655X_LDO_LINEAR(LDO14, 0x7f, 0x07, 0x2c, 0x2d, 0x2e, 0x05,
+                         2500000, 8, 100000),
+       HI655X_LDO_LINEAR(LDO15, 0x80, 0x07, 0x2c, 0x2d, 0x2e, 0x06,
+                         1600000, 8, 50000),
+       HI655X_LDO_LINEAR(LDO17, 0x82, 0x07, 0x2f, 0x30, 0x31, 0x00,
+                         2500000, 8, 100000),
+       HI655X_LDO(LDO19, 0x84, 0x07, 0x2f, 0x30, 0x31, 0x02, ldo19_voltages),
+       HI655X_LDO_LINEAR(LDO21, 0x86, 0x07, 0x2f, 0x30, 0x31, 0x04,
+                         1650000, 8, 50000),
+       HI655X_LDO(LDO22, 0x87, 0x07, 0x2f, 0x30, 0x31, 0x05, ldo22_voltages),
+};
+
+static int hi655x_regulator_probe(struct platform_device *pdev)
+{
+       unsigned int i;
+       struct hi655x_regulator *regulator;
+       struct hi655x_pmic *pmic;
+       struct regulator_config config = { };
+       struct regulator_dev *rdev;
+
+       pmic = dev_get_drvdata(pdev->dev.parent);
+       if (!pmic) {
+               dev_err(&pdev->dev, "no pmic in the regulator parent node\n");
+               return -ENODEV;
+       }
+
+       regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL);
+       if (!regulator)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, regulator);
+
+       config.dev = pdev->dev.parent;
+       config.regmap = pmic->regmap;
+       config.driver_data = regulator;
+       for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+               rdev = devm_regulator_register(&pdev->dev,
+                                              &regulators[i].rdesc,
+                                              &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(&pdev->dev, "failed to register regulator %s\n",
+                               regulator->rdesc.name);
+                       return PTR_ERR(rdev);
+               }
+       }
+       return 0;
+}
+
+static struct platform_driver hi655x_regulator_driver = {
+       .driver = {
+               .name   = "hi655x-regulator",
+       },
+       .probe  = hi655x_regulator_probe,
+};
+module_platform_driver(hi655x_regulator_driver);
+
+MODULE_AUTHOR("Chen Feng <puck.chen@hisilicon.com>");
+MODULE_DESCRIPTION("Hisilicon Hi655x regulator driver");
+MODULE_LICENSE("GPL v2");
index 19d7584..3899211 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/regmap.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/delay.h>
 #include <linux/regulator/lp872x.h>
 #include <linux/regulator/driver.h>
 #include <linux/platform_device.h>
@@ -738,10 +739,8 @@ static int lp872x_init_dvs(struct lp872x *lp)
                goto set_default_dvs_mode;
 
        gpio = dvs->gpio;
-       if (!gpio_is_valid(gpio)) {
-               dev_warn(lp->dev, "invalid gpio: %d\n", gpio);
+       if (!gpio_is_valid(gpio))
                goto set_default_dvs_mode;
-       }
 
        pinstate = dvs->init_state;
        ret = devm_gpio_request_one(lp->dev, gpio, pinstate, "LP872X DVS");
@@ -759,6 +758,33 @@ set_default_dvs_mode:
                                default_dvs_mode[lp->chipid]);
 }
 
+static int lp872x_hw_enable(struct lp872x *lp)
+{
+       int ret, gpio;
+
+       if (!lp->pdata)
+               return -EINVAL;
+
+       gpio = lp->pdata->enable_gpio;
+       if (!gpio_is_valid(gpio))
+               return 0;
+
+       /* Always set enable GPIO high. */
+       ret = devm_gpio_request_one(lp->dev, gpio, GPIOF_OUT_INIT_HIGH, "LP872X EN");
+       if (ret) {
+               dev_err(lp->dev, "gpio request err: %d\n", ret);
+               return ret;
+       }
+
+       /* Each chip has a different enable delay. */
+       if (lp->chipid == LP8720)
+               usleep_range(LP8720_ENABLE_DELAY, 1.5 * LP8720_ENABLE_DELAY);
+       else
+               usleep_range(LP8725_ENABLE_DELAY, 1.5 * LP8725_ENABLE_DELAY);
+
+       return 0;
+}
+
 static int lp872x_config(struct lp872x *lp)
 {
        struct lp872x_platform_data *pdata = lp->pdata;
@@ -877,6 +903,8 @@ static struct lp872x_platform_data
        of_property_read_u8(np, "ti,dvs-state", &dvs_state);
        pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW;
 
+       pdata->enable_gpio = of_get_named_gpio(np, "enable-gpios", 0);
+
        if (of_get_child_count(np) == 0)
                goto out;
 
@@ -950,6 +978,10 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
        lp->chipid = id->driver_data;
        i2c_set_clientdata(cl, lp);
 
+       ret = lp872x_hw_enable(lp);
+       if (ret)
+               return ret;
+
        ret = lp872x_config(lp);
        if (ret)
                return ret;
index 499e437..fe2e334 100644 (file)
@@ -93,6 +93,12 @@ static void of_get_regulation_constraints(struct device_node *np,
 
        constraints->soft_start = of_property_read_bool(np,
                                        "regulator-soft-start");
+       ret = of_property_read_u32(np, "regulator-active-discharge", &pval);
+       if (!ret) {
+               constraints->active_discharge =
+                               (pval) ? REGULATOR_ACTIVE_DISCHARGE_ENABLE :
+                                       REGULATOR_ACTIVE_DISCHARGE_DISABLE;
+       }
 
        if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) {
                if (desc && desc->of_map_mode) {
index 16ac9e1..cd271e8 100644 (file)
@@ -93,6 +93,8 @@ struct regulator_linear_range {
  * @get_current_limit: Get the configured limit for a current-limited regulator.
  * @set_input_current_limit: Configure an input limit.
  *
+ * @set_active_discharge: Set active discharge enable/disable of regulators.
+ *
  * @set_mode: Set the configured operating mode for the regulator.
  * @get_mode: Get the configured operating mode for the regulator.
  * @get_status: Return actual (not as-configured) status of regulator, as a
@@ -149,6 +151,7 @@ struct regulator_ops {
 
        int (*set_input_current_limit) (struct regulator_dev *, int lim_uA);
        int (*set_over_current_protection) (struct regulator_dev *);
+       int (*set_active_discharge) (struct regulator_dev *, bool enable);
 
        /* enable/disable regulator */
        int (*enable) (struct regulator_dev *);
@@ -266,6 +269,14 @@ enum regulator_type {
  * @bypass_mask: Mask for control when using regmap set_bypass
  * @bypass_val_on: Enabling value for control when using regmap set_bypass
  * @bypass_val_off: Disabling value for control when using regmap set_bypass
+ * @active_discharge_off: Enabling value for control when using regmap
+ *                       set_active_discharge
+ * @active_discharge_on: Disabling value for control when using regmap
+ *                      set_active_discharge
+ * @active_discharge_mask: Mask for control when using regmap
+ *                        set_active_discharge
+ * @active_discharge_reg: Register for control when using regmap
+ *                       set_active_discharge
  *
  * @enable_time: Time taken for initial enable of regulator (in uS).
  * @off_on_delay: guard time (in uS), before re-enabling a regulator
@@ -315,6 +326,10 @@ struct regulator_desc {
        unsigned int bypass_mask;
        unsigned int bypass_val_on;
        unsigned int bypass_val_off;
+       unsigned int active_discharge_on;
+       unsigned int active_discharge_off;
+       unsigned int active_discharge_mask;
+       unsigned int active_discharge_reg;
 
        unsigned int enable_time;
 
@@ -447,6 +462,8 @@ int regulator_set_voltage_time_sel(struct regulator_dev *rdev,
 int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable);
 int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable);
 
+int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
+                                         bool enable);
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
 
 #endif
index 132e05c..6029279 100644 (file)
@@ -18,6 +18,9 @@
 
 #define LP872X_MAX_REGULATORS          9
 
+#define LP8720_ENABLE_DELAY            200
+#define LP8725_ENABLE_DELAY            30000
+
 enum lp872x_regulator_id {
        LP8720_ID_BASE,
        LP8720_ID_LDO1 = LP8720_ID_BASE,
@@ -79,12 +82,14 @@ struct lp872x_regulator_data {
  * @update_config     : if LP872X_GENERAL_CFG register is updated, set true
  * @regulator_data    : platform regulator id and init data
  * @dvs               : dvs data for buck voltage control
+ * @enable_gpio       : gpio pin number for enable control
  */
 struct lp872x_platform_data {
        u8 general_config;
        bool update_config;
        struct lp872x_regulator_data regulator_data[LP872X_MAX_REGULATORS];
        struct lp872x_dvs *dvs;
+       int enable_gpio;
 };
 
 #endif
index a1067d0..5d627c8 100644 (file)
@@ -42,6 +42,13 @@ struct regulator;
 #define REGULATOR_CHANGE_DRMS          0x10
 #define REGULATOR_CHANGE_BYPASS                0x20
 
+/* Regulator active discharge flags */
+enum regulator_active_discharge {
+       REGULATOR_ACTIVE_DISCHARGE_DEFAULT,
+       REGULATOR_ACTIVE_DISCHARGE_DISABLE,
+       REGULATOR_ACTIVE_DISCHARGE_ENABLE,
+};
+
 /**
  * struct regulator_state - regulator state during low power system states
  *
@@ -100,6 +107,9 @@ struct regulator_state {
  * @initial_state: Suspend state to set by default.
  * @initial_mode: Mode to set at startup.
  * @ramp_delay: Time to settle down after voltage change (unit: uV/us)
+ * @active_discharge: Enable/disable active discharge. The enum
+ *                   regulator_active_discharge values are used for
+ *                   initialisation.
  * @enable_time: Turn-on time of the rails (unit: microseconds)
  */
 struct regulation_constraints {
@@ -140,6 +150,8 @@ struct regulation_constraints {
        unsigned int ramp_delay;
        unsigned int enable_time;
 
+       unsigned int active_discharge;
+
        /* constraint flags */
        unsigned always_on:1;   /* regulator never off when system is on */
        unsigned boot_on:1;     /* bootloader/firmware enabled regulator */