diff options
Diffstat (limited to 'drivers/regulator')
32 files changed, 2059 insertions, 226 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2805b014ae31..8155e80dd3f8 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -274,6 +274,15 @@ config REGULATOR_ISL6271A help This driver supports ISL6271A voltage regulator chip. +config REGULATOR_LM363X + tristate "TI LM363X voltage regulators" + depends on MFD_TI_LMU + help + This driver supports LM3631 and LM3632 voltage regulators for + the LCD bias. + One boost output voltage is configurable and always on. + Other LDOs are used for the display module. + config REGULATOR_LP3971 tristate "National Semiconductors LP3971 PMIC regulator driver" depends on I2C @@ -446,6 +455,7 @@ config REGULATOR_MC13892 config REGULATOR_MT6311 tristate "MediaTek MT6311 PMIC" depends on I2C + select REGMAP_I2C help Say y here to select this option to enable the power regulator of MediaTek MT6311 PMIC. @@ -504,6 +514,22 @@ config REGULATOR_PFUZE100 Say y here to support the regulators found on the Freescale PFUZE100/PFUZE200 PMIC. +config REGULATOR_PV88060 + tristate "Powerventure Semiconductor PV88060 regulator" + depends on I2C + select REGMAP_I2C + help + Say y here to support the voltage regulators and convertors + PV88060 + +config REGULATOR_PV88090 + tristate "Powerventure Semiconductor PV88090 regulator" + depends on I2C + select REGMAP_I2C + help + Say y here to support the voltage regulators and convertors + on PV88090 + config REGULATOR_PWM tristate "PWM voltage regulator" depends on PWM @@ -680,6 +706,13 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. +config REGULATOR_TPS65086 + tristate "TI TPS65086 Power regulators" + depends on MFD_TPS65086 + help + This driver provides support for the voltage regulators on + TI TPS65086 PMICs. + config REGULATOR_TPS65090 tristate "TI TPS65090 Power regulator" depends on MFD_TPS65090 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 0f8174913c17..980b1943fa81 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o +obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o @@ -66,6 +67,8 @@ obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o +obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o +obj-$(CONFIG_REGULATOR_PV88090) += pv88090-regulator.o obj-$(CONFIG_REGULATOR_PWM) += pwm-regulator.o obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o @@ -85,6 +88,7 @@ obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS65086) += tps65086-regulator.o obj-$(CONFIG_REGULATOR_TPS65090) += tps65090-regulator.o obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o obj-$(CONFIG_REGULATOR_TPS65218) += tps65218-regulator.o diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 35de22fdb7a0..f2e1a39ce0f3 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -27,8 +27,8 @@ #define AXP20X_IO_ENABLED 0x03 #define AXP20X_IO_DISABLED 0x07 -#define AXP22X_IO_ENABLED 0x04 -#define AXP22X_IO_DISABLED 0x03 +#define AXP22X_IO_ENABLED 0x03 +#define AXP22X_IO_DISABLED 0x04 #define AXP20X_WORKMODE_DCDC2_MASK BIT(2) #define AXP20X_WORKMODE_DCDC3_MASK BIT(1) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 73b7683355cd..744c9889f88d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -132,24 +132,24 @@ static bool have_full_constraints(void) return has_full_constraints || of_have_populated_dt(); } +static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) +{ + if (rdev && rdev->supply) + return rdev->supply->rdev; + + return NULL; +} + /** * regulator_lock_supply - lock a regulator and its supplies * @rdev: regulator source */ static void regulator_lock_supply(struct regulator_dev *rdev) { - struct regulator *supply; - int i = 0; - - while (1) { - mutex_lock_nested(&rdev->mutex, i++); - supply = rdev->supply; - - if (!rdev->supply) - return; + int i; - rdev = supply->rdev; - } + for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++) + mutex_lock_nested(&rdev->mutex, i); } /** @@ -2368,7 +2368,6 @@ static void regulator_disable_work(struct work_struct *work) int regulator_disable_deferred(struct regulator *regulator, int ms) { struct regulator_dev *rdev = regulator->rdev; - int ret; if (regulator->always_on) return 0; @@ -2380,13 +2379,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms) rdev->deferred_disables++; mutex_unlock(&rdev->mutex); - ret = queue_delayed_work(system_power_efficient_wq, - &rdev->disable_work, - msecs_to_jiffies(ms)); - if (ret < 0) - return ret; - else - return 0; + queue_delayed_work(system_power_efficient_wq, &rdev->disable_work, + msecs_to_jiffies(ms)); + return 0; } EXPORT_SYMBOL_GPL(regulator_disable_deferred); @@ -3451,8 +3446,10 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { - consumers[i].consumer = regulator_get(dev, - consumers[i].supply); + consumers[i].consumer = _regulator_get(dev, + consumers[i].supply, + false, + !consumers[i].optional); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n", @@ -3708,7 +3705,7 @@ static umode_t regulator_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx) { struct device *dev = kobj_to_dev(kobj); - struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev); + struct regulator_dev *rdev = dev_to_rdev(dev); const struct regulator_ops *ops = rdev->desc->ops; umode_t mode = attr->mode; diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index affa1b191314..33e8f3b8d2bd 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -257,7 +257,7 @@ static const struct regulator_linear_range da9034_ldo12_ranges[] = { REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000), }; -static struct regulator_ops da903x_regulator_ldo_ops = { +static const struct regulator_ops da903x_regulator_ldo_ops = { .set_voltage_sel = da903x_set_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, @@ -268,7 +268,7 @@ static struct regulator_ops da903x_regulator_ldo_ops = { }; /* NOTE: this is dedicated for the insane DA9030 LDO14 */ -static struct regulator_ops da9030_regulator_ldo14_ops = { +static const struct regulator_ops da9030_regulator_ldo14_ops = { .set_voltage_sel = da903x_set_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = da9030_list_ldo14_voltage, @@ -279,7 +279,7 @@ static struct regulator_ops da9030_regulator_ldo14_ops = { }; /* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks */ -static struct regulator_ops da9030_regulator_ldo1_15_ops = { +static const struct regulator_ops da9030_regulator_ldo1_15_ops = { .set_voltage_sel = da9030_set_ldo1_15_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, @@ -289,7 +289,7 @@ static struct regulator_ops da9030_regulator_ldo1_15_ops = { .is_enabled = da903x_is_enabled, }; -static struct regulator_ops da9034_regulator_dvc_ops = { +static const struct regulator_ops da9034_regulator_dvc_ops = { .set_voltage_sel = da9034_set_dvc_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, @@ -300,7 +300,7 @@ static struct regulator_ops da9034_regulator_dvc_ops = { }; /* NOTE: this is dedicated for the insane LDO12 */ -static struct regulator_ops da9034_regulator_ldo12_ops = { +static const struct regulator_ops da9034_regulator_ldo12_ops = { .set_voltage_sel = da903x_set_voltage_sel, .get_voltage_sel = da903x_get_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 12a25b40e473..1050cb77561a 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -265,7 +265,7 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, return ret; } -static struct regulator_ops da9052_dcdc_ops = { +static const struct regulator_ops da9052_dcdc_ops = { .get_current_limit = da9052_dcdc_get_current_limit, .set_current_limit = da9052_dcdc_set_current_limit, @@ -279,7 +279,7 @@ static struct regulator_ops da9052_dcdc_ops = { .disable = regulator_disable_regmap, }; -static struct regulator_ops da9052_ldo_ops = { +static const struct regulator_ops da9052_ldo_ops = { .list_voltage = da9052_list_voltage, .map_voltage = da9052_map_voltage, .get_voltage_sel = regulator_get_voltage_sel_regmap, diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index cafdafbffcaf..d029c941a1e1 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -324,7 +324,7 @@ static int da9055_suspend_disable(struct regulator_dev *rdev) return 0; } -static struct regulator_ops da9055_buck_ops = { +static const struct regulator_ops da9055_buck_ops = { .get_mode = da9055_buck_get_mode, .set_mode = da9055_buck_set_mode, @@ -345,7 +345,7 @@ static struct regulator_ops da9055_buck_ops = { .set_suspend_mode = da9055_buck_set_mode, }; -static struct regulator_ops da9055_ldo_ops = { +static const struct regulator_ops da9055_ldo_ops = { .get_mode = da9055_ldo_get_mode, .set_mode = da9055_ldo_set_mode, diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index 5638fe8d759d..0638c8b40521 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -371,7 +371,7 @@ static int da9062_ldo_set_suspend_mode(struct regulator_dev *rdev, return regmap_field_write(regl->suspend_sleep, val); } -static struct regulator_ops da9062_buck_ops = { +static const struct regulator_ops da9062_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -389,7 +389,7 @@ static struct regulator_ops da9062_buck_ops = { .set_suspend_mode = da9062_buck_set_suspend_mode, }; -static struct regulator_ops da9062_ldo_ops = { +static const struct regulator_ops da9062_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 536e931eb921..ed9e7e96f877 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -427,7 +427,7 @@ static int da9063_ldo_set_suspend_mode(struct regulator_dev *rdev, unsigned mode return regmap_field_write(regl->suspend_sleep, val); } -static struct regulator_ops da9063_buck_ops = { +static const struct regulator_ops da9063_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -445,7 +445,7 @@ static struct regulator_ops da9063_buck_ops = { .set_suspend_mode = da9063_buck_set_suspend_mode, }; -static struct regulator_ops da9063_ldo_ops = { +static const struct regulator_ops da9063_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index b3517830edb6..8b3cc9f0cd64 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -46,7 +46,7 @@ static int da9210_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA); static int da9210_get_current_limit(struct regulator_dev *rdev); -static struct regulator_ops da9210_buck_ops = { +static const struct regulator_ops da9210_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 04ef65b7eb3d..236abf473db5 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -219,7 +219,7 @@ static int da9211_get_current_limit(struct regulator_dev *rdev) return current_limits[data]; } -static struct regulator_ops da9211_buck_ops = { +static const struct regulator_ops da9211_buck_ops = { .get_mode = da9211_buck_get_mode, .set_mode = da9211_buck_set_mode, .enable = regulator_enable_regmap, diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 6ec1d400adae..6ad8ab4c578d 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -164,8 +164,11 @@ int devm_regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { - consumers[i].consumer = devm_regulator_get(dev, - consumers[i].supply); + consumers[i].consumer = _devm_regulator_get(dev, + consumers[i].supply, + consumers[i].optional ? + OPTIONAL_GET : + NORMAL_GET); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n", diff --git a/drivers/regulator/lm363x-regulator.c b/drivers/regulator/lm363x-regulator.c new file mode 100644 index 000000000000..f53e63301a20 --- /dev/null +++ b/drivers/regulator/lm363x-regulator.c @@ -0,0 +1,291 @@ +/* + * TI LM363X Regulator Driver + * + * Copyright 2015 Texas Instruments + * + * Author: Milo Kim <milo.kim@ti.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/err.h> +#include <linux/kernel.h> +#include <linux/mfd/ti-lmu.h> +#include <linux/mfd/ti-lmu-register.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/of_regulator.h> +#include <linux/slab.h> + +/* LM3631 */ +#define LM3631_BOOST_VSEL_MAX 0x25 +#define LM3631_LDO_VSEL_MAX 0x28 +#define LM3631_CONT_VSEL_MAX 0x03 +#define LM3631_VBOOST_MIN 4500000 +#define LM3631_VCONT_MIN 1800000 +#define LM3631_VLDO_MIN 4000000 +#define ENABLE_TIME_USEC 1000 + +/* LM3632 */ +#define LM3632_BOOST_VSEL_MAX 0x26 +#define LM3632_LDO_VSEL_MAX 0x29 +#define LM3632_VBOOST_MIN 4500000 +#define LM3632_VLDO_MIN 4000000 + +/* Common */ +#define LM363X_STEP_50mV 50000 +#define LM363X_STEP_500mV 500000 + +static const int ldo_cont_enable_time[] = { + 0, 2000, 5000, 10000, 20000, 50000, 100000, 200000, +}; + +static int lm363x_regulator_enable_time(struct regulator_dev *rdev) +{ + enum lm363x_regulator_id id = rdev_get_id(rdev); + u8 val, addr, mask; + + switch (id) { + case LM3631_LDO_CONT: + addr = LM3631_REG_ENTIME_VCONT; + mask = LM3631_ENTIME_CONT_MASK; + break; + case LM3631_LDO_OREF: + addr = LM3631_REG_ENTIME_VOREF; + mask = LM3631_ENTIME_MASK; + break; + case LM3631_LDO_POS: + addr = LM3631_REG_ENTIME_VPOS; + mask = LM3631_ENTIME_MASK; + break; + case LM3631_LDO_NEG: + addr = LM3631_REG_ENTIME_VNEG; + mask = LM3631_ENTIME_MASK; + break; + default: + return 0; + } + + if (regmap_read(rdev->regmap, addr, (unsigned int *)&val)) + return -EINVAL; + + val = (val & mask) >> LM3631_ENTIME_SHIFT; + + if (id == LM3631_LDO_CONT) + return ldo_cont_enable_time[val]; + else + return ENABLE_TIME_USEC * val; +} + +static struct regulator_ops lm363x_boost_voltage_table_ops = { + .list_voltage = regulator_list_voltage_linear, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, +}; + +static struct regulator_ops lm363x_regulator_voltage_table_ops = { + .list_voltage = regulator_list_voltage_linear, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .enable_time = lm363x_regulator_enable_time, +}; + +static const struct regulator_desc lm363x_regulator_desc[] = { + /* LM3631 */ + { + .name = "vboost", + .of_match = "vboost", + .id = LM3631_BOOST, + .ops = &lm363x_boost_voltage_table_ops, + .n_voltages = LM3631_BOOST_VSEL_MAX + 1, + .min_uV = LM3631_VBOOST_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_BOOST, + .vsel_mask = LM3631_VOUT_MASK, + }, + { + .name = "ldo_cont", + .of_match = "vcont", + .id = LM3631_LDO_CONT, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_CONT_VSEL_MAX + 1, + .min_uV = LM3631_VCONT_MIN, + .uV_step = LM363X_STEP_500mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_CONT, + .vsel_mask = LM3631_VOUT_CONT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL2, + .enable_mask = LM3631_EN_CONT_MASK, + }, + { + .name = "ldo_oref", + .of_match = "voref", + .id = LM3631_LDO_OREF, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_LDO_VSEL_MAX + 1, + .min_uV = LM3631_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_OREF, + .vsel_mask = LM3631_VOUT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL1, + .enable_mask = LM3631_EN_OREF_MASK, + }, + { + .name = "ldo_vpos", + .of_match = "vpos", + .id = LM3631_LDO_POS, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_LDO_VSEL_MAX + 1, + .min_uV = LM3631_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_POS, + .vsel_mask = LM3631_VOUT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL1, + .enable_mask = LM3631_EN_VPOS_MASK, + }, + { + .name = "ldo_vneg", + .of_match = "vneg", + .id = LM3631_LDO_NEG, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3631_LDO_VSEL_MAX + 1, + .min_uV = LM3631_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3631_REG_VOUT_NEG, + .vsel_mask = LM3631_VOUT_MASK, + .enable_reg = LM3631_REG_LDO_CTRL1, + .enable_mask = LM3631_EN_VNEG_MASK, + }, + /* LM3632 */ + { + .name = "vboost", + .of_match = "vboost", + .id = LM3632_BOOST, + .ops = &lm363x_boost_voltage_table_ops, + .n_voltages = LM3632_BOOST_VSEL_MAX + 1, + .min_uV = LM3632_VBOOST_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3632_REG_VOUT_BOOST, + .vsel_mask = LM3632_VOUT_MASK, + }, + { + .name = "ldo_vpos", + .of_match = "vpos", + .id = LM3632_LDO_POS, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3632_LDO_VSEL_MAX + 1, + .min_uV = LM3632_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3632_REG_VOUT_POS, + .vsel_mask = LM3632_VOUT_MASK, + .enable_reg = LM3632_REG_BIAS_CONFIG, + .enable_mask = LM3632_EN_VPOS_MASK, + }, + { + .name = "ldo_vneg", + .of_match = "vneg", + .id = LM3632_LDO_NEG, + .ops = &lm363x_regulator_voltage_table_ops, + .n_voltages = LM3632_LDO_VSEL_MAX + 1, + .min_uV = LM3632_VLDO_MIN, + .uV_step = LM363X_STEP_50mV, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .vsel_reg = LM3632_REG_VOUT_NEG, + .vsel_mask = LM3632_VOUT_MASK, + .enable_reg = LM3632_REG_BIAS_CONFIG, + .enable_mask = LM3632_EN_VNEG_MASK, + }, +}; + +static int lm363x_regulator_of_get_enable_gpio(struct device_node *np, int id) +{ + /* + * Check LCM_EN1/2_GPIO is configured. + * Those pins are used for enabling VPOS/VNEG LDOs. + */ + switch (id) { + case LM3632_LDO_POS: + return of_get_named_gpio(np, "ti,lcm-en1-gpio", 0); + case LM3632_LDO_NEG: + return of_get_named_gpio(np, "ti,lcm-en2-gpio", 0); + default: + return -EINVAL; + } +} + +static int lm363x_regulator_probe(struct platform_device *pdev) +{ + struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent); + struct regmap *regmap = lmu->regmap; + struct regulator_config cfg = { }; + struct regulator_dev *rdev; + struct device *dev = &pdev->dev; + int id = pdev->id; + int ret, ena_gpio; + + cfg.dev = dev; + cfg.regmap = regmap; + + /* + * LM3632 LDOs can be controlled by external pin. + * Register update is required if the pin is used. + */ + ena_gpio = lm363x_regulator_of_get_enable_gpio(dev->of_node, id); + if (gpio_is_valid(ena_gpio)) { + cfg.ena_gpio = ena_gpio; + cfg.ena_gpio_flags = GPIOF_OUT_INIT_LOW; + + ret = regmap_update_bits(regmap, LM3632_REG_BIAS_CONFIG, + LM3632_EXT_EN_MASK, + LM3632_EXT_EN_MASK); + if (ret) { + dev_err(dev, "External pin err: %d\n", ret); + return ret; + } + } + + rdev = devm_regulator_register(dev, &lm363x_regulator_desc[id], &cfg); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(dev, "[%d] regulator register err: %d\n", id, ret); + return ret; + } + + return 0; +} + +static struct platform_driver lm363x_regulator_driver = { + .probe = lm363x_regulator_probe, + .driver = { + .name = "lm363x-regulator", + }, +}; + +module_platform_driver(lm363x_regulator_driver); + +MODULE_DESCRIPTION("TI LM363X Regulator Driver"); +MODULE_AUTHOR("Milo Kim"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:lm363x-regulator"); diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index e5af07208f9d..19d758486553 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -108,7 +108,6 @@ struct lp872x { struct lp872x_platform_data *pdata; int num_regulators; enum lp872x_dvs_state dvs_pin; - int dvs_gpio; }; /* LP8720/LP8725 shared voltage table for LDOs */ @@ -520,6 +519,7 @@ static struct regulator_ops lp8725_buck_ops = { static struct regulator_desc lp8720_regulator_desc[] = { { .name = "ldo1", + .of_match = of_match_ptr("ldo1"), .id = LP8720_ID_LDO1, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -533,6 +533,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo2", + .of_match = of_match_ptr("ldo2"), .id = LP8720_ID_LDO2, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -546,6 +547,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo3", + .of_match = of_match_ptr("ldo3"), .id = LP8720_ID_LDO3, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -559,6 +561,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo4", + .of_match = of_match_ptr("ldo4"), .id = LP8720_ID_LDO4, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), @@ -572,6 +575,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "ldo5", + .of_match = of_match_ptr("ldo5"), .id = LP8720_ID_LDO5, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -585,6 +589,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, { .name = "buck", + .of_match = of_match_ptr("buck"), .id = LP8720_ID_BUCK, .ops = &lp8720_buck_ops, .n_voltages = ARRAY_SIZE(lp8720_buck_vtbl), @@ -599,6 +604,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { static struct regulator_desc lp8725_regulator_desc[] = { { .name = "ldo1", + .of_match = of_match_ptr("ldo1"), .id = LP8725_ID_LDO1, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -612,6 +618,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo2", + .of_match = of_match_ptr("ldo2"), .id = LP8725_ID_LDO2, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -625,6 +632,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo3", + .of_match = of_match_ptr("ldo3"), .id = LP8725_ID_LDO3, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -638,6 +646,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo4", + .of_match = of_match_ptr("ldo4"), .id = LP8725_ID_LDO4, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -651,6 +660,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "ldo5", + .of_match = of_match_ptr("ldo5"), .id = LP8725_ID_LDO5, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), @@ -664,6 +674,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "lilo1", + .of_match = of_match_ptr("lilo1"), .id = LP8725_ID_LILO1, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), @@ -677,6 +688,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "lilo2", + .of_match = of_match_ptr("lilo2"), .id = LP8725_ID_LILO2, .ops = &lp872x_ldo_ops, .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), @@ -690,6 +702,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, { .name = "buck1", + .of_match = of_match_ptr("buck1"), .id = LP8725_ID_BUCK1, .ops = &lp8725_buck_ops, .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), @@ -701,6 +714,7 @@ static struct regulator_desc lp8725_regulator_desc[] = { }, |