diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:11:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:11:40 +0000 |
commit | 8b0a8165cdad0f4133837d753649ef4682e42c3b (patch) | |
tree | 5c58f869f31ddb1f7bd6e8bdea269b680b36c5b6 /drivers/regulator | |
parent | Releasing progress-linux version 6.8.12-1~progress7.99u1. (diff) | |
download | linux-8b0a8165cdad0f4133837d753649ef4682e42c3b.tar.xz linux-8b0a8165cdad0f4133837d753649ef4682e42c3b.zip |
Merging upstream version 6.9.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/Kconfig | 2 | ||||
-rw-r--r-- | drivers/regulator/bd71815-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/bd71828-regulator.c | 58 | ||||
-rw-r--r-- | drivers/regulator/core.c | 15 | ||||
-rw-r--r-- | drivers/regulator/da9055-regulator.c | 48 | ||||
-rw-r--r-- | drivers/regulator/da9121-regulator.c | 1 | ||||
-rw-r--r-- | drivers/regulator/fixed-helper.c | 4 | ||||
-rw-r--r-- | drivers/regulator/helpers.c | 43 | ||||
-rw-r--r-- | drivers/regulator/internal.h | 2 | ||||
-rw-r--r-- | drivers/regulator/lp873x-regulator.c | 3 | ||||
-rw-r--r-- | drivers/regulator/lp87565-regulator.c | 3 | ||||
-rw-r--r-- | drivers/regulator/lp8788-buck.c | 64 | ||||
-rw-r--r-- | drivers/regulator/max8973-regulator.c | 36 | ||||
-rw-r--r-- | drivers/regulator/max8997-regulator.c | 85 | ||||
-rw-r--r-- | drivers/regulator/max8998.c | 150 | ||||
-rw-r--r-- | drivers/regulator/mp8859.c | 252 | ||||
-rw-r--r-- | drivers/regulator/pwm-regulator.c | 40 | ||||
-rw-r--r-- | drivers/regulator/qcom_smd-regulator.c | 19 | ||||
-rw-r--r-- | drivers/regulator/rtq2208-regulator.c | 7 | ||||
-rw-r--r-- | drivers/regulator/tps6287x-regulator.c | 1 | ||||
-rw-r--r-- | drivers/regulator/tps6594-regulator.c | 16 |
21 files changed, 485 insertions, 366 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 550145f827..7db0a29b5b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -288,7 +288,7 @@ config REGULATOR_CROS_EC config REGULATOR_DA903X tristate "Dialog Semiconductor DA9030/DA9034 regulators" depends on PMIC_DA903X - depends on !CC_IS_CLANG # https://bugs.llvm.org/show_bug.cgi?id=38789 + depends on !CC_IS_CLANG # https://llvm.org/pr38789 help Say y here to support the BUCKs and LDOs regulators found on Dialog Semiconductor DA9030/DA9034 PMIC. diff --git a/drivers/regulator/bd71815-regulator.c b/drivers/regulator/bd71815-regulator.c index 26192d55a6..79fbb45297 100644 --- a/drivers/regulator/bd71815-regulator.c +++ b/drivers/regulator/bd71815-regulator.c @@ -256,7 +256,7 @@ static int buck12_set_hw_dvs_levels(struct device_node *np, * 10: 2.50mV/usec 10mV 4uS * 11: 1.25mV/usec 10mV 8uS */ -static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 }; +static const unsigned int bd7181x_ramp_table[] = { 10000, 5000, 2500, 1250 }; static int bd7181x_led_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c index 08d4ee3692..dd871ffe97 100644 --- a/drivers/regulator/bd71828-regulator.c +++ b/drivers/regulator/bd71828-regulator.c @@ -206,14 +206,11 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { .suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT, .suspend_mask = BD71828_MASK_BUCK1267_VOLT, .suspend_on_mask = BD71828_MASK_SUSP_EN, - .lpsr_on_mask = BD71828_MASK_LPSR_EN, /* * LPSR voltage is same as SUSPEND voltage. Allow - * setting it so that regulator can be set enabled at - * LPSR state + * only enabling/disabling regulator for LPSR state */ - .lpsr_reg = BD71828_REG_BUCK1_SUSP_VOLT, - .lpsr_mask = BD71828_MASK_BUCK1267_VOLT, + .lpsr_on_mask = BD71828_MASK_LPSR_EN, }, .reg_inits = buck1_inits, .reg_init_amnt = ARRAY_SIZE(buck1_inits), @@ -288,13 +285,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_BUCK3_VOLT, - .idle_reg = BD71828_REG_BUCK3_VOLT, - .suspend_reg = BD71828_REG_BUCK3_VOLT, - .lpsr_reg = BD71828_REG_BUCK3_VOLT, .run_mask = BD71828_MASK_BUCK3_VOLT, - .idle_mask = BD71828_MASK_BUCK3_VOLT, - .suspend_mask = BD71828_MASK_BUCK3_VOLT, - .lpsr_mask = BD71828_MASK_BUCK3_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -329,13 +320,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_BUCK4_VOLT, - .idle_reg = BD71828_REG_BUCK4_VOLT, - .suspend_reg = BD71828_REG_BUCK4_VOLT, - .lpsr_reg = BD71828_REG_BUCK4_VOLT, .run_mask = BD71828_MASK_BUCK4_VOLT, - .idle_mask = BD71828_MASK_BUCK4_VOLT, - .suspend_mask = BD71828_MASK_BUCK4_VOLT, - .lpsr_mask = BD71828_MASK_BUCK4_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -370,13 +355,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_BUCK5_VOLT, - .idle_reg = BD71828_REG_BUCK5_VOLT, - .suspend_reg = BD71828_REG_BUCK5_VOLT, - .lpsr_reg = BD71828_REG_BUCK5_VOLT, .run_mask = BD71828_MASK_BUCK5_VOLT, - .idle_mask = BD71828_MASK_BUCK5_VOLT, - .suspend_mask = BD71828_MASK_BUCK5_VOLT, - .lpsr_mask = BD71828_MASK_BUCK5_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -493,13 +472,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_LDO1_VOLT, - .idle_reg = BD71828_REG_LDO1_VOLT, - .suspend_reg = BD71828_REG_LDO1_VOLT, - .lpsr_reg = BD71828_REG_LDO1_VOLT, .run_mask = BD71828_MASK_LDO_VOLT, - .idle_mask = BD71828_MASK_LDO_VOLT, - .suspend_mask = BD71828_MASK_LDO_VOLT, - .lpsr_mask = BD71828_MASK_LDO_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -533,13 +506,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_LDO2_VOLT, - .idle_reg = BD71828_REG_LDO2_VOLT, - .suspend_reg = BD71828_REG_LDO2_VOLT, - .lpsr_reg = BD71828_REG_LDO2_VOLT, .run_mask = BD71828_MASK_LDO_VOLT, - .idle_mask = BD71828_MASK_LDO_VOLT, - .suspend_mask = BD71828_MASK_LDO_VOLT, - .lpsr_mask = BD71828_MASK_LDO_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -573,13 +540,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_LDO3_VOLT, - .idle_reg = BD71828_REG_LDO3_VOLT, - .suspend_reg = BD71828_REG_LDO3_VOLT, - .lpsr_reg = BD71828_REG_LDO3_VOLT, .run_mask = BD71828_MASK_LDO_VOLT, - .idle_mask = BD71828_MASK_LDO_VOLT, - .suspend_mask = BD71828_MASK_LDO_VOLT, - .lpsr_mask = BD71828_MASK_LDO_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -614,13 +575,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_LDO4_VOLT, - .idle_reg = BD71828_REG_LDO4_VOLT, - .suspend_reg = BD71828_REG_LDO4_VOLT, - .lpsr_reg = BD71828_REG_LDO4_VOLT, .run_mask = BD71828_MASK_LDO_VOLT, - .idle_mask = BD71828_MASK_LDO_VOLT, - .suspend_mask = BD71828_MASK_LDO_VOLT, - .lpsr_mask = BD71828_MASK_LDO_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -655,13 +610,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR, .run_reg = BD71828_REG_LDO5_VOLT, - .idle_reg = BD71828_REG_LDO5_VOLT, - .suspend_reg = BD71828_REG_LDO5_VOLT, - .lpsr_reg = BD71828_REG_LDO5_VOLT, .run_mask = BD71828_MASK_LDO_VOLT, - .idle_mask = BD71828_MASK_LDO_VOLT, - .suspend_mask = BD71828_MASK_LDO_VOLT, - .lpsr_mask = BD71828_MASK_LDO_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, @@ -720,9 +669,6 @@ static const struct bd71828_regulator_data bd71828_rdata[] = { .suspend_reg = BD71828_REG_LDO7_VOLT, .lpsr_reg = BD71828_REG_LDO7_VOLT, .run_mask = BD71828_MASK_LDO_VOLT, - .idle_mask = BD71828_MASK_LDO_VOLT, - .suspend_mask = BD71828_MASK_LDO_VOLT, - .lpsr_mask = BD71828_MASK_LDO_VOLT, .idle_on_mask = BD71828_MASK_IDLE_EN, .suspend_on_mask = BD71828_MASK_SUSP_EN, .lpsr_on_mask = BD71828_MASK_LPSR_EN, diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1b897d0009..51ff3f9eaf 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2279,6 +2279,17 @@ struct regulator *_regulator_get(struct device *dev, const char *id, if (ret > 0) { rdev->use_count = 1; regulator->enable_count = 1; + + /* Propagate the regulator state to its supply */ + if (rdev->supply) { + ret = regulator_enable(rdev->supply); + if (ret < 0) { + destroy_regulator(regulator); + module_put(rdev->owner); + put_device(&rdev->dev); + return ERR_PTR(ret); + } + } } else { rdev->use_count = 0; regulator->enable_count = 0; @@ -3336,6 +3347,7 @@ struct regmap *regulator_get_regmap(struct regulator *regulator) return map ? map : ERR_PTR(-EOPNOTSUPP); } +EXPORT_SYMBOL_GPL(regulator_get_regmap); /** * regulator_get_hardware_vsel_register - get the HW voltage selector register @@ -3937,7 +3949,6 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev, if (ret < 0) return ret; - possible_uV = desired_min_uV; done = true; goto finish; @@ -5896,7 +5907,7 @@ static const struct dev_pm_ops __maybe_unused regulator_pm_ops = { }; #endif -struct class regulator_class = { +const struct class regulator_class = { .name = "regulator", .dev_release = regulator_dev_release, .dev_groups = regulator_dev_groups, diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 8fd9ac7875..352547c375 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -9,7 +9,6 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/gpio.h> #include <linux/gpio/consumer.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> @@ -413,31 +412,35 @@ static struct da9055_regulator_info da9055_regulator_info[] = { * GPIO can control regulator state and/or select the regulator register * set A/B for voltage ramping. */ -static int da9055_gpio_init(struct da9055_regulator *regulator, +static int da9055_gpio_init(struct device *dev, + struct da9055_regulator *regulator, struct regulator_config *config, struct da9055_pdata *pdata, int id) { struct da9055_regulator_info *info = regulator->info; + struct gpio_desc *ren; + struct gpio_desc *ena; + struct gpio_desc *rsel; int ret = 0; - if (!pdata) - return 0; + /* Look for "regulator-enable-gpios" GPIOs in the regulator node */ + ren = devm_gpiod_get_optional(dev, "regulator-enable", GPIOD_IN); + if (IS_ERR(ren)) + return PTR_ERR(ren); - if (pdata->gpio_ren && pdata->gpio_ren[id]) { - char name[18]; - int gpio_mux = pdata->gpio_ren[id]; + if (ren) { + /* This GPIO is not optional at this point */ + ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(ena)) + return PTR_ERR(ena); - config->ena_gpiod = pdata->ena_gpiods[id]; + config->ena_gpiod = ena; /* * GPI pin is muxed with regulator to control the * regulator state. */ - sprintf(name, "DA9055 GPI %d", gpio_mux); - ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, - name); - if (ret < 0) - goto err; + gpiod_set_consumer_name(ren, "DA9055 ren GPI"); /* * Let the regulator know that its state is controlled @@ -448,24 +451,22 @@ static int da9055_gpio_init(struct da9055_regulator *regulator, pdata->reg_ren[id] << DA9055_E_GPI_SHIFT); if (ret < 0) - goto err; + return ret; } - if (pdata->gpio_rsel && pdata->gpio_rsel[id]) { - char name[18]; - int gpio_mux = pdata->gpio_rsel[id]; + /* Look for "regulator-select-gpios" GPIOs in the regulator node */ + rsel = devm_gpiod_get_optional(dev, "regulator-select", GPIOD_IN); + if (IS_ERR(rsel)) + return PTR_ERR(rsel); + if (rsel) { regulator->reg_rselect = pdata->reg_rsel[id]; /* * GPI pin is muxed with regulator to select the * regulator register set A/B for voltage ramping. */ - sprintf(name, "DA9055 GPI %d", gpio_mux); - ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN, - name); - if (ret < 0) - goto err; + gpiod_set_consumer_name(rsel, "DA9055 rsel GPI"); /* * Let the regulator know that its register set A/B @@ -477,7 +478,6 @@ static int da9055_gpio_init(struct da9055_regulator *regulator, << DA9055_V_GPI_SHIFT); } -err: return ret; } @@ -532,7 +532,7 @@ static int da9055_regulator_probe(struct platform_device *pdev) if (pdata) config.init_data = pdata->regulators[pdev->id]; - ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); + ret = da9055_gpio_init(&pdev->dev, regulator, &config, pdata, pdev->id); if (ret < 0) return ret; diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index b551a400bd..5ee76b5335 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -14,7 +14,6 @@ // Copyright (C) 2020 Dialog Semiconductor #include <linux/of.h> -#include <linux/of_gpio.h> #include <linux/gpio/consumer.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index 0eb2442456..2d5a42b2b3 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -15,7 +15,7 @@ static void regulator_fixed_release(struct device *dev) { struct fixed_regulator_data *data = container_of(dev, struct fixed_regulator_data, pdev.dev); - kfree(data->cfg.supply_name); + kfree_const(data->cfg.supply_name); kfree(data); } @@ -36,7 +36,7 @@ struct platform_device *regulator_register_always_on(int id, const char *name, if (!data) return NULL; - data->cfg.supply_name = kstrdup(name, GFP_KERNEL); + data->cfg.supply_name = kstrdup_const(name, GFP_KERNEL); if (!data->cfg.supply_name) { kfree(data); return NULL; diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index d492683365..6e1ace660b 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c @@ -161,6 +161,32 @@ int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap); +static int write_separate_vsel_and_range(struct regulator_dev *rdev, + unsigned int sel, unsigned int range) +{ + bool range_updated; + int ret; + + ret = regmap_update_bits_base(rdev->regmap, rdev->desc->vsel_range_reg, + rdev->desc->vsel_range_mask, + range, &range_updated, false, false); + if (ret) + return ret; + + /* + * Some PMICs treat the vsel_reg same as apply-bit. Force it to be + * written if the range changed, even if the old selector was same as + * the new one + */ + if (rdev->desc->range_applied_by_vsel && range_updated) + return regmap_write_bits(rdev->regmap, + rdev->desc->vsel_reg, + rdev->desc->vsel_mask, sel); + + return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, + rdev->desc->vsel_mask, sel); +} + /** * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel * @@ -199,21 +225,12 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev, range = rdev->desc->linear_range_selectors_bitfield[i]; range <<= ffs(rdev->desc->vsel_range_mask) - 1; - if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) { - ret = regmap_update_bits(rdev->regmap, - rdev->desc->vsel_reg, + if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) + ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, rdev->desc->vsel_range_mask | rdev->desc->vsel_mask, sel | range); - } else { - ret = regmap_update_bits(rdev->regmap, - rdev->desc->vsel_range_reg, - rdev->desc->vsel_range_mask, range); - if (ret) - return ret; - - ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, - rdev->desc->vsel_mask, sel); - } + else + ret = write_separate_vsel_and_range(rdev, sel, range); if (ret) return ret; diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index fb4433068d..77a5021410 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -58,7 +58,7 @@ struct regulator { struct dentry *debugfs; }; -extern struct class regulator_class; +extern const struct class regulator_class; static inline struct regulator_dev *dev_to_rdev(struct device *dev) { diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c index 8dfdd1db20..84a134cfcd 100644 --- a/drivers/regulator/lp873x-regulator.c +++ b/drivers/regulator/lp873x-regulator.c @@ -5,6 +5,7 @@ * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ */ +#include <linux/bitfield.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/regmap.h> @@ -93,7 +94,7 @@ static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev, ret = regmap_update_bits(lp873->regmap, regulators[id].ctrl2_reg, LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE, - reg << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE)); + FIELD_PREP(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE, reg)); if (ret) { dev_err(lp873->dev, "SLEW RATE write failed: %d\n", ret); return ret; diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index 61ee5cf3f2..1259b5d201 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -5,6 +5,7 @@ * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ */ +#include <linux/bitfield.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/regmap.h> @@ -99,7 +100,7 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev, ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg, LP87565_BUCK_CTRL_2_SLEW_RATE, - reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE)); + FIELD_PREP(LP87565_BUCK_CTRL_2_SLEW_RATE, reg)); if (ret) { dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret); return ret; diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index e97ade09de..2ade249ab6 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -13,7 +13,7 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/mfd/lp8788.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> /* register address */ #define LP8788_EN_BUCK 0x0C @@ -69,8 +69,8 @@ #define BUCK_FPWM_SHIFT(x) (x) enum lp8788_dvs_state { - DVS_LOW = GPIOF_OUT_INIT_LOW, - DVS_HIGH = GPIOF_OUT_INIT_HIGH, + DVS_LOW = 0, + DVS_HIGH = 1, }; enum lp8788_dvs_mode { @@ -89,6 +89,8 @@ struct lp8788_buck { struct lp8788 *lp; struct regulator_dev *regulator; void *dvs; + struct gpio_desc *gpio1; + struct gpio_desc *gpio2; /* Only used on BUCK2 */ }; /* BUCK 1 ~ 4 voltage ranges */ @@ -106,8 +108,7 @@ static void lp8788_buck1_set_dvs(struct lp8788_buck *buck) return; pinstate = dvs->vsel == DVS_SEL_V0 ? DVS_LOW : DVS_HIGH; - if (gpio_is_valid(dvs->gpio)) - gpio_set_value(dvs->gpio, pinstate); + gpiod_set_value(buck->gpio1, pinstate); } static void lp8788_buck2_set_dvs(struct lp8788_buck *buck) @@ -139,11 +140,8 @@ static void lp8788_buck2_set_dvs(struct lp8788_buck *buck) return; } - if (gpio_is_valid(dvs->gpio[0])) - gpio_set_value(dvs->gpio[0], pin1); - - if (gpio_is_valid(dvs->gpio[1])) - gpio_set_value(dvs->gpio[1], pin2); + gpiod_set_value(buck->gpio1, pin1); + gpiod_set_value(buck->gpio2, pin2); } static void lp8788_set_dvs(struct lp8788_buck *buck, enum lp8788_buck_id id) @@ -202,19 +200,13 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck, enum lp8788_buck_id id) { enum lp8788_dvs_mode mode = lp8788_get_buck_dvs_ctrl_mode(buck, id); - struct lp8788_buck1_dvs *b1_dvs; - struct lp8788_buck2_dvs *b2_dvs; u8 val, idx, addr; int pin1, pin2; switch (id) { case BUCK1: if (mode == EXTPIN) { - b1_dvs = (struct lp8788_buck1_dvs *)buck->dvs; - if (!b1_dvs) - goto err; - - idx = gpio_get_value(b1_dvs->gpio) ? 1 : 0; + idx = gpiod_get_value(buck->gpio1); } else { lp8788_read_byte(buck->lp, LP8788_BUCK_DVS_SEL, &val); idx = (val & LP8788_BUCK1_DVS_M) >> LP8788_BUCK1_DVS_S; @@ -223,12 +215,8 @@ static u8 lp8788_select_buck_vout_addr(struct lp8788_buck *buck, break; case BUCK2: if (mode == EXTPIN) { - b2_dvs = (struct lp8788_buck2_dvs *)buck->dvs; - if (!b2_dvs) - goto err; - - pin1 = gpio_get_value(b2_dvs->gpio[0]); - pin2 = gpio_get_value(b2_dvs->gpio[1]); + pin1 = gpiod_get_value(buck->gpio1); + pin2 = gpiod_get_value(buck->gpio2); if (pin1 == PIN_LOW && pin2 == PIN_LOW) idx = 0; @@ -424,28 +412,28 @@ static int lp8788_dvs_gpio_request(struct platform_device *pdev, enum lp8788_buck_id id) { struct lp8788_platform_data *pdata = buck->lp->pdata; - char *b1_name = "LP8788_B1_DVS"; - char *b2_name[] = { "LP8788_B2_DVS1", "LP8788_B2_DVS2" }; - int i, gpio, ret; + struct device *dev = &pdev->dev; switch (id) { case BUCK1: - gpio = pdata->buck1_dvs->gpio; - ret = devm_gpio_request_one(&pdev->dev, gpio, DVS_LOW, - b1_name); - if (ret) - return ret; + buck->gpio1 = devm_gpiod_get(dev, "dvs", GPIOD_OUT_LOW); + if (IS_ERR(buck->gpio1)) + return PTR_ERR(buck->gpio1); + gpiod_set_consumer_name(buck->gpio1, "LP8788_B1_DVS"); buck->dvs = pdata->buck1_dvs; break; case BUCK2: - for (i = 0; i < LP8788_NUM_BUCK2_DVS; i++) { - gpio = pdata->buck2_dvs->gpio[i]; - ret = devm_gpio_request_one(&pdev->dev, gpio, - DVS_LOW, b2_name[i]); - if (ret) - return ret; - } + buck->gpio1 = devm_gpiod_get_index(dev, "dvs", 0, GPIOD_OUT_LOW); + if (IS_ERR(buck->gpio1)) + return PTR_ERR(buck->gpio1); + gpiod_set_consumer_name(buck->gpio1, "LP8788_B2_DVS1"); + + buck->gpio2 = devm_gpiod_get_index(dev, "dvs", 1, GPIOD_OUT_LOW); + if (IS_ERR(buck->gpio2)) + return PTR_ERR(buck->gpio2); + gpiod_set_consumer_name(buck->gpio2, "LP8788_B2_DVS2"); + buck->dvs = pdata->buck2_dvs; break; default: diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 8d51932075..f8bb6828fe 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -20,9 +20,7 @@ #include <linux/regulator/machine.h> #include <linux/regulator/max8973-regulator.h> #include <linux/regulator/of_regulator.h> -#include <linux/gpio.h> #include <linux/gpio/consumer.h> -#include <linux/of_gpio.h> #include <linux/i2c.h> #include <linux/slab.h> #include <linux/regmap.h> @@ -102,7 +100,7 @@ struct max8973_chip { struct regulator_desc desc; struct regmap *regmap; bool enable_external_control; - int dvs_gpio; + struct gpio_desc *dvs_gpiod; int lru_index[MAX8973_MAX_VOUT_REG]; int curr_vout_val[MAX8973_MAX_VOUT_REG]; int curr_vout_reg; @@ -184,7 +182,7 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev, * If gpios are available to select the VOUT register then least * recently used register for new configuration. */ - if (gpio_is_valid(max->dvs_gpio)) + if (max->dvs_gpiod) found = find_voltage_set_register(max, vsel, &vout_reg, &gpio_val); @@ -201,8 +199,8 @@ static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev, } /* Select proper VOUT register vio gpios */ - if (gpio_is_valid(max->dvs_gpio)) { - gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1); + if (max->dvs_gpiod) { + gpiod_set_value_cansleep(max->dvs_gpiod, gpio_val & 0x1); max->curr_gpio_val = gpio_val; } return 0; @@ -531,7 +529,6 @@ static struct max8973_regulator_platform_data *max8973_parse_dt( pdata->enable_ext_control = of_property_read_bool(np, "maxim,externally-enable"); - pdata->dvs_gpio = of_get_named_gpio(np, "maxim,dvs-gpio", 0); ret = of_property_read_u32(np, "maxim,dvs-default-state", &pval); if (!ret) @@ -612,13 +609,17 @@ static int max8973_probe(struct i2c_client *client) return -EIO; } - if (pdata->dvs_gpio == -EPROBE_DEFER) - return -EPROBE_DEFER; - max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL); if (!max) return -ENOMEM; + max->dvs_gpiod = devm_gpiod_get_optional(&client->dev, "maxim,dvs", + (pdata->dvs_def_state) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW); + if (IS_ERR(max->dvs_gpiod)) + return dev_err_probe(&client->dev, PTR_ERR(max->dvs_gpiod), + "failed to obtain dvs gpio\n"); + gpiod_set_consumer_name(max->dvs_gpiod, "max8973-dvs"); + max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config); if (IS_ERR(max->regmap)) { ret = PTR_ERR(max->regmap); @@ -663,7 +664,6 @@ static int max8973_probe(struct i2c_client *client) max->desc.ramp_delay_table = max8973_buck_ramp_table; max->desc.n_ramp_values = ARRAY_SIZE(max8973_buck_ramp_table); - max->dvs_gpio = (pdata->dvs_gpio) ? pdata->dvs_gpio : -EINVAL; max->enable_external_control = pdata->enable_ext_control; max->curr_gpio_val = pdata->dvs_def_state; max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state; @@ -671,21 +671,9 @@ static int max8973_probe(struct i2c_client *client) max->lru_index[0] = max->curr_vout_reg; - if (gpio_is_valid(max->dvs_gpio)) { - int gpio_flags; + if (max->dvs_gpiod) { int i; - gpio_flags = (pdata->dvs_def_state) ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - ret = devm_gpio_request_one(&client->dev, max->dvs_gpio, - gpio_flags, "max8973-dvs"); - if (ret) { - dev_err(&client->dev, - "gpio_request for gpio %d failed, err = %d\n", - max->dvs_gpio, ret); - return ret; - } - /* * Initialize the lru index with vout_reg id * The index 0 will be most recently used and diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c index 0b38eaa735..5f201ee9a5 100644 --- a/drivers/regulator/max8997-regulator.c +++ b/drivers/regulator/max8997-regulator.c @@ -9,8 +9,7 @@ #include <linux/bug.h> #include <linux/err.h> -#include <linux/gpio.h> -#include <linux/of_gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -32,7 +31,7 @@ struct max8997_data { u8 buck1_vol[8]; u8 buck2_vol[8]; u8 buck5_vol[8]; - int buck125_gpios[3]; + struct gpio_desc *buck125_gpiods[3]; int buck125_gpioindex; bool ignore_gpiodvs_side_effect; @@ -52,9 +51,9 @@ static inline void max8997_set_gpio(struct max8997_data *max8997) int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1; int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1; - gpio_set_value(max8997->buck125_gpios[0], set1); - gpio_set_value(max8997->buck125_gpios[1], set2); - gpio_set_value(max8997->buck125_gpios[2], set3); + gpiod_set_value(max8997->buck125_gpiods[0], set1); + gpiod_set_value(max8997->buck125_gpiods[1], set2); + gpiod_set_value(max8997->buck125_gpiods[2], set3); } struct voltage_map_desc { @@ -873,31 +872,13 @@ static struct regulator_desc regulators[] = { }; #ifdef CONFIG_OF -static int max8997_pmic_dt_parse_dvs_gpio(struct platform_device *pdev, - struct max8997_platform_data *pdata, - struct device_node *pmic_np) -{ - int i, gpio; - - for (i = 0; i < 3; i++) { - gpio = of_get_named_gpio(pmic_np, - "max8997,pmic-buck125-dvs-gpios", i); - if (!gpio_is_valid(gpio)) { - dev_err(&pdev->dev, "invalid gpio[%d]: %d\n", i, gpio); - return -EINVAL; - } - pdata->buck125_gpios[i] = gpio; - } - return 0; -} - static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, struct max8997_platform_data *pdata) { struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct device_node *pmic_np, *regulators_np, *reg_np; struct max8997_regulator_data *rdata; - unsigned int i, dvs_voltage_nr = 1, ret; + unsigned int i, dvs_voltage_nr = 1; pmic_np = iodev->dev->of_node; if (!pmic_np) { @@ -949,10 +930,6 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || pdata->buck5_gpiodvs) { - ret = max8997_pmic_dt_parse_dvs_gpio(pdev, pdata, pmic_np); - if (ret) - return -EINVAL; - if (of_property_read_u32(pmic_np, "max8997,pmic-buck125-default-dvs-idx", &pdata->buck125_default_idx)) { @@ -1039,7 +1016,6 @@ static int max8997_pmic_probe(struct platform_device *pdev) max8997->buck1_gpiodvs = pdata->buck1_gpiodvs; max8997->buck2_gpiodvs = pdata->buck2_gpiodvs; max8997->buck5_gpiodvs = pdata->buck5_gpiodvs; - memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3); max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect; nr_dvs = (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || @@ -1110,38 +1086,27 @@ static int max8997_pmic_probe(struct platform_device *pdev) */ if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs || pdata->buck5_gpiodvs) { + const char *gpio_names[3] = {"MAX8997 SET1", "MAX8997 SET2", "MAX8997 SET3"}; - if (!gpio_is_valid(pdata->buck125_gpios[0]) || - !gpio_is_valid(pdata->buck125_gpios[1]) || - !gpio_is_valid(pdata->buck125_gpios[2])) { - dev_err(&pdev->dev, "GPIO NOT VALID\n"); - return -EINVAL; - } + for (i = 0; i < 3; i++) { + enum gpiod_flags flags; - ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[0], - "MAX8997 SET1"); - if (ret) - return ret; - - ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[1], - "MAX8997 SET2"); - if (ret) - return ret; - - ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[2], - "MAX8997 SET3"); - if (ret) - return ret; - - gpio_direction_output(pdata->buck125_gpios[0], - (max8997->buck125_gpioindex >> 2) - & 0x1); /* SET1 */ - gpio_direction_output(pdata->buck125_gpios[1], - (max8997->buck125_gpioindex >> 1) - & 0x1); /* SET2 */ - gpio_direction_output(pdata->buck125_gpios[2], - (max8997->buck125_gpioindex >> 0) - & 0x1); /* SET3 */ + if (max8997->buck125_gpioindex & BIT(2 - i)) + flags = GPIOD_OUT_HIGH; + else + flags = GPIOD_OUT_LOW; + + max8997->buck125_gpiods[i] = devm_gpiod_get_index(iodev->dev, + "max8997,pmic-buck125-dvs", + i, + flags); + if (IS_ERR(max8997->buck125_gpiods[i])) { + ret = PTR_ERR(max8997->buck125_gpiods[i]); + return dev_err_probe(iodev->dev, ret, "cant get GPIO %d (%d)\n", + i, ret); + } + gpiod_set_consumer_name(max8997->buck125_gpiods[i], gpio_names[i]); + } } /* DVS-GPIO disabled */ diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index fadb471738..254a77887f 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -10,12 +10,12 @@ #include <linux/init.h> #include <linux/i2c.h> #include <linux/err.h> -#include <linux/gpio.h> +#include <linux/bits.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/mutex.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> @@ -31,6 +31,9 @@ struct max8998_data { unsigned int buck1_idx; /* index to last changed voltage */ /* value in a set */ unsigned int buck2_idx; + struct gpio_desc *buck1_gpio1; + struct gpio_desc *buck1_gpio2; + struct gpio_desc *buck2_gpio; }; static const unsigned int charger_current_table[] = { @@ -227,15 +230,15 @@ static int max8998_set_voltage_ldo_sel(struct regulator_dev *rdev, return ret; } -static inline void buck1_gpio_set(int gpio1, int gpio2, int v) +static inline void buck1_gpio_set(struct gpio_desc *gpio1, struct gpio_desc *gpio2, int v) { - gpio_set_value(gpio1, v & 0x1); - gpio_set_value(gpio2, (v >> 1) & 0x1); + gpiod_set_value(gpio1, v & 0x1); + gpiod_set_value(gpio2, (v >> 1) & 0x1); } -static inline void buck2_gpio_set(int gpio, int v) +static inline void buck2_gpio_set(struct gpio_desc *gpio, int v) { - gpio_set_value(gpio, v & 0x1); + gpiod_set_value(gpio, v & 0x1); } static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, @@ -260,16 +263,15 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, selector, max8998->buck1_vol[0], max8998->buck1_vol[1], max8998->buck1_vol[2], max8998->buck1_vol[3]); - if (gpio_is_valid(pdata->buck1_set1) && - gpio_is_valid(pdata->buck1_set2)) { + if (max8998->buck1_gpio1 && max8998->buck1_gpio2) { /* check if requested voltage */ /* value is already defined */ for (j = 0; j < ARRAY_SIZE(max8998->buck1_vol); j++) { if (max8998->buck1_vol[j] == selector) { max8998->buck1_idx = j; - buck1_gpio_set(pdata->buck1_set1, - pdata->buck1_set2, j); + buck1_gpio_set(max8998->buck1_gpio1, + max8998->buck1_gpio2, j); goto buck1_exit; } } @@ -286,13 +288,13 @@ static int max8998_set_voltage_buck_sel(struct regulator_dev *rdev, &shift, &mask); ret = max8998_write_reg(i2c, reg, selector); - buck1_gpio_set(pdata->buck1_set1, - pdata->buck1_set2, max8998->buck1_idx); + buck1_gpio_set(max8998->buck1_gpio1, + max8998->buck1_gpio2, max8998->buck1_idx); buck1_last_val++; buck1_exit: dev_dbg(max8998->dev, "%s: SET1:%d, SET2:%d\n", - i2c->name, gpio_get_value(pdata->buck1_set1), - gpio_get_value(pdata->buck1_set2)); + i2c->name, gpiod_get_value(max8998->buck1_gpio1), + gpiod_get_value(max8998->buck1_gpio2)); break; } else { ret = max8998_write_reg(i2c, reg, selector); @@ -303,14 +305,13 @@ buck1_exit: dev_dbg(max8998->dev, "BUCK2, selector:%d buck2_vol1:%d, buck2_vol2:%d\n", selector, max8998->buck2_vol[0], max8998->buck2_vol[1]); - if (gpio_is_valid(pdata->buck2_set3)) { - + if (max8998->buck2_gpio) { /* check if requested voltage */ /* value is already defined */ for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) { if (max8998->buck2_vol[j] == selector) { max8998->buck2_idx = j; - buck2_gpio_set(pdata->buck2_set3, j); + buck2_gpio_set(max8998->buck2_gpio, j); goto buck2_exit; } } @@ -322,10 +323,10 @@ buck1_exit: ®, &shift, &mask); ret = max8998_write_reg(i2c, reg, selector); max8998->buck2_vol[max8998->buck2_idx] = selector; - buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx); + buck2_gpio_set(max8998->buck2_gpio, max8998->buck2_idx); buck2_exit: dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, - gpio_get_value(pdata->buck2_set3)); + gpiod_get_value(max8998->buck2_gpio)); } else { ret = max8998_write_reg(i2c, reg, selector); } @@ -539,36 +540,6 @@ static const struct regulator_desc regulators[] = { charger_current_table, MAX8998_REG_CHGR1, 0x7), }; -static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev, - struct max8998_platform_data *pdata, - struct device_node *pmic_np) -{ - int gpio; - - gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 0); - if (!gpio_is_valid(gpio)) { - dev_err(iodev->dev, "invalid buck1 gpio[0]: %d\n", gpio); - return -EINVAL; - } - pdata->buck1_set1 = gpio; - - gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck1-dvs-gpios", 1); - if (!gpio_is_valid(gpio)) { - dev_err(iodev->dev, "invalid buck1 gpio[1]: %d\n", gpio); - return -EINVAL; - } - pdata->buck1_set2 = gpio; - - gpio = of_get_named_gpio(pmic_np, "max8998,pmic-buck2-dvs-gpio", 0); - if (!gpio_is_valid(gpio)) { - dev_err(iodev->dev, "invalid buck 2 gpio: %d\n", gpio); - return -EINVAL; - } - pdata->buck2_set3 = gpio; - - return 0; -} - static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, struct max8998_platform_data *pdata) { @@ -614,10 +585,6 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, of_node_put(reg_np); of_node_put(regulators_np); - ret = max8998_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np); - if (ret) - return -EINVAL; - pdata->buck_voltage_lock = of_property_read_bool(pmic_np, "max8998,pmic-buck-voltage-lock"); ret = of_property_read_u32(pmic_np, @@ -665,6 +632,7 @@ static int max8998_pmic_probe(struct platform_device *pdev) struct regulator_dev *rdev; struct max8998_data *max8998; struct i2c_client *i2c; + enum gpiod_flags flags; int i, ret; unsigned int v; @@ -693,37 +661,38 @@ static int max8998_pmic_probe(struct platform_device *pdev) max8998->buck1_idx = pdata->buck1_default_idx; max8998->buck2_idx = pdata->buck2_default_idx; - /* NOTE: */ - /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ - /* will be displayed */ - /* Check if MAX8998 voltage selection GPIOs are defined */ - if (gpio_is_valid(pdata->buck1_set1) && - gpio_is_valid(pdata->buck1_set2)) { - /* Check if SET1 is not equal to 0 */ - if (!pdata->buck1_set1) { - dev_err(&pdev->dev, - "MAX8998 SET1 GPIO defined as 0 !\n"); - WARN_ON(!pdata->buck1_set1); - return -EIO; - } - /* Check if SET2 is not equal to 0 */ - if (!pdata->buck1_set2) { - dev_err(&pdev->dev, - "MAX8998 SET2 GPIO defined as 0 !\n"); - WARN_ON(!pdata->buck1_set2); - return -EIO; - } - - gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); - gpio_direction_output(pdata->buck1_set1, - max8998->buck1_idx & 0x1); - - - gpio_request(pdata->buck1_set2, "MAX8998 BUCK1_SET2"); - gpio_direction_output(pdata->buck1_set2, - (max8998->buck1_idx >> 1) & 0x1); - + flags = (max8998->buck1_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + max8998->buck1_gpio1 = devm_gpiod_get_index_optional(iodev->dev, + "max8998,pmic-buck1-dvs", + 0, + flags); + if (IS_ERR(max8998->buck1_gpio1)) + return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio1), + "could not get BUCK1 GPIO1\n"); + gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET1"); + + flags = (max8998->buck1_idx & BIT(1)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + max8998->buck1_gpio2 = devm_gpiod_get_index_optional(iodev->dev, + "max8998,pmic-buck1-dvs", + 1, + flags); + if (IS_ERR(max8998->buck1_gpio2)) + return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck1_gpio2), + "could not get BUCK1 GPIO2\n"); + gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK1_SET2"); + + flags = (max8998->buck2_idx & BIT(0)) ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + max8998->buck2_gpio = devm_gpiod_get_index_optional(iodev->dev, + "max8998,pmic-buck2-dvs", + 0, + flags); + if (IS_ERR(max8998->buck2_gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(max8998->buck2_gpio), + "could not get BUCK2 GPIO\n"); + gpiod_set_consumer_name(max8998->buck1_gpio1, "MAX8998 BUCK2_SET3"); + + if (max8998->buck1_gpio1 && max8998->buck1_gpio2) { /* Set predefined values for BUCK1 registers */ for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) { int index = MAX8998_BUCK1 - MAX8998_LDO2; @@ -742,18 +711,7 @@ static int max8998_pmic_probe(struct platform_device *pdev) } } - if (gpio_is_valid(pdata->buck2_set3)) { - /* Check if SET3 is not equal to 0 */ - if (!pdata->buck2_set3) { - dev_err(&pdev->dev, - "MAX8998 SET3 GPIO defined as 0 !\n"); - WARN_ON(!pdata->buck2_set3); - return -EIO; - } - gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); - gpio_direction_output(pdata->buck2_set3, - max8998->buck2_idx & 0x1); - + if (max8998->buck2_gpio) { /* Set predefined values for BUCK2 registers */ for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) { int index = MAX8998_BUCK2 - MAX8998_LDO2; diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c index b820bd6043..ab105ffd6a 100644 --- a/drivers/regulator/mp8859.c +++ b/drivers/regulator/mp8859.c @@ -35,6 +35,16 @@ #define MP8859_GO_BIT 0x01 +#define MP8859_IOUT_LIM_MASK 0x7f + +#define MP8859_ENABLE_MASK 0x80 +#define MP8859_DISCHG_EN_MASK 0x10 +#define MP8859_MODE_MASK 0x08 + +#define MP8859_PG_MASK 0x80 +#define MP8859_OTP_MASK 0x40 +#define MP8859_OTW_MASK 0x20 +#define MP8859_CC_CV_MASK 0x10 static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) { @@ -73,21 +83,221 @@ static int mp8859_get_voltage_sel(struct regulator_dev *rdev) return val; } +static int mp8859_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int from, unsigned int to) +{ + int change; + + /* The voltage ramps at 1mV/uS, selectors are 10mV */ + if (from > to) + change = from - to; + else + change = to - from; + + return change * 10 * 1000; +} + +static unsigned int mp8859_get_mode(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val); + if (ret != 0) { + dev_err(&rdev->dev, "Failed to read mode: %d\n", ret); + return 0; + } + + if (val & MP8859_MODE_MASK) + return REGULATOR_MODE_FAST; + else + return REGULATOR_MODE_NORMAL; +} + +static int mp8859_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + unsigned int val; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = MP8859_MODE_MASK; + break; + case REGULATOR_MODE_NORMAL: + val = 0; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(rdev->regmap, MP8859_CTL1_REG, + MP8859_MODE_MASK, val); +} + +static int mp8859_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) +{ + unsigned int cur_val, new_val; + int ret, i; + + /* Steps of 50mA */ + new_val = max_uA / 50000; + if (new_val > MP8859_IOUT_LIM_MASK) + return -EINVAL; + if (new_val == 0) + return -EINVAL; + + /* + * If the regulator is limiting then ramp gradually as per + * datasheet, otherwise just set the value directly. + */ + ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &cur_val); + if (ret != 0) + return ret; + if (!(cur_val & MP8859_CC_CV_MASK)) { + return regmap_update_bits(rdev->regmap, MP8859_IOUT_LIM_REG, + MP8859_IOUT_LIM_MASK, new_val); + } + + ret = regmap_read(rdev->regmap, MP8859_IOUT_LIM_REG, &cur_val); + if (ret != 0) + return ret; + + if (cur_val >= new_val) { + for (i = cur_val; i >= new_val; i--) { + ret = regmap_update_bits(rdev->regmap, + MP8859_IOUT_LIM_REG, + MP8859_IOUT_LIM_MASK, + cur_val - i); + if (ret != 0) + return ret; + } + } else { + for (i = cur_val; i <= new_val; i++) { + ret = regmap_update_bits(rdev->regmap, + MP8859_IOUT_LIM_REG, + MP8859_IOUT_LIM_MASK, + cur_val + i); + if (ret != 0) + return ret; + } + } + + return 0; +} + +static int mp8859_get_status(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + /* Output status is only meaingful when enabled */ + ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &val); + if (ret != 0) + return ret; + if (!(val & MP8859_ENABLE_MASK)) + return REGULATOR_STATUS_UNDEFINED; + + ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &val); + if (ret != 0) + return ret; + + if (val & MP8859_PG_MASK) + return REGULATOR_STATUS_ON; + else + return REGULATOR_STATUS_ERROR; +} + +static int mp8859_get_error_flags(struct regulator_dev *rdev, + unsigned int *flags) +{ + unsigned int status, enabled; + int ret; + + *flags = 0; + + /* Output status is only meaingful when enabled */ + ret = regmap_read(rdev->regmap, MP8859_CTL1_REG, &enabled); + if (ret != 0) + return ret; + enabled &= MP8859_ENABLE_MASK; + + ret = regmap_read(rdev->regmap, MP8859_STATUS_REG, &status); + if (ret != 0) + return ret; + + if (enabled && !(status & MP8859_PG_MASK)) + status |= REGULATOR_ERROR_FAIL; + if (status & MP8859_OTP_MASK) + status |= REGULATOR_ERROR_OVER_TEMP; + if (status & MP8859_OTW_MASK) + status |= REGULATOR_ERROR_OVER_TEMP_WARN; + if (status & MP8859_CC_CV_MASK) + status |= REGULATOR_ERROR_OVER_CURRENT; + + return 0; +} + static const struct linear_range mp8859_dcdc_ranges[] = { REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000), }; +static bool mp8859_readable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MP8859_VOUT_L_REG: + case MP8859_VOUT_H_REG: + case MP8859_VOUT_GO_REG: + case MP8859_IOUT_LIM_REG: + case MP8859_CTL1_REG: + case MP8859_CTL2_REG: + case MP8859_STATUS_REG: + case MP8859_INTERRUPT_REG: + case MP8859_MASK_REG: + case MP8859_ID1_REG: + case MP8859_MFR_ID_REG: + case MP8859_DEV_ID_REG: + case MP8859_IC_REV_REG: + return true; + default: + return false; + } +} + +static bool mp8859_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MP8859_VOUT_GO_REG: + case MP8859_STATUS_REG: + case MP8859_INTERRUPT_REG: + return true; + default: + return false; + } +} + static const struct regmap_config mp8859_regmap = { .reg_bits = 8, .val_bits = 8, .max_register = MP8859_MAX_REG, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, + .readable_reg = mp8859_readable, + .volatile_reg = mp8859_volatile, }; static const struct regulator_ops mp8859_ops = { .set_voltage_sel = mp8859_set_voltage_sel, .get_voltage_sel = mp8859_get_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_time_sel = mp8859_set_voltage_time_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_mode = mp8859_set_mode, + .get_mode = mp8859_get_mode, + .set_active_discharge = regulator_set_active_discharge_regmap, + .set_current_limit = mp8859_set_current_limit, + .get_status = mp8859_get_status, + .get_error_flags = mp8859_get_error_flags, }; static const struct regulator_desc mp8859_regulators[] = { @@ -100,6 +310,12 @@ static const struct regulator_desc mp8859_regulators[] = { .n_voltages = VOL_MAX_IDX + 1, .linear_ranges = mp8859_dcdc_ranges, .n_linear_ranges = 1, + .enable_reg = MP8859_CTL1_REG, + .enable_mask = MP8859_ENABLE_MASK, + .enable_val = MP8859_ENABLE_MASK, + .active_discharge_reg = MP8859_CTL1_REG, + .active_discharge_on = MP8859_DISCHG_EN_MASK, + .active_discharge_mask = MP8859_DISCHG_EN_MASK, .ops = &mp8859_ops, .owner = THIS_MODULE, }, @@ -111,12 +327,46 @@ static int mp8859_i2c_probe(struct i2c_client *i2c) struct regulator_config config = {.dev = &i2c->dev}; struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap); struct regulator_dev *rdev; + unsigned int val, rev; if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); dev_err(&i2c->dev, "regmap init failed: %d\n", ret); return ret; } + + ret = regmap_read(regmap, MP8859_MFR_ID_REG, &val); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read manufacturer ID: %d\n", ret); + return ret; + } + if (val != 0x9) { + dev_err(&i2c->dev, "Manufacturer ID %x != 9\n", val); + return -EINVAL; + } + + ret = regmap_read(regmap, MP8859_DEV_ID_REG, &val); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read device ID: %d\n", ret); + return ret; + } + if (val != 0x58) { + dev_err(&i2c->dev, "Manufacturer ID %x != 0x58\n", val); + return -EINVAL; + } + + ret = regmap_read(regmap, MP8859_IC_REV_REG, &rev); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read device revision: %d\n", ret); + return ret; + } + ret = regmap_read(regmap, MP8859_ID1_REG, &val); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read device ID1: %d\n", ret); + return ret; + } + dev_info(&i2c->dev, "MP8859-%04d revision %d\n", val, rev); + rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0], &config); diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 60cfcd741c..7434b6b22d 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -271,11 +271,10 @@ static int pwm_regulator_init_table(struct platform_device *pdev, of_find_property(np, "voltage-table", &length); if ((length < sizeof(*duty_cycle_table)) || - (length % sizeof(*duty_cycle_table))) { - dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n", - length); - return -EINVAL; - } + (length % sizeof(*duty_cycle_table))) + return dev_err_probe(&pdev->dev, -EINVAL, + "voltage-table length(%d) is invalid\n", + length); duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL); if (!duty_cycle_table) @@ -284,10 +283,9 @@ static int pwm_regulator_init_table(struct platform_device *pdev, ret = of_property_read_u32_array(np, "voltage-table", (u32 *)duty_cycle_table, length / sizeof(u32)); - if (ret) { - dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Failed to read voltage-table\n"); drvdata->state = -ENOTRECOVERABLE; drvdata->duty_cycle_table = duty_cycle_table; @@ -359,10 +357,9 @@ static int pwm_regulator_probe(struct platform_device *pdev) enum gpiod_flags gpio_flags; int ret; - if (!np) { - dev_err(&pdev->dev, "Device Tree node missing\n"); - return -EINVAL; - } + if (!np) + return dev_err_probe(&pdev->dev, -EINVAL, + "Device Tree node missing\n"); drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) @@ -400,8 +397,7 @@ static int pwm_regulator_probe(struct platform_device *pdev) gpio_flags); if (IS_ERR(drvdata->enb_gpio)) { ret = PTR_ERR(drvdata->enb_gpio); - dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret); - return ret; + return dev_err_probe(&pdev->dev, ret, "Failed to get enable GPIO\n"); } ret = pwm_adjust_config(drvdata->pwm); @@ -409,19 +405,17 @@ static int pwm_regulator_probe(struct platform_device *pdev) return ret; ret = pwm_regulator_init_boot_on(pdev, drvdata, init_data); - if (ret) { - dev_err(&pdev->dev, "Failed to apply boot_on settings: %d\n", - ret); - return ret; - } + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Failed to apply boot_on settings\n"); regulator = devm_regulator_register(&pdev->dev, &drvdata->desc, &config); if (IS_ERR(regulator)) { ret = PTR_ERR(regulator); - dev_err(&pdev->dev, "Failed to register regulator %s: %d\n", - drvdata->desc.name, ret); - return ret; + return dev_err_probe(&pdev->dev, ret, + "Failed to register regulator %s\n", + drvdata->desc.name); } return 0; diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index d1be956802..3b7e06b9f5 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -11,11 +11,10 @@ #include <linux/regulator/of_regulator.h> #include <linux/soc/qcom/smd-rpm.h> +struct qcom_smd_rpm *smd_vreg_rpm; + struct qcom_rpm_reg { struct device *dev; - - struct qcom_smd_rpm *rpm; - u32 type; u32 id; @@ -70,7 +69,7 @@ static int rpm_reg_write_active(struct qcom_rpm_reg *vreg) if (!reqlen) return 0; - ret = qcom_rpm_smd_write(vreg->rpm, QCOM_SMD_RPM_ACTIVE_STATE, + ret = qcom_rpm_smd_write(smd_vreg_rpm, QCOM_SMD_RPM_ACTIVE_STATE, vreg->type, vreg->id, req, sizeof(req[0]) * reqlen); if (!ret) { @@ -1384,14 +1383,13 @@ MODULE_DEVICE_TABLE(of, rpm_of_match); * @dev: Pointer to the top level qcom_smd-regulator PMIC device * @node: Pointer to the individual qcom_smd-regulator resource * device node - * @rpm: Pointer to the rpm bus node * @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator * resources defined for the top level PMIC device * * Return: 0 on success, errno on failure */ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev, - struct device_node *node, struct qcom_smd_rpm *rpm, + struct device_node *node, const struct rpm_regulator_data *pmic_rpm_data) { struct regulator_config config = {}; @@ -1409,7 +1407,6 @@ static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev } vreg->dev = dev; - vreg->rpm = rpm; vreg->type = rpm_data->type; vreg->id = rpm_data->id; @@ -1449,6 +1446,11 @@ static int rpm_reg_probe(struct platform_device *pdev) return -ENODEV; } + if (smd_vreg_rpm && rpm != smd_vreg_rpm) + return dev_err_probe(dev, -EINVAL, "RPM mismatch\n"); + + smd_vreg_rpm = rpm; + vreg_data = of_device_get_match_data(dev); if (!vreg_data) return -ENODEV; @@ -1460,8 +1462,7 @@ static int rpm_reg_probe(struct platform_device *pdev) return -ENOMEM; } - ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data); - + ret = rpm_regulator_init_vreg(vreg, dev, node, vreg_data); if (ret < 0) { of_node_put(node); return ret; diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c index 2d54844c42..3079de41ef 100644 --- a/drivers/regulator/rtq2208-regulator.c +++ b/drivers/regulator/rtq2208-regulator.c @@ -48,7 +48,7 @@ /* Value */ #define RTQ2208_RAMP_VALUE_MIN_uV 500 -#define RTQ2208_RAMP_VALUE_MAX_uV 64000 +#define RTQ2208_RAMP_VALUE_MAX_uV 16000 #define RTQ2208_BUCK_MASK(uv_irq, ov_irq) (1 << ((uv_irq) % 8) | 1 << ((ov_irq) % 8)) @@ -142,12 +142,11 @@ static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) * Because the relation of seleltion and value is like that * * seletion: value - * 000: 64mv - * 001: 32mv + * 010: 16mv * ... * 111: 0.5mv * - * For example, if I would like to select 64mv, the fls(ramp_delay) - 1 will be 0b111, + * For example, if I would like to select 16mv, the fls(ramp_delay) - 1 will be 0b010, * and I need to use 0b111 - sel to do the shifting */ diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c index 9b7c3d7778..3c9d79e003 100644 --- a/drivers/regulator/tps6287x-regulator.c +++ b/drivers/regulator/tps6287x-regulator.c @@ -115,6 +115,7 @@ static struct regulator_desc tps6287x_reg = { .vsel_mask = 0xFF, .vsel_range_reg = TPS6287X_CTRL2, .vsel_range_mask = TPS6287X_CTRL2_VRANGE, + .range_applied_by_vsel = true, .ramp_reg = TPS6287X_CTRL1, .ramp_mask = TPS6287X_CTRL1_VRAMP, .ramp_delay_table = tps6287x_ramp_table, diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c index b7f0c87797..5fad61785e 100644 --- a/drivers/regulator/tps6594-regulator.c +++ b/drivers/regulator/tps6594-regulator.c @@ -287,30 +287,30 @@ static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = { static const struct regulator_desc multi_regs[] = { TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1, REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_VOUT_1(1), + TPS6594_REG_BUCKX_VOUT_1(0), TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_CTRL(1), + TPS6594_REG_BUCKX_CTRL(0), TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges, 4, 4000, 0, NULL, 0, 0), TPS6594_REGULATOR("BUCK34", "buck34", TPS6594_BUCK_3, REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_VOUT_1(3), + TPS6594_REG_BUCKX_VOUT_1(2), TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_CTRL(3), + TPS6594_REG_BUCKX_CTRL(2), TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges, 4, 0, 0, NULL, 0, 0), TPS6594_REGULATOR("BUCK123", "buck123", TPS6594_BUCK_1, REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_VOUT_1(1), + TPS6594_REG_BUCKX_VOUT_1(0), TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_CTRL(1), + TPS6594_REG_BUCKX_CTRL(0), TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges, 4, 4000, 0, NULL, 0, 0), TPS6594_REGULATOR("BUCK1234", "buck1234", TPS6594_BUCK_1, REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_VOUT_1(1), + TPS6594_REG_BUCKX_VOUT_1(0), TPS6594_MASK_BUCKS_VSET, - TPS6594_REG_BUCKX_CTRL(1), + TPS6594_REG_BUCKX_CTRL(0), TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges, 4, 4000, 0, NULL, 0, 0), }; |