diff options
Diffstat (limited to 'drivers/regulator')
133 files changed, 3480 insertions, 4512 deletions
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index 89bbd6e8bad1..69ae25886181 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulators driver for Marvell 88PM800 * * Copyright (C) 2012 Marvell International Ltd. * Joseph(Yossi) Hanin <yhanin@marvell.com> * Yi Zhang <yizhang@marvell.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/module.h> #include <linux/moduleparam.h> @@ -77,11 +74,6 @@ struct pm800_regulator_info { int max_ua; }; -struct pm800_regulators { - struct pm80x_chip *chip; - struct regmap *map; -}; - /* * vreg - the buck regs string. * ereg - the string for the enable register. @@ -235,7 +227,6 @@ static int pm800_regulator_probe(struct platform_device *pdev) { struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent); - struct pm800_regulators *pm800_data; struct regulator_config config = { }; struct regulator_init_data *init_data; int i, ret; @@ -252,18 +243,8 @@ static int pm800_regulator_probe(struct platform_device *pdev) return -EINVAL; } - pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), - GFP_KERNEL); - if (!pm800_data) - return -ENOMEM; - - pm800_data->map = chip->subchip->regmap_power; - pm800_data->chip = chip; - - platform_set_drvdata(pdev, pm800_data); - config.dev = chip->dev; - config.regmap = pm800_data->map; + config.regmap = chip->subchip->regmap_power; for (i = 0; i < PM800_ID_RG_MAX; i++) { struct regulator_dev *regulator; diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 28f55248eb90..1d1c4a7ec3e2 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -1,17 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulators driver for Marvell 88PM8607 * * Copyright (C) 2009 Marvell International Ltd. * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> #include <linux/init.h> #include <linux/err.h> -#include <linux/i2c.h> #include <linux/of.h> #include <linux/regulator/of_regulator.h> #include <linux/platform_device.h> @@ -22,12 +18,7 @@ struct pm8607_regulator_info { struct regulator_desc desc; - struct pm860x_chip *chip; - struct regulator_dev *regulator; - struct i2c_client *i2c; - struct i2c_client *i2c_8606; - unsigned int *vol_table; unsigned int *vol_suspend; int slope_double; @@ -210,13 +201,15 @@ static const unsigned int LDO14_suspend_table[] = { static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) { struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - int ret = -EINVAL; + int ret; + + ret = regulator_list_voltage_table(rdev, index); + if (ret < 0) + return ret; + + if (info->slope_double) + ret <<= 1; - if (info->vol_table && (index < rdev->desc->n_voltages)) { - ret = info->vol_table[index]; - if (info->slope_double) - ret <<= 1; - } return ret; } @@ -239,6 +232,8 @@ static const struct regulator_ops pm8606_preg_ops = { { \ .desc = { \ .name = "PREG", \ + .of_match = of_match_ptr("PREG"), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &pm8606_preg_ops, \ .type = REGULATOR_CURRENT, \ .id = PM8606_ID_PREG, \ @@ -253,10 +248,13 @@ static const struct regulator_ops pm8606_preg_ops = { { \ .desc = { \ .name = #vreg, \ + .of_match = of_match_ptr(#vreg), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &pm8607_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .id = PM8607_ID_##vreg, \ .owner = THIS_MODULE, \ + .volt_table = vreg##_table, \ .n_voltages = ARRAY_SIZE(vreg##_table), \ .vsel_reg = PM8607_##vreg, \ .vsel_mask = ARRAY_SIZE(vreg##_table) - 1, \ @@ -266,7 +264,6 @@ static const struct regulator_ops pm8606_preg_ops = { .enable_mask = 1 << (ebit), \ }, \ .slope_double = (0), \ - .vol_table = (unsigned int *)&vreg##_table, \ .vol_suspend = (unsigned int *)&vreg##_suspend_table, \ } @@ -274,10 +271,13 @@ static const struct regulator_ops pm8606_preg_ops = { { \ .desc = { \ .name = "LDO" #_id, \ + .of_match = of_match_ptr("LDO" #_id), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &pm8607_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .id = PM8607_ID_LDO##_id, \ .owner = THIS_MODULE, \ + .volt_table = LDO##_id##_table, \ .n_voltages = ARRAY_SIZE(LDO##_id##_table), \ .vsel_reg = PM8607_##vreg, \ .vsel_mask = (ARRAY_SIZE(LDO##_id##_table) - 1) << (shift), \ @@ -285,7 +285,6 @@ static const struct regulator_ops pm8606_preg_ops = { .enable_mask = 1 << (ebit), \ }, \ .slope_double = (0), \ - .vol_table = (unsigned int *)&LDO##_id##_table, \ .vol_suspend = (unsigned int *)&LDO##_id##_suspend_table, \ } @@ -313,42 +312,13 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = { PM8606_PREG(PREREGULATORB, 5), }; -#ifdef CONFIG_OF -static int pm8607_regulator_dt_init(struct platform_device *pdev, - struct pm8607_regulator_info *info, - struct regulator_config *config) -{ - struct device_node *nproot, *np; - nproot = pdev->dev.parent->of_node; - if (!nproot) - return -ENODEV; - nproot = of_get_child_by_name(nproot, "regulators"); - if (!nproot) { - dev_err(&pdev->dev, "failed to find regulators node\n"); - return -ENODEV; - } - for_each_child_of_node(nproot, np) { - if (of_node_name_eq(np, info->desc.name)) { - config->init_data = - of_get_regulator_init_data(&pdev->dev, np, - &info->desc); - config->of_node = np; - break; - } - } - of_node_put(nproot); - return 0; -} -#else -#define pm8607_regulator_dt_init(x, y, z) (-1) -#endif - static int pm8607_regulator_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm8607_regulator_info *info = NULL; struct regulator_init_data *pdata = dev_get_platdata(&pdev->dev); struct regulator_config config = { }; + struct regulator_dev *rdev; struct resource *res; int i; @@ -371,33 +341,27 @@ static int pm8607_regulator_probe(struct platform_device *pdev) /* i is used to check regulator ID */ i = -1; } - info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; - info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : - chip->client; - info->chip = chip; /* check DVC ramp slope double */ - if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double) + if ((i == PM8607_ID_BUCK3) && chip->buck3_double) info->slope_double = 1; - config.dev = &pdev->dev; + config.dev = chip->dev; config.driver_data = info; - if (pm8607_regulator_dt_init(pdev, info, &config)) - if (pdata) - config.init_data = pdata; + if (pdata) + config.init_data = pdata; if (chip->id == CHIP_PM8607) config.regmap = chip->regmap; else config.regmap = chip->regmap_companion; - info->regulator = devm_regulator_register(&pdev->dev, &info->desc, - &config); - if (IS_ERR(info->regulator)) { + rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); + if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); - return PTR_ERR(info->regulator); + return PTR_ERR(rdev); } platform_set_drvdata(pdev, info); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index ee60a222f5eb..8553bdf87c1d 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menuconfig REGULATOR bool "Voltage and Current Regulator Support" help @@ -180,6 +181,17 @@ config REGULATOR_BCM590XX BCM590xx PMUs. This will enable support for the software controllable LDO/Switching regulators. +config REGULATOR_BD70528 + tristate "ROHM BD70528 Power Regulator" + depends on MFD_ROHM_BD70528 + help + This driver supports voltage regulators on ROHM BD70528 PMIC. + This will enable support for the software controllable buck + and LDO regulators. + + This driver can also be built as a module. If so, the module + will be called bd70528-regulator. + config REGULATOR_BD718XX tristate "ROHM BD71837 Power Regulator" depends on MFD_ROHM_BD718XX @@ -212,6 +224,7 @@ config REGULATOR_CPCAP 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 help Say y here to support the BUCKs and LDOs regulators found on Dialog Semiconductor DA9030/DA9034 PMIC. @@ -457,6 +470,14 @@ config REGULATOR_MAX77620 chip to control Step-Down DC-DC and LDOs. Say Y here to enable the regulator driver. +config REGULATOR_MAX77650 + tristate "Maxim MAX77650/77651 regulator support" + depends on MFD_MAX77650 + help + Regulator driver for MAX77650/77651 PMIC from Maxim + Semiconductor. This device has a SIMO with three independent + power rails and an LDO. + config REGULATOR_MAX8649 tristate "Maxim 8649 voltage regulator" depends on I2C @@ -484,7 +505,7 @@ config REGULATOR_MAX8925 tristate "Maxim MAX8925 Power Management IC" depends on MFD_MAX8925 help - Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. + Say y here to support the voltage regulator of Maxim MAX8925 PMIC. config REGULATOR_MAX8952 tristate "Maxim MAX8952 Power Management IC" @@ -501,7 +522,7 @@ config REGULATOR_MAX8973 select REGMAP_I2C help The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down - switching regulator delievers up to 9A of output current. Each + switching regulator delivers up to 9A of output current. Each phase operates at a 2MHz fixed frequency with a 120 deg shift from the adjacent phase, allowing the use of small magnetic component. @@ -646,7 +667,7 @@ config REGULATOR_PCF50633 tristate "NXP PCF50633 regulator driver" depends on MFD_PCF50633 help - Say Y here to support the voltage regulators and convertors + Say Y here to support the voltage regulators and converters on PCF50633 config REGULATOR_PFUZE100 @@ -820,6 +841,13 @@ config REGULATOR_STM32_VREFBUF This driver can also be built as a module. If so, the module will be called stm32-vrefbuf. +config REGULATOR_STM32_PWR + bool "STMicroelectronics STM32 PWR" + depends on ARCH_STM32 || COMPILE_TEST + help + This driver supports internal regulators (1V1, 1V8, 3V3) in the + STMicroelectronics STM32 chips. + config REGULATOR_STPMIC1 tristate "STMicroelectronics STPMIC1 PMIC Regulators" depends on MFD_STPMIC1 @@ -924,7 +952,7 @@ config REGULATOR_TPS65132 select REGMAP_I2C help This driver supports TPS65132 single inductor - dual output - power supply specifcally designed for display panels. + power supply specifically designed for display panels. config REGULATOR_TPS65217 tristate "TI TPS65217 Power regulators" @@ -991,7 +1019,8 @@ config REGULATOR_TWL4030 config REGULATOR_UNIPHIER tristate "UniPhier regulator driver" depends on ARCH_UNIPHIER || COMPILE_TEST - depends on OF && MFD_SYSCON + depends on OF + select REGMAP_MMIO default ARCH_UNIPHIER help Support for regulators implemented on Socionext UniPhier SoCs. diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b12e1c9b2118..93f53840e8f1 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o +obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o @@ -60,6 +61,7 @@ obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o +obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o @@ -103,6 +105,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o +obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index afc5b5900181..d6ed5bf9235e 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * linux/drivers/regulator/aat2870-regulator.c * * Copyright (c) 2011, NVIDIA Corporation. * Author: Jin Park <jinyoungp@nvidia.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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA */ #include <linux/kernel.h> diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index de2644490f0d..a544f45efe53 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -1,8 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/regulator/ab3100.c * * Copyright (C) 2008-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 * Low-level control of the AB3100 IC Low Dropout (LDO) * regulators, external regulator and buck converter * Author: Mattias Wallin <mattias.wallin@stericsson.com> @@ -48,7 +48,6 @@ * @regreg: regulator register number in the AB3100 */ struct ab3100_regulator { - struct regulator_dev *rdev; struct device *dev; struct ab3100_platform_data *plfdata; u8 regreg; @@ -354,14 +353,13 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) return 0; } -static struct regulator_ops regulator_ops_fixed = { - .list_voltage = regulator_list_voltage_linear, +static const struct regulator_ops regulator_ops_fixed = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, }; -static struct regulator_ops regulator_ops_variable = { +static const struct regulator_ops regulator_ops_variable = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, @@ -370,7 +368,7 @@ static struct regulator_ops regulator_ops_variable = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops regulator_ops_variable_sleepable = { +static const struct regulator_ops regulator_ops_variable_sleepable = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, @@ -386,14 +384,14 @@ static struct regulator_ops regulator_ops_variable_sleepable = { * is an on/off switch plain an simple. The external * voltage is defined in the board set-up if any. */ -static struct regulator_ops regulator_ops_external = { +static const struct regulator_ops regulator_ops_external = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator_external, }; -static struct regulator_desc +static const struct regulator_desc ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { { .name = "LDO_A", @@ -402,7 +400,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_A_VOLTAGE, + .fixed_uV = LDO_A_VOLTAGE, .enable_time = 200, }, { @@ -412,7 +410,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_C_VOLTAGE, + .fixed_uV = LDO_C_VOLTAGE, .enable_time = 200, }, { @@ -422,7 +420,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_D_VOLTAGE, + .fixed_uV = LDO_D_VOLTAGE, .enable_time = 200, }, { @@ -500,7 +498,7 @@ static int ab3100_regulator_register(struct platform_device *pdev, struct device_node *np, unsigned long id) { - struct regulator_desc *desc; + const struct regulator_desc *desc; struct ab3100_regulator *reg; struct regulator_dev *rdev; struct regulator_config config = { }; @@ -545,8 +543,6 @@ static int ab3100_regulator_register(struct platform_device *pdev, return err; } - /* Then set a pointer back to the registered regulator */ - reg->rdev = rdev; return 0; } @@ -609,18 +605,6 @@ static const u8 ab3100_reg_initvals[] = { LDO_D_SETTING, }; -static int ab3100_regulators_remove(struct platform_device *pdev) -{ - int i; - - for (i = 0; i < AB3100_NUM_REGULATORS; i++) { - struct ab3100_regulator *reg = &ab3100_regulators[i]; - - reg->rdev = NULL; - } - return 0; -} - static int ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) { @@ -647,10 +631,8 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) pdev, NULL, ab3100_regulator_matches[i].init_data, ab3100_regulator_matches[i].of_node, (unsigned long)ab3100_regulator_matches[i].driver_data); - if (err) { - ab3100_regulators_remove(pdev); + if (err) return err; - } } return 0; @@ -705,14 +687,12 @@ static int ab3100_regulators_probe(struct platform_device *pdev) /* Register the regulators */ for (i = 0; i < AB3100_NUM_REGULATORS; i++) { - struct regulator_desc *desc = &ab3100_regulator_desc[i]; + const struct regulator_desc *desc = &ab3100_regulator_desc[i]; err = ab3100_regulator_register(pdev, plfdata, NULL, NULL, desc->id); - if (err) { - ab3100_regulators_remove(pdev); + if (err) return err; - } } return 0; @@ -723,7 +703,6 @@ static struct platform_driver ab3100_regulators_driver = { .name = "ab3100-regulators", }, .probe = ab3100_regulators_probe, - .remove = ab3100_regulators_remove, }; static __init int ab3100_regulators_init(void) diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 2ca00045eb99..8bb43a671ded 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * - * License Terms: GNU General Public License v2 - * * Authors: Bengt Jonsson <bengt.g.jonsson@stericsson.com> * * This file is based on drivers/regulator/ab8500.c @@ -479,7 +478,6 @@ static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { * struct ab8500_ext_regulator_info - ab8500 regulator information * @dev: device pointer * @desc: regulator description - * @rdev: regulator device * @cfg: regulator configuration (extension of regulator FW configuration) * @update_bank: bank to control on/off * @update_reg: register to control on/off @@ -495,7 +493,6 @@ static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { struct ab8500_ext_regulator_info { struct device *dev; struct regulator_desc desc; - struct regulator_dev *rdev; struct ab8500_ext_regulator_cfg *cfg; u8 update_bank; u8 update_reg; @@ -530,7 +527,7 @@ static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) info->update_bank, info->update_reg, info->update_mask, regval); if (ret < 0) { - dev_err(rdev_get_dev(info->rdev), + dev_err(rdev_get_dev(rdev), "couldn't set enable bits for regulator\n"); return ret; } @@ -566,7 +563,7 @@ static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) info->update_bank, info->update_reg, info->update_mask, regval); if (ret < 0) { - dev_err(rdev_get_dev(info->rdev), + dev_err(rdev_get_dev(rdev), "couldn't set disable bits for regulator\n"); return ret; } @@ -720,7 +717,7 @@ static int ab8500_ext_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static struct regulator_ops ab8500_ext_regulator_ops = { +static const struct regulator_ops ab8500_ext_regulator_ops = { .enable = ab8500_ext_regulator_enable, .disable = ab8500_ext_regulator_disable, .is_enabled = ab8500_ext_regulator_is_enabled, @@ -735,6 +732,7 @@ static struct ab8500_ext_regulator_info [AB8500_EXT_SUPPLY1] = { .desc = { .name = "VEXTSUPPLY1", + .of_match = of_match_ptr("ab8500_ext1"), .ops = &ab8500_ext_regulator_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_EXT_SUPPLY1, @@ -752,6 +750,7 @@ static struct ab8500_ext_regulator_info [AB8500_EXT_SUPPLY2] = { .desc = { .name = "VEXTSUPPLY2", + .of_match = of_match_ptr("ab8500_ext2"), .ops = &ab8500_ext_regulator_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_EXT_SUPPLY2, @@ -769,6 +768,7 @@ static struct ab8500_ext_regulator_info [AB8500_EXT_SUPPLY3] = { .desc = { .name = "VEXTSUPPLY3", + .of_match = of_match_ptr("ab8500_ext3"), .ops = &ab8500_ext_regulator_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_EXT_SUPPLY3, @@ -785,30 +785,13 @@ static struct ab8500_ext_regulator_info }, }; -static struct of_regulator_match ab8500_ext_regulator_match[] = { - { .name = "ab8500_ext1", .driver_data = (void *) AB8500_EXT_SUPPLY1, }, - { .name = "ab8500_ext2", .driver_data = (void *) AB8500_EXT_SUPPLY2, }, - { .name = "ab8500_ext3", .driver_data = (void *) AB8500_EXT_SUPPLY3, }, -}; - static int ab8500_ext_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_regulator_platform_data *pdata = &ab8500_regulator_plat_data; - struct device_node *np = pdev->dev.of_node; struct regulator_config config = { }; - int i, err; - - if (np) { - err = of_regulator_match(&pdev->dev, np, - ab8500_ext_regulator_match, - ARRAY_SIZE(ab8500_ext_regulator_match)); - if (err < 0) { - dev_err(&pdev->dev, - "Error parsing regulator init data: %d\n", err); - return err; - } - } + struct regulator_dev *rdev; + int i; if (!ab8500) { dev_err(&pdev->dev, "null mfd parent\n"); @@ -844,23 +827,18 @@ static int ab8500_ext_regulator_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.driver_data = info; - config.of_node = ab8500_ext_regulator_match[i].of_node; - config.init_data = (np) ? - ab8500_ext_regulator_match[i].init_data : - &pdata->ext_regulator[i]; + config.init_data = &pdata->ext_regulator[i]; /* register regulator with framework */ - info->rdev = devm_regulator_register(&pdev->dev, &info->desc, - &config); - if (IS_ERR(info->rdev)) { - err = PTR_ERR(info->rdev); + rdev = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); - return err; + return PTR_ERR(rdev); } - dev_dbg(rdev_get_dev(info->rdev), - "%s-probed\n", info->desc.name); + dev_dbg(&pdev->dev, "%s-probed\n", info->desc.name); } return 0; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 83dba3fbfe0c..efb2f01a9101 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * - * License Terms: GNU General Public License v2 - * * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson * Daniel Willerud <daniel.willerud@stericsson.com> for ST-Ericsson @@ -44,7 +43,6 @@ struct ab8500_shared_mode { * struct ab8500_regulator_info - ab8500 regulator information * @dev: device pointer * @desc: regulator description - * @regulator_dev: regulator device * @shared_mode: used when mode is shared between two regulators * @load_lp_uA: maximum load in idle (low power) mode * @update_bank: bank to control on/off @@ -65,7 +63,6 @@ struct ab8500_shared_mode { struct ab8500_regulator_info { struct device *dev; struct regulator_desc desc; - struct regulator_dev *regulator; struct ab8500_shared_mode *shared_mode; int load_lp_uA; u8 update_bank; @@ -510,7 +507,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, return ret; } -static struct regulator_ops ab8500_regulator_volt_mode_ops = { +static const struct regulator_ops ab8500_regulator_volt_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -522,7 +519,7 @@ static struct regulator_ops ab8500_regulator_volt_mode_ops = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_volt_ops = { +static const struct regulator_ops ab8500_regulator_volt_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -531,7 +528,7 @@ static struct regulator_ops ab8500_regulator_volt_ops = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_mode_ops = { +static const struct regulator_ops ab8500_regulator_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -541,14 +538,14 @@ static struct regulator_ops ab8500_regulator_mode_ops = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_ops = { +static const struct regulator_ops ab8500_regulator_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_anamic_mode_ops = { +static const struct regulator_ops ab8500_regulator_anamic_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -1600,6 +1597,7 @@ static int ab8500_regulator_register(struct platform_device *pdev, struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_regulator_info *info = NULL; struct regulator_config config = { }; + struct regulator_dev *rdev; /* assign per-regulator data */ info = &abx500_regulator.info[id]; @@ -1621,12 +1619,11 @@ static int ab8500_regulator_register(struct platform_device *pdev, } /* register regulator with framework */ - info->regulator = devm_regulator_register(&pdev->dev, &info->desc, - &config); - if (IS_ERR(info->regulator)) { + rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); + if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); - return PTR_ERR(info->regulator); + return PTR_ERR(rdev); } return 0; diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 21e20483bd91..cf72d7c6b8c9 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * act8865-regulator.c - Voltage regulation for active-semi ACT88xx PMUs * * http://www.active-semi.com/products/power-management-units/act88xx/ * * Copyright (C) 2013 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> @@ -131,7 +122,7 @@ * ACT8865 voltage number */ #define ACT8865_VOLTAGE_NUM 64 -#define ACT8600_SUDCDC_VOLTAGE_NUM 255 +#define ACT8600_SUDCDC_VOLTAGE_NUM 256 struct act8865 { struct regmap *regmap; @@ -222,10 +213,11 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(3000000, 0, 63, 0), REGULATOR_LINEAR_RANGE(3000000, 64, 159, 100000), REGULATOR_LINEAR_RANGE(12600000, 160, 191, 200000), - REGULATOR_LINEAR_RANGE(19000000, 191, 255, 400000), + REGULATOR_LINEAR_RANGE(19000000, 192, 247, 400000), + REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0), }; -static struct regulator_ops act8865_ops = { +static const struct regulator_ops act8865_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -235,7 +227,7 @@ static struct regulator_ops act8865_ops = { .is_enabled = regulator_is_enabled_regmap, }; -static struct regulator_ops act8865_ldo_ops = { +static const struct regulator_ops act8865_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -244,6 +236,8 @@ static struct regulator_ops act8865_ldo_ops = { #define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \ [_family##_ID_##_id] = { \ .name = _name, \ + .of_match = of_match_ptr(_name), \ + .regulators_node = of_match_ptr("regulators"), \ .supply_name = _supply, \ .id = _family##_ID_##_id, \ .type = REGULATOR_VOLTAGE, \ @@ -264,6 +258,8 @@ static const struct regulator_desc act8600_regulators[] = { ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET, "vp3"), { .name = "SUDCDC_REG4", + .of_match = of_match_ptr("SUDCDC_REG4"), + .regulators_node = of_match_ptr("regulators"), .id = ACT8600_ID_SUDCDC4, .ops = &act8865_ops, .type = REGULATOR_VOLTAGE, @@ -282,6 +278,8 @@ static const struct regulator_desc act8600_regulators[] = { ACT88xx_REG("LDO8", ACT8600, LDO8, VSET, "inl"), { .name = "LDO_REG9", + .of_match = of_match_ptr("LDO_REG9"), + .regulators_node = of_match_ptr("regulators"), .id = ACT8600_ID_LDO9, .ops = &act8865_ldo_ops, .type = REGULATOR_VOLTAGE, @@ -293,6 +291,8 @@ static const struct regulator_desc act8600_regulators[] = { }, { .name = "LDO_REG10", + .of_match = of_match_ptr("LDO_REG10"), + .regulators_node = of_match_ptr("regulators"), .id = ACT8600_ID_LDO10, .ops = &act8865_ldo_ops, .type = REGULATOR_VOLTAGE, @@ -347,110 +347,6 @@ static const struct of_device_id act8865_dt_ids[] = { { } }; MODULE_DEVICE_TABLE(of, act8865_dt_ids); - -static struct of_regulator_match act8846_matches[] = { - [ACT8846_ID_REG1] = { .name = "REG1" }, - [ACT8846_ID_REG2] = { .name = "REG2" }, - [ACT8846_ID_REG3] = { .name = "REG3" }, - [ACT8846_ID_REG4] = { .name = "REG4" }, - [ACT8846_ID_REG5] = { .name = "REG5" }, - [ACT8846_ID_REG6] = { .name = "REG6" }, - [ACT8846_ID_REG7] = { .name = "REG7" }, - [ACT8846_ID_REG8] = { .name = "REG8" }, - [ACT8846_ID_REG9] = { .name = "REG9" }, - [ACT8846_ID_REG10] = { .name = "REG10" }, - [ACT8846_ID_REG11] = { .name = "REG11" }, - [ACT8846_ID_REG12] = { .name = "REG12" }, -}; - -static struct of_regulator_match act8865_matches[] = { - [ACT8865_ID_DCDC1] = { .name = "DCDC_REG1"}, - [ACT8865_ID_DCDC2] = { .name = "DCDC_REG2"}, - [ACT8865_ID_DCDC3] = { .name = "DCDC_REG3"}, - [ACT8865_ID_LDO1] = { .name = "LDO_REG1"}, - [ACT8865_ID_LDO2] = { .name = "LDO_REG2"}, - [ACT8865_ID_LDO3] = { .name = "LDO_REG3"}, - [ACT8865_ID_LDO4] = { .name = "LDO_REG4"}, -}; - -static struct of_regulator_match act8600_matches[] = { - [ACT8600_ID_DCDC1] = { .name = "DCDC_REG1"}, - [ACT8600_ID_DCDC2] = { .name = "DCDC_REG2"}, - [ACT8600_ID_DCDC3] = { .name = "DCDC_REG3"}, - [ACT8600_ID_SUDCDC4] = { .name = "SUDCDC_REG4"}, - [ACT8600_ID_LDO5] = { .name = "LDO_REG5"}, - [ACT8600_ID_LDO6] = { .name = "LDO_REG6"}, - [ACT8600_ID_LDO7] = { .name = "LDO_REG7"}, - [ACT8600_ID_LDO8] = { .name = "LDO_REG8"}, - [ACT8600_ID_LDO9] = { .name = "LDO_REG9"}, - [ACT8600_ID_LDO10] = { .name = "LDO_REG10"}, -}; - -static int act8865_pdata_from_dt(struct device *dev, - struct act8865_platform_data *pdata, - unsigned long type) -{ - int matched, i, num_matches; - struct device_node *np; - struct act8865_regulator_data *regulator; - struct of_regulator_match *matches; - - switch (type) { - case ACT8600: - matches = act8600_matches; - num_matches = ARRAY_SIZE(act8600_matches); - break; - case ACT8846: - matches = act8846_matches; - num_matches = ARRAY_SIZE(act8846_matches); - break; - case ACT8865: - matches = act8865_matches; - num_matches = ARRAY_SIZE(act8865_matches); - break; - default: - dev_err(dev, "invalid device id %lu\n", type); - return -EINVAL; - } - - np = of_get_child_by_name(dev->of_node, "regulators"); - if (!np) { - dev_err(dev, "missing 'regulators' subnode in DT\n"); - return -EINVAL; - } - - matched = of_regulator_match(dev, np, matches, num_matches); - of_node_put(np); - if (matched <= 0) - return matched; - - pdata->regulators = devm_kcalloc(dev, - num_matches, - sizeof(struct act8865_regulator_data), - GFP_KERNEL); - if (!pdata->regulators) - return -ENOMEM; - - pdata->num_regulators = num_matches; - regulator = pdata->regulators; - - for (i = 0; i < num_matches; i++) { - regulator->id = i; - regulator->name = matches[i].name; - regulator->init_data = matches[i].init_data; - regulator->of_node = matches[i].of_node; - regulator++; - } - - return 0; -} -#else -static inline int act8865_pdata_from_dt(struct device *dev, - struct act8865_platform_data *pdata, - unsigned long type) -{ - return 0; -} #endif static struct act8865_regulator_data *act8865_get_regulator_data( @@ -458,9 +354,6 @@ static struct act8865_regulator_data *act8865_get_regulator_data( { int i; - if (!pdata) - return NULL; - for (i = 0; i < pdata->num_regulators; i++) { if (pdata->regulators[i].id == id) return &pdata->regulators[i]; @@ -483,7 +376,7 @@ static int act8865_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { const struct regulator_desc *regulators; - struct act8865_platform_data pdata_of, *pdata; + struct act8865_platform_data *pdata = NULL; struct device *dev = &client->dev; int i, ret, num_regulators; struct act8865 *act8865; @@ -492,9 +385,7 @@ static int act8865_pmic_probe(struct i2c_client *client, int off_reg, off_mask; int voltage_select = 0; - pdata = dev_get_platdata(dev); - - if (dev->of_node && !pdata) { + if (dev->of_node) { const struct of_device_id *id; id = of_match_device(of_match_ptr(act8865_dt_ids), dev); @@ -508,6 +399,7 @@ static int act8865_pmic_probe(struct i2c_client *client, NULL); } else { type = i2c_id->driver_data; + pdata = dev_get_platdata(dev); } switch (type) { @@ -542,14 +434,6 @@ static int act8865_pmic_probe(struct i2c_client *client, return -EINVAL; } - if (dev->of_node && !pdata) { - ret = act8865_pdata_from_dt(dev, &pdata_of, type); - if (ret < 0) - return ret; - - pdata = &pdata_of; - } - act8865 = devm_kzalloc(dev, sizeof(struct act8865), GFP_KERNEL); if (!act8865) return -ENOMEM; @@ -576,17 +460,20 @@ static int act8865_pmic_probe(struct i2c_client *client, for (i = 0; i < num_regulators; i++) { const struct regulator_desc *desc = ®ulators[i]; struct regulator_config config = { }; - struct act8865_regulator_data *rdata; struct regulator_dev *rdev; config.dev = dev; config.driver_data = act8865; config.regmap = act8865->regmap; - rdata = act8865_get_regulator_data(desc->id, pdata); - if (rdata) { - config.init_data = rdata->init_data; - config.of_node = rdata->of_node; + if (pdata) { + struct act8865_regulator_data *rdata; + + rdata = act8865_get_regulator_data(desc->id, pdata); + if (rdata) { + config.init_data = rdata->init_data; + config.of_node = rdata->of_node; + } } rdev = devm_regulator_register(dev, desc, &config); diff --git a/drivers/regulator/act8945a-regulator.c b/drivers/regulator/act8945a-regulator.c index 603db77723b6..584284938ac9 100644 --- a/drivers/regulator/act8945a-regulator.c +++ b/drivers/regulator/act8945a-regulator.c @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Voltage regulation driver for active-semi ACT8945A PMIC * * Copyright (C) 2015 Atmel Corporation * * Author: Wenyou Yang <wenyou.yang@atmel.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * */ #include <linux/module.h> @@ -87,7 +82,8 @@ static const struct regulator_linear_range act8945a_voltage_ranges[] = { static int act8945a_set_suspend_state(struct regulator_dev *rdev, bool enable) { struct regmap *regmap = rdev->regmap; - int id = rdev->desc->id, reg, val; + int id = rdev_get_id(rdev); + int reg, val; switch (id) { case ACT8945A_ID_DCDC1: @@ -159,7 +155,7 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct act8945a_pmic *act8945a = rdev_get_drvdata(rdev); struct regmap *regmap = rdev->regmap; - int id = rdev->desc->id; + int id = rdev_get_id(rdev); int reg, ret, val = 0; switch (id) { @@ -190,11 +186,11 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode) switch (mode) { case REGULATOR_MODE_STANDBY: - if (rdev->desc->id > ACT8945A_ID_DCDC3) + if (id > ACT8945A_ID_DCDC3) val = BIT(5); break; case REGULATOR_MODE_NORMAL: - if (rdev->desc->id <= ACT8945A_ID_DCDC3) + if (id <= ACT8945A_ID_DCDC3) val = BIT(5); break; default: @@ -213,7 +209,7 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode) static unsigned int act8945a_get_mode(struct regulator_dev *rdev) { struct act8945a_pmic *act8945a = rdev_get_drvdata(rdev); - int id = rdev->desc->id; + int id = rdev_get_id(rdev); if (id < ACT8945A_ID_DCDC1 || id >= ACT8945A_ID_MAX) return -EINVAL; diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index 11c1f880b7bb..75f432f61e91 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -1,11 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Voltage and current regulation for AD5398 and AD5821 * * Copyright 2010 Analog Devices Inc. * * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. */ #include <linux/module.h> diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index d9d8155ed8cb..754739d004e5 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -23,18 +23,10 @@ #define LDO_FET_FULL_ON 0x1f struct anatop_regulator { - u32 control_reg; - struct regmap *anatop; - int vol_bit_shift; - int vol_bit_width; u32 delay_reg; int delay_bit_shift; int delay_bit_width; - int min_bit_val; - int min_voltage; - int max_voltage; struct regulator_desc rdesc; - struct regulator_init_data *initdata; bool bypass; int sel; }; @@ -55,7 +47,7 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, * to calculate how many steps LDO need to * ramp up, and how much delay needed. (us) */ - regmap_read(anatop_reg->anatop, anatop_reg->delay_reg, &val); + regmap_read(reg->regmap, anatop_reg->delay_reg, &val); val = (val >> anatop_reg->delay_bit_shift) & ((1 << anatop_reg->delay_bit_width) - 1); ret = (new_sel - old_sel) * (LDO_RAMP_UP_UNIT_IN_CYCLES << @@ -170,6 +162,13 @@ static int anatop_regulator_probe(struct platform_device *pdev) struct anatop_regulator *sreg; struct regulator_init_data *initdata; struct regulator_config config = { }; + struct regmap *regmap; + u32 control_reg; + u32 vol_bit_shift; + u32 vol_bit_width; + u32 min_bit_val; + u32 min_voltage; + u32 max_voltage; int ret = 0; u32 val; @@ -192,48 +191,41 @@ static int anatop_regulator_probe(struct platform_device *pdev) return -ENOMEM; initdata->supply_regulator = "vin"; - sreg->initdata = initdata; anatop_np = of_get_parent(np); if (!anatop_np) return -ENODEV; - sreg->anatop = syscon_node_to_regmap(anatop_np); + regmap = syscon_node_to_regmap(anatop_np); of_node_put(anatop_np); - if (IS_ERR(sreg->anatop)) - return PTR_ERR(sreg->anatop); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); - ret = of_property_read_u32(np, "anatop-reg-offset", - &sreg->control_reg); + ret = of_property_read_u32(np, "anatop-reg-offset", &control_reg); if (ret) { dev_err(dev, "no anatop-reg-offset property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-vol-bit-width", - &sreg->vol_bit_width); + ret = of_property_read_u32(np, "anatop-vol-bit-width", &vol_bit_width); if (ret) { dev_err(dev, "no anatop-vol-bit-width property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-vol-bit-shift", - &sreg->vol_bit_shift); + ret = of_property_read_u32(np, "anatop-vol-bit-shift", &vol_bit_shift); if (ret) { dev_err(dev, "no anatop-vol-bit-shift property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-min-bit-val", - &sreg->min_bit_val); + ret = of_property_read_u32(np, "anatop-min-bit-val", &min_bit_val); if (ret) { dev_err(dev, "no anatop-min-bit-val property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-min-voltage", - &sreg->min_voltage); + ret = of_property_read_u32(np, "anatop-min-voltage", &min_voltage); if (ret) { dev_err(dev, "no anatop-min-voltage property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-max-voltage", - &sreg->max_voltage); + ret = of_property_read_u32(np, "anatop-max-voltage", &max_voltage); if (ret) { dev_err(dev, "no anatop-max-voltage property set\n"); return ret; @@ -247,24 +239,23 @@ static int anatop_regulator_probe(struct platform_device *pdev) of_property_read_u32(np, "anatop-delay-bit-shift", &sreg->delay_bit_shift); - rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1 - + sreg->min_bit_val; - rdesc->min_uV = sreg->min_voltage; + rdesc->n_voltages = (max_voltage - min_voltage) / 25000 + 1 + + min_bit_val; + rdesc->min_uV = min_voltage; rdesc->uV_step = 25000; - rdesc->linear_min_sel = sreg->min_bit_val; - rdesc->vsel_reg = sreg->control_reg; - rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) << - sreg->vol_bit_shift; + rdesc->linear_min_sel = min_bit_val; + rdesc->vsel_reg = control_reg; + rdesc->vsel_mask = ((1 << vol_bit_width) - 1) << vol_bit_shift; rdesc->min_dropout_uV = 125000; config.dev = &pdev->dev; config.init_data = initdata; config.driver_data = sreg; config.of_node = pdev->dev.of_node; - config.regmap = sreg->anatop; + config.regmap = regmap; /* Only core regulators have the ramp up delay configuration. */ - if (sreg->control_reg && sreg->delay_bit_width) { + if (control_reg && sreg->delay_bit_width) { rdesc->ops = &anatop_core_rops; ret = regmap_read(config.regmap, rdesc->vsel_reg, &val); @@ -273,7 +264,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) return ret; } - sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift; + sreg->sel = (val & rdesc->vsel_mask) >> vol_bit_shift; if (sreg->sel == LDO_FET_FULL_ON) { sreg->sel = 0; sreg->bypass = true; @@ -306,7 +297,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) anatop_rops.disable = regulator_disable_regmap; anatop_rops.is_enabled = regulator_is_enabled_regmap; - rdesc->enable_reg = sreg->control_reg; + rdesc->enable_reg = control_reg; rdesc->enable_mask = BIT(enable_bit); } } diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index b9a93049e41e..e4bc7b1e5ccd 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -1,15 +1,10 @@ -/* - * arizona-ldo1.c -- LDO1 supply for Arizona devices - * - * Copyright 2012 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// arizona-ldo1.c -- LDO1 supply for Arizona devices +// +// Copyright 2012 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -40,35 +35,10 @@ struct arizona_ldo1 { struct gpio_desc *ena_gpiod; }; -static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev, - unsigned int selector) -{ - if (selector >= rdev->desc->n_voltages) - return -EINVAL; - - if (selector == rdev->desc->n_voltages - 1) - return 1800000; - else - return rdev->desc->min_uV + (rdev->desc->uV_step * selector); -} - -static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - int sel; - - sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); - if (sel >= rdev->desc->n_voltages) - sel = rdev->desc->n_voltages - 1; - - return sel; -} - static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) { - struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); - struct regmap *regmap = ldo->regmap; + struct regmap *regmap = rdev_get_regmap(rdev); unsigned int val; int ret; @@ -85,16 +55,12 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, if (val) return 0; - val = sel << ARIZONA_LDO1_VSEL_SHIFT; - - return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1, - ARIZONA_LDO1_VSEL_MASK, val); + return regulator_set_voltage_sel_regmap(rdev, sel); } static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) { - struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); - struct regmap *regmap = ldo->regmap; + struct regmap *regmap = rdev_get_regmap(rdev); unsigned int val; int ret; @@ -105,32 +71,35 @@ static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) if (val & ARIZONA_LDO1_HI_PWR) return rdev->desc->n_voltages - 1; - ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val); - if (ret != 0) - return ret; - - return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT; + return regulator_get_voltage_sel_regmap(rdev); } static const struct regulator_ops arizona_ldo1_hc_ops = { - .list_voltage = arizona_ldo1_hc_list_voltage, - .map_voltage = arizona_ldo1_hc_map_voltage, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = arizona_ldo1_hc_get_voltage_sel, .set_voltage_sel = arizona_ldo1_hc_set_voltage_sel, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; +static const struct regulator_linear_range arizona_ldo1_hc_ranges[] = { + REGULATOR_LINEAR_RANGE(900000, 0, 0x6, 50000), + REGULATOR_LINEAR_RANGE(1800000, 0x7, 0x7, 0), +}; + static const struct regulator_desc arizona_ldo1_hc = { .name = "LDO1", .supply_name = "LDOVDD", .type = REGULATOR_VOLTAGE, .ops = &arizona_ldo1_hc_ops, + .vsel_reg = ARIZONA_LDO1_CONTROL_1, + .vsel_mask = ARIZONA_LDO1_VSEL_MASK, .bypass_reg = ARIZONA_LDO1_CONTROL_1, .bypass_mask = ARIZONA_LDO1_BYPASS, - .min_uV = 900000, - .uV_step = 50000, + .linear_ranges = arizona_ldo1_hc_ranges, + .n_linear_ranges = ARRAY_SIZE(arizona_ldo1_hc_ranges), .n_voltages = 8, .enable_time = 1500, .ramp_delay = 24000, diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 120de94caf02..be0d46da51a1 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -1,15 +1,10 @@ -/* - * arizona-micsupp.c -- Microphone supply for Arizona devices - * - * Copyright 2012 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// arizona-micsupp.c -- Microphone supply for Arizona devices +// +// Copyright 2012 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index f7fe218bb3e4..ece88103f2fd 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -17,14 +17,6 @@ #include <linux/regulator/of_regulator.h> #include <linux/slab.h> -struct as3711_regulator_info { - struct regulator_desc desc; -}; - -struct as3711_regulator { - struct as3711_regulator_info *reg_info; -}; - /* * The regulator API supports 4 modes of operataion: FAST, NORMAL, IDLE and * STANDBY. We map them in the following way to AS3711 SD1-4 DCDC modes: @@ -129,7 +121,6 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = { #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _sfx) \ [AS3711_REGULATOR_ ## _id] = { \ - .desc = { \ .name = "as3711-regulator-" # _id, \ .id = AS3711_REGULATOR_ ## _id, \ .n_voltages = (_vmask + 1), \ @@ -142,10 +133,9 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = { .enable_mask = BIT(_en_bit), \ .linear_ranges = as3711_ ## _sfx ## _ranges, \ .n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \ - }, \ } -static struct as3711_regulator_info as3711_reg_info[] = { +static const struct regulator_desc as3711_reg_desc[] = { AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, sd), AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, sd), AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, sd), @@ -161,7 +151,7 @@ static struct as3711_regulator_info as3711_reg_info[] = { /* StepUp output voltage depends on supplying regulator */ }; -#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info) +#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_desc) static struct of_regulator_match as3711_regulator_matches[AS3711_REGULATOR_NUM] = { @@ -215,11 +205,8 @@ static int as3711_regulator_probe(struct platform_device *pdev) struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = {.dev = &pdev->dev,}; - struct as3711_regulator *reg = NULL; - struct as3711_regulator *regs; struct device_node *of_node[AS3711_REGULATOR_NUM] = {}; struct regulator_dev *rdev; - struct as3711_regulator_info *ri; int ret; int id; @@ -236,30 +223,20 @@ static int as3711_regulator_probe(struct platform_device *pdev) } } - regs = devm_kcalloc(&pdev->dev, - AS3711_REGULATOR_NUM, - sizeof(struct as3711_regulator), - GFP_KERNEL); - if (!regs) - return -ENOMEM; - - for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { - reg = ®s[id]; - reg->reg_info = ri; - + for (id = 0; id < AS3711_REGULATOR_NUM; id++) { config.init_data = pdata->init_data[id]; - config.driver_data = reg; config.regmap = as3711->regmap; config.of_node = of_node[id]; - rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); + rdev = devm_regulator_register(&pdev->dev, &as3711_reg_desc[id], + &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register regulator %s\n", - ri->desc.name); + as3711_reg_desc[id].name); return PTR_ERR(rdev); } } - platform_set_drvdata(pdev, regs); + return 0; } diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 66337e12719b..bd5d0bacb08d 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Voltage regulator support for AMS AS3722 PMIC * @@ -5,21 +6,6 @@ * * Author: Florian Lobmaier <florian.lobmaier@ams.com> * Author: Laxman Dewangan <ldewangan@nvidia.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include <linux/err.h> @@ -81,7 +67,6 @@ struct as3722_regulator_config_data { struct as3722_regulators { struct device *dev; struct as3722 *as3722; - struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX]; struct regulator_desc desc[AS3722_REGULATOR_ID_MAX]; struct as3722_regulator_config_data reg_config_data[AS3722_REGULATOR_ID_MAX]; @@ -314,63 +299,10 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = { }, }; - -static const int as3722_ldo_current[] = { 150000, 300000 }; -static const int as3722_sd016_current[] = { 2500000, 3000000, 3500000 }; - -static int as3722_current_to_index(int min_uA, int max_uA, - const int *curr_table, int n_currents) -{ - int i; - - for (i = n_currents - 1; i >= 0; i--) { - if ((min_uA <= curr_table[i]) && (curr_table[i] <= max_uA)) - return i; - } - return -EINVAL; -} - -static int as3722_ldo_get_current_limit(struct regulator_dev *rdev) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - u32 val; - int ret; - - ret = as3722_read(as3722, as3722_reg_lookup[id].vsel_reg, &val); - if (ret < 0) { - dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n", - as3722_reg_lookup[id].vsel_reg, ret); - return ret; - } - if (val & AS3722_LDO_ILIMIT_MASK) - return 300000; - return 150000; -} - -static int as3722_ldo_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - int ret; - u32 reg = 0; - - ret = as3722_current_to_index(min_uA, max_uA, as3722_ldo_current, - ARRAY_SIZE(as3722_ldo_current)); - if (ret < 0) { - dev_err(as3722_regs->dev, - "Current range min:max = %d:%d does not support\n", - min_uA, max_uA); - return ret; - } - if (ret) - reg = AS3722_LDO_ILIMIT_BIT; - return as3722_update_bits(as3722, as3722_reg_lookup[id].vsel_reg, - AS3722_LDO_ILIMIT_MASK, reg); -} +static const unsigned int as3722_ldo_current[] = { 150000, 300000 }; +static const unsigned int as3722_sd016_current[] = { + 2500000, 3000000, 3500000 +}; static const struct regulator_ops as3722_ldo0_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -379,16 +311,16 @@ static const struct regulator_ops as3722_ldo0_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static const struct regulator_ops as3722_ldo0_extcntrl_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg, @@ -440,8 +372,8 @@ static const struct regulator_ops as3722_ldo6_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; @@ -451,8 +383,8 @@ static const struct regulator_ops as3722_ldo6_extcntrl_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; @@ -471,8 +403,8 @@ static const struct regulator_ops as3722_ldo_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static const struct regulator_ops as3722_ldo_extcntrl_ops = { @@ -480,8 +412,8 @@ static const struct regulator_ops as3722_ldo_extcntrl_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev) @@ -539,85 +471,6 @@ static int as3722_sd_set_mode(struct regulator_dev *rdev, return ret; } -static int as3722_sd016_get_current_limit(struct regulator_dev *rdev) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - u32 val, reg; - int mask; - int ret; - - switch (id) { - case AS3722_REGULATOR_ID_SD0: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD0_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD1: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD1_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD6: - reg = AS3722_OVCURRENT_DEB_REG; - mask = AS3722_OVCURRENT_SD6_TRIP_MASK; - break; - default: - return -EINVAL; - } - ret = as3722_read(as3722, reg, &val); - if (ret < 0) { - dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n", - reg, ret); - return ret; - } - val &= mask; - val >>= ffs(mask) - 1; - if (val == 3) - return -EINVAL; - return as3722_sd016_current[val]; -} - -static int as3722_sd016_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - int ret; - int val; - int mask; - u32 reg; - - ret = as3722_current_to_index(min_uA, max_uA, as3722_sd016_current, - ARRAY_SIZE(as3722_sd016_current)); - if (ret < 0) { - dev_err(as3722_regs->dev, - "Current range min:max = %d:%d does not support\n", - min_uA, max_uA); - return ret; - } - - switch (id) { - case AS3722_REGULATOR_ID_SD0: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD0_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD1: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD1_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD6: - reg = AS3722_OVCURRENT_DEB_REG; - mask = AS3722_OVCURRENT_SD6_TRIP_MASK; - break; - default: - return -EINVAL; - } - ret <<= ffs(mask) - 1; - val = ret & mask; - return as3722_update_bits(as3722, reg, mask, val); -} - static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs) { int err; @@ -649,8 +502,8 @@ static const struct regulator_ops as3722_sd016_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_sd016_get_current_limit, - .set_current_limit = as3722_sd016_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_mode = as3722_sd_get_mode, .set_mode = as3722_sd_set_mode, }; @@ -660,8 +513,8 @@ static const struct regulator_ops as3722_sd016_extcntrl_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_sd016_get_current_limit, - .set_current_limit = as3722_sd016_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_mode = as3722_sd_get_mode, .set_mode = as3722_sd_set_mode, }; @@ -807,42 +660,45 @@ static int as3722_regulator_probe(struct platform_device *pdev) config.regmap = as3722->regmap; for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) { + struct regulator_desc *desc; + + desc = &as3722_regs->desc[id]; reg_config = &as3722_regs->reg_config_data[id]; - as3722_regs->desc[id].name = as3722_reg_lookup[id].name; - as3722_regs->desc[id].supply_name = as3722_reg_lookup[id].sname; - as3722_regs->desc[id].id = as3722_reg_lookup[id].regulator_id; - as3722_regs->desc[id].n_voltages = - as3722_reg_lookup[id].n_voltages; - as3722_regs->desc[id].type = REGULATOR_VOLTAGE; - as3722_regs->desc[id].owner = THIS_MODULE; - as3722_regs->desc[id].enable_reg = - as3722_reg_lookup[id].enable_reg; - as3722_regs->desc[id].enable_mask = - as3722_reg_lookup[id].enable_mask; - as3722_regs->desc[id].vsel_reg = as3722_reg_lookup[id].vsel_reg; - as3722_regs->desc[id].vsel_mask = - as3722_reg_lookup[id].vsel_mask; + desc->name = as3722_reg_lookup[id].name; + desc->supply_name = as3722_reg_lookup[id].sname; + desc->id = as3722_reg_lookup[id].regulator_id; + desc->n_voltages = as3722_reg_lookup[id].n_voltages; + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; + desc->enable_reg = as3722_reg_lookup[id].enable_reg; + desc->enable_mask = as3722_reg_lookup[id].enable_mask; + desc->vsel_reg = as3722_reg_lookup[id].vsel_reg; + desc->vsel_mask = as3722_reg_lookup[id].vsel_mask; switch (id) { case AS3722_REGULATOR_ID_LDO0: if (reg_config->ext_control) ops = &as3722_ldo0_extcntrl_ops; else ops = &as3722_ldo0_ops; - as3722_regs->desc[id].min_uV = 825000; - as3722_regs->desc[id].uV_step = 25000; - as3722_regs->desc[id].linear_min_sel = 1; - as3722_regs->desc[id].enable_time = 500; + desc->min_uV = 825000; + desc->uV_step = 25000; + desc->linear_min_sel = 1; + desc->enable_time = 500; + desc->curr_table = as3722_ldo_current; + desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); + desc->csel_reg = as3722_reg_lookup[id].vsel_reg; + desc->csel_mask = AS3722_LDO_ILIMIT_MASK; break; case AS3722_REGULATOR_ID_LDO3: if (reg_config->ext_control) ops = &as3722_ldo3_extcntrl_ops; else ops = &as3722_ldo3_ops; - as3722_regs->desc[id].min_uV = 620000; - as3722_regs->desc[id].uV_step = 20000; - as3722_regs->desc[id].linear_min_sel = 1; - as3722_regs->desc[id].enable_time = 500; + desc->min_uV = 620000; + desc->uV_step = 20000; + desc->linear_min_sel = 1; + desc->enable_time = 500; if (reg_config->enable_tracking) { ret = as3722_ldo3_set_tracking_mode(as3722_regs, id, AS3722_LDO3_MODE_PMOS_TRACKING); @@ -859,18 +715,17 @@ static int as3722_regulator_probe(struct platform_device *pdev) ops = &as3722_ldo6_extcntrl_ops; else ops = &as3722_ldo6_ops; - as3722_regs->desc[id].enable_time = 500; - as3722_regs->desc[id].bypass_reg = - AS3722_LDO6_VOLTAGE_REG; - as3722_regs->desc[id].bypass_mask = - AS3722_LDO_VSEL_MASK; - as3722_regs->desc[id].bypass_val_on = - AS3722_LDO6_VSEL_BYPASS; - as3722_regs->desc[id].bypass_val_off = - AS3722_LDO6_VSEL_BYPASS; - as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges; - as3722_regs->desc[id].n_linear_ranges = - ARRAY_SIZE(as3722_ldo_ranges); + desc->enable_time = 500; + desc->bypass_reg = AS3722_LDO6_VOLTAGE_REG; + desc->bypass_mask = AS3722_LDO_VSEL_MASK; + desc->bypass_val_on = AS3722_LDO6_VSEL_BYPASS; + desc->bypass_val_off = AS3722_LDO6_VSEL_BYPASS; + desc->linear_ranges = as3722_ldo_ranges; + desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges); + desc->curr_table = as3722_ldo_current; + desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); + desc->csel_reg = as3722_reg_lookup[id].vsel_reg; + desc->csel_mask = AS3722_LDO_ILIMIT_MASK; break; case AS3722_REGULATOR_ID_SD0: case AS3722_REGULATOR_ID_SD1: @@ -886,12 +741,28 @@ static int as3722_regulator_probe(struct platform_device *pdev) as3722_regs->desc[id].min_uV = 410000; } else { as3722_regs->desc[id].n_voltages = - AS3722_SD0_VSEL_MAX + 1, + AS3722_SD0_VSEL_MAX + 1; as3722_regs->desc[id].min_uV = 610000; } - as3722_regs->desc[id].uV_step = 10000; - as3722_regs->desc[id].linear_min_sel = 1; - as3722_regs->desc[id].enable_time = 600; + desc->uV_step = 10000; + desc->linear_min_sel = 1; + desc->enable_time = 600; + desc->curr_table = as3722_sd016_current; + desc->n_current_limits = + ARRAY_SIZE(as3722_sd016_current); + if (id == AS3722_REGULATOR_ID_SD0) { + desc->csel_reg = AS3722_OVCURRENT_REG; + desc->csel_mask = + AS3722_OVCURRENT_SD0_TRIP_MASK; + } else if (id == AS3722_REGULATOR_ID_SD1) { + desc->csel_reg = AS3722_OVCURRENT_REG; + desc->csel_mask = + AS3722_OVCURRENT_SD1_TRIP_MASK; + } else if (id == AS3722_REGULATOR_ID_SD6) { + desc->csel_reg = AS3722_OVCURRENT_DEB_REG; + desc->csel_mask = + AS3722_OVCURRENT_SD6_TRIP_MASK; + } break; case AS3722_REGULATOR_ID_SD2: case AS3722_REGULATOR_ID_SD3: @@ -901,9 +772,8 @@ static int as3722_regulator_probe(struct platform_device *pdev) ops = &as3722_sd2345_extcntrl_ops; else ops = &as3722_sd2345_ops; - as3722_regs->desc[id].linear_ranges = - as3722_sd2345_ranges; - as3722_regs->desc[id].n_linear_ranges = + desc->linear_ranges = as3722_sd2345_ranges; + desc->n_linear_ranges = ARRAY_SIZE(as3722_sd2345_ranges); break; default: @@ -911,17 +781,19 @@ static int as3722_regulator_probe(struct platform_device *pdev) ops = &as3722_ldo_extcntrl_ops; else ops = &as3722_ldo_ops; - as3722_regs->desc[id].enable_time = 500; - as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges; - as3722_regs->desc[id].n_linear_ranges = - ARRAY_SIZE(as3722_ldo_ranges); + desc->enable_time = 500; + desc->linear_ranges = as3722_ldo_ranges; + desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges); + desc->curr_table = as3722_ldo_current; + desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); + desc->csel_reg = as3722_reg_lookup[id].vsel_reg; + desc->csel_mask = AS3722_LDO_ILIMIT_MASK; break; } - as3722_regs->desc[id].ops = ops; + desc->ops = ops; config.init_data = reg_config->reg_init; config.of_node = as3722_regulator_matches[id].of_node; - rdev = devm_regulator_register(&pdev->dev, - &as3722_regs->desc[id], &config); + rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(&pdev->dev, "regulator %d register failed %d\n", @@ -929,7 +801,6 @@ static int as3722_regulator_probe(struct platform_device *pdev) return ret; } - as3722_regs->rdevs[id] = rdev; if (reg_config->ext_control) { ret = regulator_enable_regmap(rdev); if (ret < 0) { diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 48af859fd053..152053361862 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -367,17 +367,14 @@ static const int axp209_dcdc2_ldo3_slew_rates[] = { static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) { struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); - const struct regulator_desc *desc = rdev->desc; + int id = rdev_get_id(rdev); u8 reg, mask, enable, cfg = 0xff; const int *slew_rates; int rate_count = 0; - if (!rdev) - return -EINVAL; - switch (axp20x->variant) { case AXP209_ID: - if (desc->id == AXP20X_DCDC2) { + if (id == AXP20X_DCDC2) { slew_rates = axp209_dcdc2_ldo3_slew_rates; rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates); reg = AXP20X_DCDC2_LDO3_V_RAMP; @@ -389,7 +386,7 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) break; } - if (desc->id == AXP20X_LDO3) { + if (id == AXP20X_LDO3) { slew_rates = axp209_dcdc2_ldo3_slew_rates; rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates); reg = AXP20X_DCDC2_LDO3_V_RAMP; @@ -436,14 +433,11 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) static int axp20x_regulator_enable_regmap(struct regulator_dev *rdev) { struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); - const struct regulator_desc *desc = rdev->desc; - - if (!rdev) - return -EINVAL; + int id = rdev_get_id(rdev); switch (axp20x->variant) { case AXP209_ID: - if ((desc->id == AXP20X_LDO3) && + if ((id == AXP20X_LDO3) && rdev->constraints && rdev->constraints->soft_start) { int v_out; int ret; @@ -573,7 +567,7 @@ static const struct regulator_desc axp22x_regulators[] = { AXP22X_DCDC3_V_OUT, AXP22X_DCDC3_V_OUT_MASK, AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC3_MASK), AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20, - AXP22X_DCDC4_V_OUT, AXP22X_DCDC4_V_OUT, + AXP22X_DCDC4_V_OUT, AXP22X_DCDC4_V_OUT_MASK, AXP22X_PWR_OUT_CTRL1, AXP22X_PWR_OUT_DCDC4_MASK), AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50, AXP22X_DCDC5_V_OUT, AXP22X_DCDC5_V_OUT_MASK, @@ -719,7 +713,7 @@ static const struct regulator_desc axp803_regulators[] = { AXP22X_ALDO1_V_OUT, AXP22X_ALDO1_V_OUT_MASK, AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO1_MASK), AXP_DESC(AXP803, ALDO2, "aldo2", "aldoin", 700, 3300, 100, - AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT, + AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO2_MASK), AXP_DESC(AXP803, ALDO3, "aldo3", "aldoin", 700, 3300, 100, AXP22X_ALDO3_V_OUT, AXP22X_ALDO3_V_OUT_MASK, @@ -729,7 +723,7 @@ static const struct regulator_desc axp803_regulators[] = { AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK), AXP_DESC_RANGES(AXP803, DLDO2, "dldo2", "dldoin", axp803_dldo2_ranges, AXP803_DLDO2_NUM_VOLTAGES, - AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT, + AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK), AXP_DESC(AXP803, DLDO3, "dldo3", "dldoin", 700, 3300, 100, AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK, @@ -744,7 +738,7 @@ static const struct regulator_desc axp803_regulators[] = { AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK), AXP_DESC(AXP803, ELDO3, "eldo3", "eldoin", 700, 1900, 50, - AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT, + AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK), AXP_DESC(AXP803, FLDO1, "fldo1", "fldoin", 700, 1450, 50, AXP803_FLDO1_V_OUT, AXP803_FLDO1_V_OUT_MASK, @@ -791,7 +785,7 @@ static const struct regulator_desc axp806_regulators[] = { AXP806_DCDCA_V_CTRL, AXP806_DCDCA_V_CTRL_MASK, AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCA_MASK), AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50, - AXP806_DCDCB_V_CTRL, AXP806_DCDCB_V_CTRL, + AXP806_DCDCB_V_CTRL, AXP806_DCDCB_V_CTRL_MASK, AXP806_PWR_OUT_CTRL1, AXP806_PWR_OUT_DCDCB_MASK), AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc", axp806_dcdca_ranges, AXP806_DCDCA_NUM_VOLTAGES, @@ -817,7 +811,7 @@ static const struct regulator_desc axp806_regulators[] = { AXP806_BLDO1_V_CTRL, AXP806_BLDO1_V_CTRL_MASK, AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_BLDO1_MASK), AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100, - AXP806_BLDO2_V_CTRL, AXP806_BLDO2_V_CTRL, + AXP806_BLDO2_V_CTRL, AXP806_BLDO2_V_CTRL_MASK, AXP806_PWR_OUT_CTRL2, AXP806_PWR_OUT_BLDO2_MASK), AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100, AXP806_BLDO3_V_CTRL, AXP806_BLDO3_V_CTRL_MASK, @@ -952,7 +946,7 @@ static const struct regulator_desc axp813_regulators[] = { AXP22X_ALDO1_V_OUT, AXP22X_ALDO1_V_OUT_MASK, AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO1_MASK), AXP_DESC(AXP813, ALDO2, "aldo2", "aldoin", 700, 3300, 100, - AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT, + AXP22X_ALDO2_V_OUT, AXP22X_ALDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL3, AXP806_PWR_OUT_ALDO2_MASK), AXP_DESC(AXP813, ALDO3, "aldo3", "aldoin", 700, 3300, 100, AXP22X_ALDO3_V_OUT, AXP22X_ALDO3_V_OUT_MASK, @@ -962,7 +956,7 @@ static const struct regulator_desc axp813_regulators[] = { AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK), AXP_DESC_RANGES(AXP813, DLDO2, "dldo2", "dldoin", axp803_dldo2_ranges, AXP803_DLDO2_NUM_VOLTAGES, - AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT, + AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK), AXP_DESC(AXP813, DLDO3, "dldo3", "dldoin", 700, 3300, 100, AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK, @@ -977,7 +971,7 @@ static const struct regulator_desc axp813_regulators[] = { AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK), AXP_DESC(AXP813, ELDO3, "eldo3", "eldoin", 700, 1900, 50, - AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT, + AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK), /* to do / check ... */ AXP_DESC(AXP813, FLDO1, "fldo1", "fldoin", 700, 1450, 50, @@ -1027,7 +1021,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) * (See include/linux/mfd/axp20x.h) */ reg = AXP803_DCDC_FREQ_CTRL; - /* Fall through to the check below.*/ + /* Fall through - to the check below.*/ case AXP806_ID: /* * AXP806 also have DCDC work frequency setting register at a @@ -1118,12 +1112,12 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work break; case AXP806_ID: - reg = AXP806_DCDC_MODE_CTRL2; /* * AXP806 DCDC regulator IDs have the same range as AXP22X. - * Fall through to the check below. * (See include/linux/mfd/axp20x.h) */ + reg = AXP806_DCDC_MODE_CTRL2; + /* Fall through - to the check below. */ case AXP221_ID: case AXP223_ID: case AXP809_ID: diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 92d6d7b10cf7..8c98c3f07660 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Broadcom BCM590xx regulator driver * * Copyright 2014 Linaro Limited * Author: Matt Porter <mporter@linaro.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/err.h> @@ -103,10 +99,6 @@ ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS)) #define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS) -struct bcm590xx_board { - struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS]; -}; - /* LDO group A: supported voltages in microvolts */ static const unsigned int ldo_a_table[] = { 1200000, 1800000, 2500000, 2700000, 2800000, @@ -242,8 +234,12 @@ static int bcm590xx_get_enable_register(int id) case BCM590XX_REG_SDSR2: reg = BCM590XX_SDSR2PMCTRL1; break; + case BCM590XX_REG_VSR: + reg = BCM590XX_VSRPMCTRL1; + break; case BCM590XX_REG_VBUS: reg = BCM590XX_OTG_CTRL; + break; } @@ -276,105 +272,15 @@ static const struct regulator_ops bcm590xx_ops_vbus = { .disable = regulator_disable_regmap, }; -#define BCM590XX_MATCH(_name, _id) \ - { \ - .name = #_name, \ - .driver_data = (void *)&bcm590xx_regs[BCM590XX_REG_##_id], \ - } - -static struct of_regulator_match bcm590xx_matches[] = { - BCM590XX_MATCH(rfldo, RFLDO), - BCM590XX_MATCH(camldo1, CAMLDO1), - BCM590XX_MATCH(camldo2, CAMLDO2), - BCM590XX_MATCH(simldo1, SIMLDO1), - BCM590XX_MATCH(simldo2, SIMLDO2), - BCM590XX_MATCH(sdldo, SDLDO), - BCM590XX_MATCH(sdxldo, SDXLDO), - BCM590XX_MATCH(mmcldo1, MMCLDO1), - BCM590XX_MATCH(mmcldo2, MMCLDO2), - BCM590XX_MATCH(audldo, AUDLDO), - BCM590XX_MATCH(micldo, MICLDO), - BCM590XX_MATCH(usbldo, USBLDO), - BCM590XX_MATCH(vibldo, VIBLDO), - BCM590XX_MATCH(csr, CSR), - BCM590XX_MATCH(iosr1, IOSR1), - BCM590XX_MATCH(iosr2, IOSR2), - BCM590XX_MATCH(msr, MSR), - BCM590XX_MATCH(sdsr1, SDSR1), - BCM590XX_MATCH(sdsr2, SDSR2), - BCM590XX_MATCH(vsr, VSR), - BCM590XX_MATCH(gpldo1, GPLDO1), - BCM590XX_MATCH(gpldo2, GPLDO2), - BCM590XX_MATCH(gpldo3, GPLDO3), - BCM590XX_MATCH(gpldo4, GPLDO4), - BCM590XX_MATCH(gpldo5, GPLDO5), - BCM590XX_MATCH(gpldo6, GPLDO6), - BCM590XX_MATCH(vbus, VBUS), -}; - -static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( - struct platform_device *pdev, - struct of_regulator_match **bcm590xx_reg_matches) -{ - struct bcm590xx_board *data; - struct device_node *np = pdev->dev.parent->of_node; - struct device_node *regulators; - struct of_regulator_match *matches = bcm590xx_matches; - int count = ARRAY_SIZE(bcm590xx_matches); - int idx = 0; - int ret; - - if (!np) { - dev_err(&pdev->dev, "of node not found\n"); - return NULL; - } - - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) - return NULL; - - np = of_node_get(np); - regulators = of_get_child_by_name(np, "regulators"); - if (!regulators) { - dev_warn(&pdev->dev, "regulator node not found\n"); - return NULL; - } - - ret = of_regulator_match(&pdev->dev, regulators, matches, count); - of_node_put(regulators); - if (ret < 0) { - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", - ret); - return NULL; - } - - *bcm590xx_reg_matches = matches; - - for (idx = 0; idx < count; idx++) { - if (!matches[idx].init_data || !matches[idx].of_node) - continue; - - data->bcm590xx_pmu_init_data[idx] = matches[idx].init_data; - } - - return data; -} - static int bcm590xx_probe(struct platform_device *pdev) { struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent); - struct bcm590xx_board *pmu_data = NULL; struct bcm590xx_reg *pmu; struct regulator_config config = { }; struct bcm590xx_info *info; - struct regulator_init_data *reg_data; struct regulator_dev *rdev; - struct of_regulator_match *bcm590xx_reg_matches = NULL; int i; - pmu_data = bcm590xx_parse_dt_reg_data(pdev, - &bcm590xx_reg_matches); - pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); if (!pmu) return -ENOMEM; @@ -393,13 +299,10 @@ static int bcm590xx_probe(struct platform_device *pdev) info = bcm590xx_regs; for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { - if (pmu_data) - reg_data = pmu_data->bcm590xx_pmu_init_data[i]; - else - reg_data = NULL; - /* Register the regulators */ pmu->desc[i].name = info->name; + pmu->desc[i].of_match = of_match_ptr(info->name); + pmu->desc[i].regulators_node = of_match_ptr("regulators"); pmu->desc[i].supply_name = info->vin_name; pmu->desc[i].id = i; pmu->desc[i].volt_table = info->volt_table; @@ -429,16 +332,12 @@ static int bcm590xx_probe(struct platform_device *pdev) pmu->desc[i].owner = THIS_MODULE; config.dev = bcm590xx->dev; - config.init_data = reg_data; config.driver_data = pmu; if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i)) config.regmap = bcm590xx->regmap_sec; else config.regmap = bcm590xx->regmap_pri; - if (bcm590xx_reg_matches) - config.of_node = bcm590xx_reg_matches[i].of_node; - rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i], &config); if (IS_ERR(rdev)) { diff --git a/drivers/regulator/bd70528-regulator.c b/drivers/regulator/bd70528-regulator.c new file mode 100644 index 000000000000..30e3ed430a8a --- /dev/null +++ b/drivers/regulator/bd70528-regulator.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 ROHM Semiconductors +// bd70528-regulator.c ROHM BD70528MWV regulator driver + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/mfd/rohm-bd70528.h> +#include <linux/module.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/slab.h> + +#define BUCK_RAMPRATE_250MV 0 +#define BUCK_RAMPRATE_125MV 1 +#define BUCK_RAMP_MAX 250 + +static const struct regulator_linear_range bd70528_buck1_volts[] = { + REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000), + REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000), +}; +static const struct regulator_linear_range bd70528_buck2_volts[] = { + REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000), + REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000), + REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000), +}; +static const struct regulator_linear_range bd70528_buck3_volts[] = { + REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000), + REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0), +}; + +/* All LDOs have same voltage ranges */ +static const struct regulator_linear_range bd70528_ldo_volts[] = { + REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000), + REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000), + REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000), + REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0), +}; + +/* Also both LEDs support same voltages */ +static const unsigned int led_volts[] = { + 20000, 30000 +}; + +static int bd70528_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) +{ + if (ramp_delay > 0 && ramp_delay <= BUCK_RAMP_MAX) { + unsigned int ramp_value = BUCK_RAMPRATE_250MV; + + if (ramp_delay <= 125) + ramp_value = BUCK_RAMPRATE_125MV; + + return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, + BD70528_MASK_BUCK_RAMP, + ramp_value << BD70528_SIFT_BUCK_RAMP); + } + dev_err(&rdev->dev, "%s: ramp_delay: %d not supported\n", + rdev->desc->name, ramp_delay); + return -EINVAL; +} + +static int bd70528_led_set_voltage_sel(struct regulator_dev *rdev, + unsigned int sel) +{ + int ret; + + ret = regulator_is_enabled_regmap(rdev); + if (ret < 0) + return ret; + + if (ret == 0) + return regulator_set_voltage_sel_regmap(rdev, sel); + + dev_err(&rdev->dev, + "LED voltage change not allowed when led is enabled\n"); + + return -EBUSY; +} + +static const struct regulator_ops bd70528_buck_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = bd70528_set_ramp_delay, +}; + +static const struct regulator_ops bd70528_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = bd70528_set_ramp_delay, +}; + +static const struct regulator_ops bd70528_led_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_table, + .set_voltage_sel = bd70528_led_set_voltage_sel, + .get_voltage_sel = regulator_get_voltage_sel_regmap, +}; + +static const struct regulator_desc bd70528_desc[] = { + { + .name = "buck1", + .of_match = of_match_ptr("BUCK1"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_BUCK1, + .ops = &bd70528_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd70528_buck1_volts, + .n_linear_ranges = ARRAY_SIZE(bd70528_buck1_volts), + .n_voltages = BD70528_BUCK_VOLTS, + .enable_reg = BD70528_REG_BUCK1_EN, + .enable_mask = BD70528_MASK_RUN_EN, + .vsel_reg = BD70528_REG_BUCK1_VOLT, + .vsel_mask = BD70528_MASK_BUCK_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "buck2", + .of_match = of_match_ptr("BUCK2"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_BUCK2, + .ops = &bd70528_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd70528_buck2_volts, + .n_linear_ranges = ARRAY_SIZE(bd70528_buck2_volts), + .n_voltages = BD70528_BUCK_VOLTS, + .enable_reg = BD70528_REG_BUCK2_EN, + .enable_mask = BD70528_MASK_RUN_EN, + .vsel_reg = BD70528_REG_BUCK2_VOLT, + .vsel_mask = BD70528_MASK_BUCK_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "buck3", + .of_match = of_match_ptr("BUCK3"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_BUCK3, + .ops = &bd70528_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd70528_buck3_volts, + .n_linear_ranges = ARRAY_SIZE(bd70528_buck3_volts), + .n_voltages = BD70528_BUCK_VOLTS, + .enable_reg = BD70528_REG_BUCK3_EN, + .enable_mask = BD70528_MASK_RUN_EN, + .vsel_reg = BD70528_REG_BUCK3_VOLT, + .vsel_mask = BD70528_MASK_BUCK_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "ldo1", + .of_match = of_match_ptr("LDO1"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_LDO1, + .ops = &bd70528_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd70528_ldo_volts, + .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts), + .n_voltages = BD70528_LDO_VOLTS, + .enable_reg = BD70528_REG_LDO1_EN, + .enable_mask = BD70528_MASK_RUN_EN, + .vsel_reg = BD70528_REG_LDO1_VOLT, + .vsel_mask = BD70528_MASK_LDO_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "ldo2", + .of_match = of_match_ptr("LDO2"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_LDO2, + .ops = &bd70528_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd70528_ldo_volts, + .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts), + .n_voltages = BD70528_LDO_VOLTS, + .enable_reg = BD70528_REG_LDO2_EN, + .enable_mask = BD70528_MASK_RUN_EN, + .vsel_reg = BD70528_REG_LDO2_VOLT, + .vsel_mask = BD70528_MASK_LDO_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "ldo3", + .of_match = of_match_ptr("LDO3"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_LDO3, + .ops = &bd70528_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd70528_ldo_volts, + .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts), + .n_voltages = BD70528_LDO_VOLTS, + .enable_reg = BD70528_REG_LDO3_EN, + .enable_mask = BD70528_MASK_RUN_EN, + .vsel_reg = BD70528_REG_LDO3_VOLT, + .vsel_mask = BD70528_MASK_LDO_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "ldo_led1", + .of_match = of_match_ptr("LDO_LED1"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_LED1, + .ops = &bd70528_led_ops, + .type = REGULATOR_VOLTAGE, + .volt_table = &led_volts[0], + .n_voltages = ARRAY_SIZE(led_volts), + .enable_reg = BD70528_REG_LED_EN, + .enable_mask = BD70528_MASK_LED1_EN, + .vsel_reg = BD70528_REG_LED_VOLT, + .vsel_mask = BD70528_MASK_LED1_VOLT, + .owner = THIS_MODULE, + }, + { + .name = "ldo_led2", + .of_match = of_match_ptr("LDO_LED2"), + .regulators_node = of_match_ptr("regulators"), + .id = BD70528_LED2, + .ops = &bd70528_led_ops, + .type = REGULATOR_VOLTAGE, + .volt_table = &led_volts[0], + .n_voltages = ARRAY_SIZE(led_volts), + .enable_reg = BD70528_REG_LED_EN, + .enable_mask = BD70528_MASK_LED2_EN, + .vsel_reg = BD70528_REG_LED_VOLT, + .vsel_mask = BD70528_MASK_LED2_VOLT, + .owner = THIS_MODULE, + }, + +}; + +static int bd70528_probe(struct platform_device *pdev) +{ + struct rohm_regmap_dev *bd70528; + int i; + struct regulator_config config = { + .dev = pdev->dev.parent, + }; + + bd70528 = dev_get_drvdata(pdev->dev.parent); + if (!bd70528) { + dev_err(&pdev->dev, "No MFD driver data\n"); + return -EINVAL; + } + + config.regmap = bd70528->regmap; + + for (i = 0; i < ARRAY_SIZE(bd70528_desc); i++) { + struct regulator_dev *rdev; + + rdev = devm_regulator_register(&pdev->dev, &bd70528_desc[i], + &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, + "failed to register %s regulator\n", + bd70528_desc[i].name); + return PTR_ERR(rdev); + } + } + return 0; +} + +static struct platform_driver bd70528_regulator = { + .driver = { + .name = "bd70528-pmic" + }, + .probe = bd70528_probe, +}; + +module_platform_driver(bd70528_regulator); + +MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); +MODULE_DESCRIPTION("BD70528 voltage regulator driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index b8dcdc21dc22..fde4264da6ff 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -27,8 +27,8 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { - int id = rdev->desc->id; - unsigned int ramp_value = BUCK_RAMPRATE_10P00MV; + int id = rdev_get_id(rdev); + unsigned int ramp_value; dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1, ramp_delay); @@ -79,7 +79,7 @@ static int bd718xx_set_voltage_sel_pickable_restricted( return regulator_set_voltage_sel_pickable_regmap(rdev, sel); } -static struct regulator_ops bd718xx_pickable_range_ldo_ops = { +static const struct regulator_ops bd718xx_pickable_range_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -88,7 +88,7 @@ static struct regulator_ops bd718xx_pickable_range_ldo_ops = { .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, }; -static struct regulator_ops bd718xx_pickable_range_buck_ops = { +static const struct regulator_ops bd718xx_pickable_range_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -98,7 +98,7 @@ static struct regulator_ops bd718xx_pickable_range_buck_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops bd718xx_ldo_regulator_ops = { +static const struct regulator_ops bd718xx_ldo_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -107,7 +107,7 @@ static struct regulator_ops bd718xx_ldo_regulator_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; -static struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = { +static const struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -116,7 +116,7 @@ static struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; -static struct regulator_ops bd718xx_buck_regulator_ops = { +static const struct regulator_ops bd718xx_buck_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -126,7 +126,7 @@ static struct regulator_ops bd718xx_buck_regulator_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops bd718xx_buck_regulator_nolinear_ops = { +static const struct regulator_ops bd718xx_buck_regulator_nolinear_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -137,7 +137,7 @@ static struct regulator_ops bd718xx_buck_regulator_nolinear_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops bd718xx_dvs_buck_regulator_ops = { +static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -350,6 +350,135 @@ static const struct reg_init bd71837_ldo6_inits[] = { }, }; +#define NUM_DVS_BUCKS 4 + +struct of_dvs_setting { + const char *prop; + unsigned int reg; +}; + +static int set_dvs_levels(const struct of_dvs_setting *dvs, + struct device_node *np, + const struct regulator_desc *desc, + struct regmap *regmap) +{ + int ret, i; + unsigned int uv; + + ret = of_property_read_u32(np, dvs->prop, &uv); + if (ret) { + if (ret != -EINVAL) + return ret; + return 0; + } + + for (i = 0; i < desc->n_voltages; i++) { + ret = regulator_desc_list_voltage_linear_range(desc, i); + if (ret < 0) + continue; + if (ret == uv) { + i <<= ffs(desc->vsel_mask) - 1; + ret = regmap_update_bits(regmap, dvs->reg, + DVS_BUCK_RUN_MASK, i); + break; + } + } + return ret; +} + +static int buck4_set_hw_dvs_levels(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + int ret, i; + const struct of_dvs_setting dvs[] = { + { + .prop = "rohm,dvs-run-voltage", + .reg = BD71837_REG_BUCK4_VOLT_RUN, + }, + }; + + for (i = 0; i < ARRAY_SIZE(dvs); i++) { + ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); + if (ret) + break; + } + return ret; +} +static int buck3_set_hw_dvs_levels(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + int ret, i; + const struct of_dvs_setting dvs[] = { + { + .prop = "rohm,dvs-run-voltage", + .reg = BD71837_REG_BUCK3_VOLT_RUN, + }, + }; + + for (i = 0; i < ARRAY_SIZE(dvs); i++) { + ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); + if (ret) + break; + } + return ret; +} + +static int buck2_set_hw_dvs_levels(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + int ret, i; + const struct of_dvs_setting dvs[] = { + { + .prop = "rohm,dvs-run-voltage", + .reg = BD718XX_REG_BUCK2_VOLT_RUN, + }, + { + .prop = "rohm,dvs-idle-voltage", + .reg = BD718XX_REG_BUCK2_VOLT_IDLE, + }, + }; + + + + for (i = 0; i < ARRAY_SIZE(dvs); i++) { + ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); + if (ret) + break; + } + return ret; +} + +static int buck1_set_hw_dvs_levels(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + int ret, i; + const struct of_dvs_setting dvs[] = { + { + .prop = "rohm,dvs-run-voltage", + .reg = BD718XX_REG_BUCK1_VOLT_RUN, + }, + { + .prop = "rohm,dvs-idle-voltage", + .reg = BD718XX_REG_BUCK1_VOLT_IDLE, + }, + { + .prop = "rohm,dvs-suspend-voltage", + .reg = BD718XX_REG_BUCK1_VOLT_SUSP, + }, + }; + + for (i = 0; i < ARRAY_SIZE(dvs); i++) { + ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap); + if (ret) + break; + } + return ret; +} + static const struct bd718xx_regulator_data bd71847_regulators[] = { { .desc = { @@ -368,6 +497,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .enable_reg = BD718XX_REG_BUCK1_CTRL, .enable_mask = BD718XX_BUCK_EN, .owner = THIS_MODULE, + .of_parse_cb = buck1_set_hw_dvs_levels, }, .init = { .reg = BD718XX_REG_BUCK1_CTRL, @@ -391,6 +521,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .enable_reg = BD718XX_REG_BUCK2_CTRL, .enable_mask = BD718XX_BUCK_EN, .owner = THIS_MODULE, + .of_parse_cb = buck2_set_hw_dvs_levels, }, .init = { .reg = BD718XX_REG_BUCK2_CTRL, @@ -662,6 +793,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .enable_reg = BD718XX_REG_BUCK1_CTRL, .enable_mask = BD718XX_BUCK_EN, .owner = THIS_MODULE, + .of_parse_cb = buck1_set_hw_dvs_levels, }, .init = { .reg = BD718XX_REG_BUCK1_CTRL, @@ -685,6 +817,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .enable_reg = BD718XX_REG_BUCK2_CTRL, .enable_mask = BD718XX_BUCK_EN, .owner = THIS_MODULE, + .of_parse_cb = buck2_set_hw_dvs_levels, }, .init = { .reg = BD718XX_REG_BUCK2_CTRL, @@ -708,6 +841,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .enable_reg = BD71837_REG_BUCK3_CTRL, .enable_mask = BD718XX_BUCK_EN, .owner = THIS_MODULE, + .of_parse_cb = buck3_set_hw_dvs_levels, }, .init = { .reg = BD71837_REG_BUCK3_CTRL, @@ -731,6 +865,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .enable_reg = BD71837_REG_BUCK4_CTRL, .enable_mask = BD718XX_BUCK_EN, .owner = THIS_MODULE, + .of_parse_cb = buck4_set_hw_dvs_levels, }, .init = { .reg = BD71837_REG_BUCK4_CTRL, @@ -1029,6 +1164,7 @@ static int bd718xx_probe(struct platform_device *pdev) }; int i, j, err; + bool use_snvs; mfd = dev_get_drvdata(pdev->dev.parent); if (!mfd) { @@ -1055,27 +1191,28 @@ static int bd718xx_probe(struct platform_device *pdev) BD718XX_REG_REGLOCK); } - /* At poweroff transition PMIC HW disables EN bit for regulators but - * leaves SEL bit untouched. So if state transition from POWEROFF - * is done to SNVS - then all power rails controlled by SW (having - * SEL bit set) stay disabled as EN is cleared. This may result boot - * failure if any crucial systems are powered by these rails. - * + use_snvs = of_property_read_bool(pdev->dev.parent->of_node, + "rohm,reset-snvs-powered"); + + /* * Change the next stage from poweroff to be READY instead of SNVS * for all reset types because OTP loading at READY will clear SEL * bit allowing HW defaults for power rails to be used */ - err = regmap_update_bits(mfd->regmap, BD718XX_REG_TRANS_COND1, - BD718XX_ON_REQ_POWEROFF_MASK | - BD718XX_SWRESET_POWEROFF_MASK | - BD718XX_WDOG_POWEROFF_MASK | - BD718XX_KEY_L_POWEROFF_MASK, - BD718XX_POWOFF_TO_RDY); - if (err) { - dev_err(&pdev->dev, "Failed to change reset target\n"); - goto err; - } else { - dev_dbg(&pdev->dev, "Changed all resets from SVNS to READY\n"); + if (!use_snvs) { + err = regmap_update_bits(mfd->regmap, BD718XX_REG_TRANS_COND1, + BD718XX_ON_REQ_POWEROFF_MASK | + BD718XX_SWRESET_POWEROFF_MASK | + BD718XX_WDOG_POWEROFF_MASK | + BD718XX_KEY_L_POWEROFF_MASK, + BD718XX_POWOFF_TO_RDY); + if (err) { + dev_err(&pdev->dev, "Failed to change reset target\n"); + goto err; + } else { + dev_dbg(&pdev->dev, + "Changed all resets from SVNS to READY\n"); + } } for (i = 0; i < pmic_regulators[mfd->chip_type].r_amount; i++) { @@ -1098,19 +1235,33 @@ static int bd718xx_probe(struct platform_device *pdev) err = PTR_ERR(rdev); goto err; } - /* Regulator register gets the regulator constraints and + + /* + * Regulator register gets the regulator constraints and * applies them (set_machine_constraints). This should have * turned the control register(s) to correct values and we * can now switch the control from PMIC state machine to the * register interface + * + * At poweroff transition PMIC HW disables EN bit for + * regulators but leaves SEL bit untouched. So if state + * transition from POWEROFF is done to SNVS - then all power + * rails controlled by SW (having SEL bit set) stay disabled + * as EN is cleared. This will result boot failure if any + * crucial systems are powered by these rails. We don't + * enable SW control for crucial regulators if snvs state is + * used */ - err = regmap_update_bits(mfd->regmap, r->init.reg, - r->init.mask, r->init.val); - if (err) { - dev_err(&pdev->dev, - "Failed to write BUCK/LDO SEL bit for (%s)\n", - desc->name); - goto err; + if (!use_snvs || !rdev->constraints->always_on || + !rdev->constraints->boot_on) { + err = regmap_update_bits(mfd->regmap, r->init.reg, + r->init.mask, r->init.val); + if (err) { + dev_err(&pdev->dev, + "Failed to take control for (%s)\n", + desc->name); + goto err; + } } for (j = 0; j < r->additional_init_amnt; j++) { err = regmap_update_bits(mfd->regmap, diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c index e12dd1f750f3..e690c2ce5b3c 100644 --- a/drivers/regulator/bd9571mwv-regulator.c +++ b/drivers/regulator/bd9571mwv-regulator.c @@ -100,7 +100,7 @@ static int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev, } /* Operations permitted on AVS voltage regulator */ -static struct regulator_ops avs_ops = { +static const struct regulator_ops avs_ops = { .set_voltage_sel = bd9571mwv_avs_set_voltage_sel_regmap, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = bd9571mwv_avs_get_voltage_sel_regmap, @@ -108,7 +108,7 @@ static struct regulator_ops avs_ops = { }; /* Operations permitted on voltage regulators */ -static struct regulator_ops reg_ops = { +static const struct regulator_ops reg_ops = { .set_voltage_sel = bd9571mwv_reg_set_voltage_sel_regmap, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -116,13 +116,13 @@ static struct regulator_ops reg_ops = { }; /* Operations permitted on voltage monitors */ -static struct regulator_ops vid_ops = { +static const struct regulator_ops vid_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, }; -static struct regulator_desc regulators[] = { +static const struct regulator_desc regulators[] = { BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f, 0x80, 600000, 10000, 0x3c), BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf, diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b9d7b45c7295..c894cf0d8a28 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * core.c -- Voltage/Current Regulator framework. * @@ -5,12 +6,6 @@ * Copyright 2008 SlimLogic Ltd. * * Author: Liam Girdwood <lrg@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/kernel.h> @@ -23,7 +18,6 @@ #include <linux/mutex.h> #include <linux/suspend.h> #include <linux/delay.h> -#include <linux/gpio.h> #include <linux/gpio/consumer.h> #include <linux/of.h> #include <linux/regmap.h> @@ -82,7 +76,6 @@ struct regulator_enable_gpio { struct gpio_desc *gpiod; u32 enable_count; /* a number of enabled shared GPIO */ u32 request_count; /* a number of requested shared GPIO */ - unsigned int ena_gpio_invert:1; }; /* @@ -145,14 +138,6 @@ static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops) return false; } -static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) -{ - if (rdev && rdev->supply) - return rdev->supply->rdev; - - return NULL; -} - /** * regulator_lock_nested - lock a single regulator * @rdev: regulator source @@ -326,7 +311,7 @@ err_unlock: * @rdev: regulator source * @ww_ctx: w/w mutex acquire context * - * Unlock all regulators related with rdev by coupling or suppling. + * Unlock all regulators related with rdev by coupling or supplying. */ static void regulator_unlock_dependent(struct regulator_dev *rdev, struct ww_acquire_ctx *ww_ctx) @@ -341,7 +326,7 @@ static void regulator_unlock_dependent(struct regulator_dev *rdev, * @ww_ctx: w/w mutex acquire context * * This function as a wrapper on regulator_lock_recursive(), which locks - * all regulators related with rdev by coupling or suppling. + * all regulators related with rdev by coupling or supplying. */ static void regulator_lock_dependent(struct regulator_dev *rdev, struct ww_acquire_ctx *ww_ctx) @@ -924,14 +909,14 @@ static int drms_uA_update(struct regulator_dev *rdev) int current_uA = 0, output_uV, input_uV, err; unsigned int mode; - lockdep_assert_held_once(&rdev->mutex.base); - /* * first check to see if we can set modes at all, otherwise just * tell the consumer everything is OK. */ - if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) + if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) { + rdev_dbg(rdev, "DRMS operation not allowed\n"); return 0; + } if (!rdev->desc->ops->get_optimum_mode && !rdev->desc->ops->set_load) @@ -1003,7 +988,7 @@ static int suspend_set_state(struct regulator_dev *rdev, if (rstate == NULL) return 0; - /* If we have no suspend mode configration don't set anything; + /* If we have no suspend mode configuration don't set anything; * only warn if the driver implements set_suspend_voltage or * set_suspend_mode callback. */ @@ -1131,7 +1116,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, int current_uV = _regulator_get_voltage(rdev); if (current_uV == -ENOTRECOVERABLE) { - /* This regulator can't be read and must be initted */ + /* This regulator can't be read and must be initialized */ rdev_info(rdev, "Setting %d-%duV\n", rdev->constraints->min_uV, rdev->constraints->max_uV); @@ -1780,7 +1765,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) struct device *dev = rdev->dev.parent; int ret; - /* No supply to resovle? */ + /* No supply to resolve? */ if (!rdev->supply_name) return 0; @@ -2058,15 +2043,7 @@ static void _regulator_put(struct regulator *regulator) debugfs_remove_recursive(regulator->debugfs); if (regulator->dev) { - int count = 0; - struct regulator *r; - - list_for_each_entry(r, &rdev->consumer_list, list) - if (r->dev == regulator->dev) - count++; - - if (count == 1) - device_link_remove(regulator->dev, &rdev->dev); + device_link_remove(regulator->dev, &rdev->dev); /* remove any sysfs entries */ sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); @@ -2237,38 +2214,21 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, { struct regulator_enable_gpio *pin; struct gpio_desc *gpiod; - int ret; - if (config->ena_gpiod) - gpiod = config->ena_gpiod; - else - gpiod = gpio_to_desc(config->ena_gpio); + gpiod = config->ena_gpiod; list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { if (pin->gpiod == gpiod) { - rdev_dbg(rdev, "GPIO %d is already used\n", - config->ena_gpio); + rdev_dbg(rdev, "GPIO is already used\n"); goto update_ena_gpio_to_rdev; } } - if (!config->ena_gpiod) { - ret = gpio_request_one(config->ena_gpio, - GPIOF_DIR_OUT | config->ena_gpio_flags, - rdev_get_name(rdev)); - if (ret) - return ret; - } - pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); - if (pin == NULL) { - if (!config->ena_gpiod) - gpio_free(config->ena_gpio); + if (pin == NULL) return -ENOMEM; - } pin->gpiod = gpiod; - pin->ena_gpio_invert = config->ena_gpio_invert; list_add(&pin->list, ®ulator_ena_gpio_list); update_ena_gpio_to_rdev: @@ -2319,8 +2279,7 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) if (enable) { /* Enable GPIO at initial use */ if (pin->enable_count == 0) - gpiod_set_value_cansleep(pin->gpiod, - !pin->ena_gpio_invert); + gpiod_set_value_cansleep(pin->gpiod, 1); pin->enable_count++; } else { @@ -2331,8 +2290,7 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) /* Disable GPIO if not used */ if (pin->enable_count <= 1) { - gpiod_set_value_cansleep(pin->gpiod, - pin->ena_gpio_invert); + gpiod_set_value_cansleep(pin->gpiod, 0); pin->enable_count = 0; } } @@ -2409,7 +2367,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) * timer wrapping. * in case of multiple timer wrapping, either it can be * detected by out-of-range remaining, or it cannot be - * detected and we gets a panelty of + * detected and we get a penalty of * _regulator_enable_delay(). */ remaining = intended - start_jiffy; @@ -2809,7 +2767,7 @@ static void regulator_disable_work(struct work_struct *work) /** * regulator_disable_deferred - disable regulator output with delay * @regulator: regulator source - * @ms: miliseconds until the regulator is disabled + * @ms: milliseconds until the regulator is disabled * * Execute regulator_disable() on the regulator after a delay. This * is intended for use with devices that require some time to quiesce. @@ -3040,7 +2998,7 @@ EXPORT_SYMBOL_GPL(regulator_get_linear_step); * @min_uV: Minimum required voltage in uV. * @max_uV: Maximum required voltage in uV. * - * Returns a boolean or a negative error code. + * Returns a boolean. */ int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV) @@ -3064,7 +3022,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, ret = regulator_count_voltages(regulator); if (ret < 0) - return ret; + return 0; voltages = ret; for (i = 0; i < voltages; i++) { @@ -3358,15 +3316,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, /* for not coupled regulators this will just set the voltage */ ret = regulator_balance_voltage(rdev, state); - if (ret < 0) - goto out2; + if (ret < 0) { + voltage->min_uV = old_min_uV; + voltage->max_uV = old_max_uV; + } out: - return 0; -out2: - voltage->min_uV = old_min_uV; - voltage->max_uV = old_max_uV; - return ret; } @@ -4383,8 +4338,6 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); - dev_err(dev, "Failed to get supply '%s': %d\n", - consumers[i].supply, ret); consumers[i].consumer = NULL; goto err; } @@ -4393,6 +4346,13 @@ int regulator_bulk_get(struct device *dev, int num_consumers, return 0; err: + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get supply '%s': %d\n", + consumers[i].supply, ret); + else + dev_dbg(dev, "Failed to get supply '%s', deferring\n", + consumers[i].supply); + while (--i >= 0) regulator_put(consumers[i].consumer); @@ -4943,7 +4903,7 @@ regulator_register(const struct regulator_desc *regulator_desc, * device tree until we have handled it over to the core. If the * config that was passed in to this function DOES NOT contain * a descriptor, and the config after this call DOES contain - * a descriptor, we definately got one from parsing the device + * a descriptor, we definitely got one from parsing the device * tree. */ if (!cfg->ena_gpiod && config->ena_gpiod) @@ -4975,15 +4935,13 @@ regulator_register(const struct regulator_desc *regulator_desc, goto clean; } - if (config->ena_gpiod || - ((config->ena_gpio || config->ena_gpio_initialized) && - gpio_is_valid(config->ena_gpio))) { + if (config->ena_gpiod) { mutex_lock(®ulator_list_mutex); ret = regulator_ena_gpio_request(rdev, config); mutex_unlock(®ulator_list_mutex); if (ret != 0) { - rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", - config->ena_gpio, ret); + rdev_err(rdev, "Failed to request enable GPIO: %d\n", + ret); goto clean; } /* The regulator core took over the GPIO descriptor */ @@ -5102,10 +5060,11 @@ void regulator_unregister(struct regulator_dev *rdev) regulator_put(rdev->supply); } + flush_work(&rdev->disable_work.work); + mutex_lock(®ulator_list_mutex); debugfs_remove_recursive(rdev->debugfs); - flush_work(&rdev->disable_work.work); WARN_ON(rdev->open_count); regulator_remove_coupling(rdev); unset_regulator_supplies(rdev); @@ -5251,6 +5210,12 @@ struct device *rdev_get_dev(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(rdev_get_dev); +struct regmap *rdev_get_regmap(struct regulator_dev *rdev) +{ + return rdev->regmap; +} +EXPORT_SYMBOL_GPL(rdev_get_regmap); + void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data) { return reg_init_data->driver_data; diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index 2131457937b7..d3284361e594 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -100,12 +100,11 @@ struct cpcap_regulator { struct regulator_desc rdesc; const u16 assign_reg; const u16 assign_mask; - const u16 vsel_shift; }; #define CPCAP_REG(_ID, reg, assignment_reg, assignment_mask, val_tbl, \ - mode_mask, volt_mask, volt_shft, \ - mode_val, off_val, volt_trans_time) { \ + mode_mask, volt_mask, mode_val, off_val, \ + volt_trans_time) { \ .rdesc = { \ .name = #_ID, \ .of_match = of_match_ptr(#_ID), \ @@ -127,7 +126,6 @@ struct cpcap_regulator { }, \ .assign_reg = (assignment_reg), \ .assign_mask = (assignment_mask), \ - .vsel_shift = (volt_shft), \ } struct cpcap_ddata { @@ -336,155 +334,155 @@ static const unsigned int vaudio_val_tbl[] = { 0, 2775000, }; * SW1 to SW4 and SW6 seems to be unused for mapphone. Note that VSIM and * VSIMCARD have a shared resource assignment bit. */ -static struct cpcap_regulator omap4_regulators[] = { +static const struct cpcap_regulator omap4_regulators[] = { CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW1_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW2_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW3_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW4_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW5_SEL, sw5_val_tbl, - 0x28, 0, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0), + 0x28, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0), CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW6_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2, CPCAP_BIT_VCAM_SEL, vcam_val_tbl, - 0x87, 0x30, 4, 0x3, 0, 420), + 0x87, 0x30, 0x3, 0, 420), CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VCSI_SEL, vcsi_val_tbl, - 0x47, 0x10, 4, 0x43, 0x41, 350), + 0x47, 0x10, 0x43, 0x41, 350), CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VDAC_SEL, vdac_val_tbl, - 0x87, 0x30, 4, 0x3, 0, 420), + 0x87, 0x30, 0x3, 0, 420), CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2, CPCAP_BIT_VDIG_SEL, vdig_val_tbl, - 0x87, 0x30, 4, 0x82, 0, 420), + 0x87, 0x30, 0x82, 0, 420), CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl, - 0x80, 0xf, 0, 0x80, 0, 420), + 0x80, 0xf, 0x80, 0, 420), CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl, - 0x17, 0, 0, 0, 0x12, 0), + 0x17, 0, 0, 0x12, 0), CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2, CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl, - 0x87, 0x38, 3, 0x82, 0, 420), + 0x87, 0x38, 0x82, 0, 420), CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VPLL_SEL, vpll_val_tbl, - 0x43, 0x18, 3, 0x2, 0, 420), + 0x43, 0x18, 0x2, 0, 420), CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VRF1_SEL, vrf1_val_tbl, - 0xac, 0x2, 1, 0x4, 0, 10), + 0xac, 0x2, 0x4, 0, 10), CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VRF2_SEL, vrf2_val_tbl, - 0x23, 0x8, 3, 0, 0, 10), + 0x23, 0x8, 0, 0, 10), CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl, - 0x23, 0x8, 3, 0, 0, 420), + 0x23, 0x8, 0, 0, 420), CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl, - 0x47, 0x10, 4, 0, 0, 420), + 0x47, 0x10, 0, 0, 420), CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl, - 0x20c, 0xc0, 6, 0x20c, 0, 420), + 0x20c, 0xc0, 0x20c, 0, 420), CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3, 0xffff, vsim_val_tbl, - 0x23, 0x8, 3, 0x3, 0, 420), + 0x23, 0x8, 0x3, 0, 420), CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3, 0xffff, vsimcard_val_tbl, - 0x1e80, 0x8, 3, 0x1e00, 0, 420), + 0x1e80, 0x8, 0x1e00, 0, 420), CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VVIB_SEL, vvib_val_tbl, - 0x1, 0xc, 2, 0x1, 0, 500), + 0x1, 0xc, 0x1, 0, 500), CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VUSB_SEL, vusb_val_tbl, - 0x11c, 0x40, 6, 0xc, 0, 0), + 0x11c, 0x40, 0xc, 0, 0), CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4, CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl, - 0x16, 0x1, 0, 0x4, 0, 0), + 0x16, 0x1, 0x4, 0, 0), { /* sentinel */ }, }; -static struct cpcap_regulator xoom_regulators[] = { +static const struct cpcap_regulator xoom_regulators[] = { CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW1_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW2_SEL, sw2_sw4_val_tbl, - 0xf00, 0x7f, 0, 0x800, 0, 120), + 0xf00, 0x7f, 0x800, 0, 120), CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW3_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW4_SEL, sw2_sw4_val_tbl, - 0xf00, 0x7f, 0, 0x900, 0, 100), + 0xf00, 0x7f, 0x900, 0, 100), CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW5_SEL, sw5_val_tbl, - 0x2a, 0, 0, 0x22, 0, 0), + 0x2a, 0, 0x22, 0, 0), CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2, CPCAP_BIT_SW6_SEL, unknown_val_tbl, - 0, 0, 0, 0, 0, 0), + 0, 0, 0, 0, 0), CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2, CPCAP_BIT_VCAM_SEL, vcam_val_tbl, - 0x87, 0x30, 4, 0x7, 0, 420), + 0x87, 0x30, 0x7, 0, 420), CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VCSI_SEL, vcsi_val_tbl, - 0x47, 0x10, 4, 0x7, 0, 350), + 0x47, 0x10, 0x7, 0, 350), CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VDAC_SEL, vdac_val_tbl, - 0x87, 0x30, 4, 0x3, 0, 420), + 0x87, 0x30, 0x3, 0, 420), CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2, CPCAP_BIT_VDIG_SEL, vdig_val_tbl, - 0x87, 0x30, 4, 0x5, 0, 420), + 0x87, 0x30, 0x5, 0, 420), CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl, - 0x80, 0xf, 0, 0x80, 0, 420), + 0x80, 0xf, 0x80, 0, 420), CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl, - 0x17, 0, 0, 0x2, 0, 0), + 0x17, 0, 0x2, 0, 0), CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2, CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl, - 0x87, 0x38, 3, 0x2, 0, 420), + 0x87, 0x38, 0x2, 0, 420), CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VPLL_SEL, vpll_val_tbl, - 0x43, 0x18, 3, 0x1, 0, 420), + 0x43, 0x18, 0x1, 0, 420), CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VRF1_SEL, vrf1_val_tbl, - 0xac, 0x2, 1, 0xc, 0, 10), + 0xac, 0x2, 0xc, 0, 10), CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VRF2_SEL, vrf2_val_tbl, - 0x23, 0x8, 3, 0x3, 0, 10), + 0x23, 0x8, 0x3, 0, 10), CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl, - 0x23, 0x8, 3, 0x3, 0, 420), + 0x23, 0x8, 0x3, 0, 420), CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl, - 0x47, 0x10, 4, 0x5, 0, 420), + 0x47, 0x10, 0x5, 0, 420), CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3, CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl, - 0x20c, 0xc0, 6, 0x8, 0, 420), + 0x20c, 0xc0, 0x8, 0, 420), CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3, 0xffff, vsim_val_tbl, - 0x23, 0x8, 3, 0x3, 0, 420), + 0x23, 0x8, 0x3, 0, 420), CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3, 0xffff, vsimcard_val_tbl, - 0x1e80, 0x8, 3, 0x1e00, 0, 420), + 0x1e80, 0x8, 0x1e00, 0, 420), CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VVIB_SEL, vvib_val_tbl, - 0x1, 0xc, 2, 0, 0x1, 500), + 0x1, 0xc, 0, 0x1, 500), CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3, CPCAP_BIT_VUSB_SEL, vusb_val_tbl, - 0x11c, 0x40, 6, 0xc, 0, 0), + 0x11c, 0x40, 0xc, 0, 0), CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4, CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl, - 0x16, 0x1, 0, 0x4, 0, 0), + 0x16, 0x1, 0x4, 0, 0), { /* sentinel */ }, }; @@ -507,17 +505,12 @@ MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table); static int cpcap_regulator_probe(struct platform_device *pdev) { struct cpcap_ddata *ddata; - const struct of_device_id *match; + const struct cpcap_regulator *match_data; struct regulator_config config; - struct regulator_init_data init_data; int i; - match = of_match_device(of_match_ptr(cpcap_regulator_id_table), - &pdev->dev); - if (!match) - return -EINVAL; - - if (!match->data) { + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) { dev_err(&pdev->dev, "no configuration data found\n"); return -ENODEV; @@ -532,14 +525,12 @@ static int cpcap_regulator_probe(struct platform_device *pdev) return -ENODEV; ddata->dev = &pdev->dev; - ddata->soc = match->data; + ddata->soc = match_data; platform_set_drvdata(pdev, ddata); memset(&config, 0, sizeof(config)); - memset(&init_data, 0, sizeof(init_data)); config.dev = &pdev->dev; config.regmap = ddata->reg; - config.init_data = &init_data; for (i = 0; i < CPCAP_NR_REGULATORS; i++) { const struct cpcap_regulator *regulator = &ddata->soc[i]; diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 33e8f3b8d2bd..5493c3a86426 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -1,13 +1,9 @@ -/* - * Regulators driver for Dialog Semiconductor DA903x - * - * Copyright (C) 2006-2008 Marvell International Ltd. - * Copyright (C) 2008 Compulab Ltd. - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Regulators driver for Dialog Semiconductor DA903x +// +// Copyright (C) 2006-2008 Marvell International Ltd. +// Copyright (C) 2008 Compulab Ltd. #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 207cb3859dcc..e18d291c7f21 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -1,16 +1,10 @@ -/* -* da9052-regulator.c: Regulator driver for DA9052 -* -* Copyright(c) 2011 Dialog Semiconductor Ltd. -* -* Author: David Dajun Chen <dchen@diasemi.com> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ +// SPDX-License-Identifier: GPL-2.0+ +// +// da9052-regulator.c: Regulator driver for DA9052 +// +// Copyright(c) 2011 Dialog Semiconductor Ltd. +// +// Author: David Dajun Chen <dchen@diasemi.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -19,10 +13,8 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> -#ifdef CONFIG_OF #include <linux/of.h> #include <linux/regulator/of_regulator.h> -#endif #include <linux/mfd/da9052/da9052.h> #include <linux/mfd/da9052/reg.h> @@ -290,10 +282,12 @@ static const struct regulator_ops da9052_ldo_ops = { .disable = regulator_disable_regmap, }; -#define DA9052_LDO(_id, step, min, max, sbits, ebits, abits) \ +#define DA9052_LDO(_id, _name, step, min, max, sbits, ebits, abits) \ {\ .reg_desc = {\ - .name = #_id,\ + .name = #_name,\ + .of_match = of_match_ptr(#_name),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9052_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9052_ID_##_id,\ @@ -310,10 +304,12 @@ static const struct regulator_ops da9052_ldo_ops = { .activate_bit = (abits),\ } -#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \ +#define DA9052_DCDC(_id, _name, step, min, max, sbits, ebits, abits) \ {\ .reg_desc = {\ - .name = #_id,\ + .name = #_name,\ + .of_match = of_match_ptr(#_name),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9052_dcdc_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9052_ID_##_id,\ @@ -331,37 +327,37 @@ static const struct regulator_ops da9052_ldo_ops = { } static struct da9052_regulator_info da9052_regulator_info[] = { - DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), - DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), - DA9052_DCDC(BUCK3, 25, 950, 2525, 6, 6, DA9052_SUPPLY_VBMEMGO), - DA9052_DCDC(BUCK4, 50, 1800, 3600, 5, 6, 0), - DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0), - DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), - DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), - DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0), - DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0), - DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0), + DA9052_DCDC(BUCK1, buck1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), + DA9052_DCDC(BUCK2, buck2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), + DA9052_DCDC(BUCK3, buck3, 25, 950, 2525, 6, 6, DA9052_SUPPLY_VBMEMGO), + DA9052_DCDC(BUCK4, buck4, 50, 1800, 3600, 5, 6, 0), + DA9052_LDO(LDO1, ldo1, 50, 600, 1800, 5, 6, 0), + DA9052_LDO(LDO2, ldo2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), + DA9052_LDO(LDO3, ldo3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), + DA9052_LDO(LDO4, ldo4, 25, 1725, 3300, 6, 6, 0), + DA9052_LDO(LDO5, ldo5, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO6, ldo6, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO7, ldo7, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO8, ldo8, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO9, ldo9, 50, 1250, 3650, 6, 6, 0), + DA9052_LDO(LDO10, ldo10, 50, 1200, 3600, 6, 6, 0), }; static struct da9052_regulator_info da9053_regulator_info[] = { - DA9052_DCDC(BUCK1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), - DA9052_DCDC(BUCK2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), - DA9052_DCDC(BUCK3, 25, 950, 2525, 6, 6, DA9052_SUPPLY_VBMEMGO), - DA9052_DCDC(BUCK4, 25, 950, 2525, 6, 6, 0), - DA9052_LDO(LDO1, 50, 600, 1800, 5, 6, 0), - DA9052_LDO(LDO2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), - DA9052_LDO(LDO3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), - DA9052_LDO(LDO4, 25, 1725, 3300, 6, 6, 0), - DA9052_LDO(LDO5, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO6, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO7, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO8, 50, 1200, 3600, 6, 6, 0), - DA9052_LDO(LDO9, 50, 1250, 3650, 6, 6, 0), - DA9052_LDO(LDO10, 50, 1200, 3600, 6, 6, 0), + DA9052_DCDC(BUCK1, buck1, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBCOREGO), + DA9052_DCDC(BUCK2, buck2, 25, 500, 2075, 6, 6, DA9052_SUPPLY_VBPROGO), + DA9052_DCDC(BUCK3, buck3, 25, 950, 2525, 6, 6, DA9052_SUPPLY_VBMEMGO), + DA9052_DCDC(BUCK4, buck4, 25, 950, 2525, 6, 6, 0), + DA9052_LDO(LDO1, ldo1, 50, 600, 1800, 5, 6, 0), + DA9052_LDO(LDO2, ldo2, 25, 600, 1800, 6, 6, DA9052_SUPPLY_VLDO2GO), + DA9052_LDO(LDO3, ldo3, 25, 1725, 3300, 6, 6, DA9052_SUPPLY_VLDO3GO), + DA9052_LDO(LDO4, ldo4, 25, 1725, 3300, 6, 6, 0), + DA9052_LDO(LDO5, ldo5, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO6, ldo6, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO7, ldo7, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO8, ldo8, 50, 1200, 3600, 6, 6, 0), + DA9052_LDO(LDO9, ldo9, 50, 1250, 3650, 6, 6, 0), + DA9052_LDO(LDO10, ldo10, 50, 1200, 3600, 6, 6, 0), }; static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, @@ -417,36 +413,11 @@ static int da9052_regulator_probe(struct platform_device *pdev) return -EINVAL; } - config.dev = &pdev->dev; + config.dev = da9052->dev; config.driver_data = regulator; config.regmap = da9052->regmap; - if (pdata) { + if (pdata) config.init_data = pdata->regulators[cell->id]; - } else { -#ifdef CONFIG_OF - struct device_node *nproot = da9052->dev->of_node; - struct device_node *np; - - if (!nproot) - return -ENODEV; - - nproot = of_get_child_by_name(nproot, "regulators"); - if (!nproot) - return -ENODEV; - - for_each_child_of_node(nproot, np) { - if (of_node_name_eq(np, - regulator->info->reg_desc.name)) { - config.init_data = of_get_regulator_init_data( - &pdev->dev, np, - ®ulator->info->reg_desc); - config.of_node = np; - break; - } - } - of_node_put(nproot); -#endif - } regulator->rdev = devm_regulator_register(&pdev->dev, ®ulator->info->reg_desc, diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 588c3d2445cf..c025ccb1a30a 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -1,16 +1,10 @@ -/* -* Regulator driver for DA9055 PMIC -* -* Copyright(c) 2012 Dialog Semiconductor Ltd. -* -* Author: David Dajun Chen <dchen@diasemi.com> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator driver for DA9055 PMIC +// +// Copyright(c) 2012 Dialog Semiconductor Ltd. +// +// Author: David Dajun Chen <dchen@diasemi.com> #include <linux/module.h> #include <linux/init.h> @@ -48,7 +42,9 @@ #define DA9055_ID_LDO6 7 /* DA9055 BUCK current limit */ -static const int da9055_current_limits[] = { 500000, 600000, 700000, 800000 }; +static const unsigned int da9055_current_limits[] = { + 500000, 600000, 700000, 800000 +}; struct da9055_conf_reg { int reg; @@ -169,39 +165,6 @@ static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) val << volt.sl_shift); } -static int da9055_buck_get_current_limit(struct regulator_dev *rdev) -{ - struct da9055_regulator *regulator = rdev_get_drvdata(rdev); - struct da9055_regulator_info *info = regulator->info; - int ret; - - ret = da9055_reg_read(regulator->da9055, DA9055_REG_BUCK_LIM); - if (ret < 0) - return ret; - - ret &= info->mode.mask; - return da9055_current_limits[ret >> info->mode.shift]; -} - -static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, - int max_uA) -{ - struct da9055_regulator *regulator = rdev_get_drvdata(rdev); - struct da9055_regulator_info *info = regulator->info; - int i; - - for (i = ARRAY_SIZE(da9055_current_limits) - 1; i >= 0; i--) { - if ((min_uA <= da9055_current_limits[i]) && - (da9055_current_limits[i] <= max_uA)) - return da9055_reg_update(regulator->da9055, - DA9055_REG_BUCK_LIM, - info->mode.mask, - i << info->mode.shift); - } - - return -EINVAL; -} - static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) { struct da9055_regulator *regulator = rdev_get_drvdata(rdev); @@ -329,8 +292,8 @@ static const struct regulator_ops da9055_buck_ops = { .get_mode = da9055_buck_get_mode, .set_mode = da9055_buck_set_mode, - .get_current_limit = da9055_buck_get_current_limit, - .set_current_limit = da9055_buck_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_voltage_sel = da9055_regulator_get_voltage_sel, .set_voltage_sel = da9055_regulator_set_voltage_sel, @@ -369,6 +332,8 @@ static const struct regulator_ops da9055_ldo_ops = { {\ .reg_desc = {\ .name = #_id,\ + .of_match = of_match_ptr(#_id),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9055_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9055_ID_##_id,\ @@ -397,6 +362,8 @@ static const struct regulator_ops da9055_ldo_ops = { {\ .reg_desc = {\ .name = #_id,\ + .of_match = of_match_ptr(#_id),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9055_buck_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9055_ID_##_id,\ @@ -407,6 +374,10 @@ static const struct regulator_ops da9055_ldo_ops = { .uV_step = (step) * 1000,\ .linear_min_sel = (voffset),\ .owner = THIS_MODULE,\ + .curr_table = da9055_current_limits,\ + .n_current_limits = ARRAY_SIZE(da9055_current_limits),\ + .csel_reg = DA9055_REG_BUCK_LIM,\ + .csel_mask = (mbits),\ },\ .conf = {\ .reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ @@ -457,7 +428,6 @@ static int da9055_gpio_init(struct da9055_regulator *regulator, int gpio_mux = pdata->gpio_ren[id]; config->ena_gpiod = pdata->ena_gpiods[id]; - config->ena_gpio_invert = 1; /* * GPI pin is muxed with regulator to control the @@ -515,8 +485,10 @@ static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data) { struct da9055_regulator *regulator = data; + regulator_lock(regulator->rdev); regulator_notifier_call_chain(regulator->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(regulator->rdev); return IRQ_HANDLED; } @@ -535,59 +507,6 @@ static inline struct da9055_regulator_info *find_regulator_info(int id) return NULL; } -#ifdef CONFIG_OF -static struct of_regulator_match da9055_reg_matches[] = { - { .name = "BUCK1", }, - { .name = "BUCK2", }, - { .name = "LDO1", }, - { .name = "LDO2", }, - { .name = "LDO3", }, - { .name = "LDO4", }, - { .name = "LDO5", }, - { .name = "LDO6", }, -}; - -static int da9055_regulator_dt_init(struct platform_device *pdev, - struct da9055_regulator *regulator, - struct regulator_config *config, - int regid) -{ - struct device_node *nproot, *np; - int ret; - - nproot = of_node_get(pdev->dev.parent->of_node); - if (!nproot) - return -ENODEV; - - np = of_get_child_by_name(nproot, "regulators"); - if (!np) - return -ENODEV; - - ret = of_regulator_match(&pdev->dev, np, &da9055_reg_matches[regid], 1); - of_node_put(nproot); - if (ret < 0) { - dev_err(&pdev->dev, "Error matching regulator: %d\n", ret); - return ret; - } - - config->init_data = da9055_reg_matches[regid].init_data; - config->of_node = da9055_reg_matches[regid].of_node; - - if (!config->of_node) - return -ENODEV; - - return 0; -} -#else -static inline int da9055_regulator_dt_init(struct platform_device *pdev, - struct da9055_regulator *regulator, - struct regulator_config *config, - int regid) -{ - return -ENODEV; -} -#endif /* CONFIG_OF */ - static int da9055_regulator_probe(struct platform_device *pdev) { struct regulator_config config = { }; @@ -608,18 +527,12 @@ static int da9055_regulator_probe(struct platform_device *pdev) } regulator->da9055 = da9055; - config.dev = &pdev->dev; + config.dev = da9055->dev; config.driver_data = regulator; config.regmap = da9055->regmap; - if (pdata) { + if (pdata) config.init_data = pdata->regulators[pdev->id]; - } else { - ret = da9055_regulator_dt_init(pdev, regulator, &config, - pdev->id); - if (ret < 0) - return ret; - } ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); if (ret < 0) diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index 34a70d9dc450..a02e0488410f 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -1,17 +1,8 @@ -/* - * Regulator device driver for DA9061 and DA9062. - * Copyright (C) 2015-2017 Dialog Semiconductor - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator device driver for DA9061 and DA9062. +// Copyright (C) 2015-2017 Dialog Semiconductor + #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -53,16 +44,12 @@ enum { /* Regulator capabilities and registers description */ struct da9062_regulator_info { struct regulator_desc desc; - /* Current limiting */ - unsigned int n_current_limits; - const int *current_limits; /* Main register fields */ struct reg_field mode; struct reg_field suspend; struct reg_field sleep; struct reg_field suspend_sleep; unsigned int suspend_vsel_reg; - struct reg_field ilimit; /* Event detection bit */ struct reg_field oc_event; }; @@ -78,7 +65,6 @@ struct da9062_regulator { struct regmap_field *suspend; struct regmap_field *sleep; struct regmap_field *suspend_sleep; - struct regmap_field *ilimit; }; /* Encapsulates all information for the regulators driver */ @@ -104,7 +90,7 @@ enum { * - DA9062_ID_[BUCK1|BUCK2|BUCK4] * Entry indexes corresponds to register values. */ -static const int da9062_buck_a_limits[] = { +static const unsigned int da9062_buck_a_limits[] = { 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 }; @@ -114,44 +100,11 @@ static const int da9062_buck_a_limits[] = { * - DA9062_ID_BUCK3 * Entry indexes corresponds to register values. */ -static const int da9062_buck_b_limits[] = { +static const unsigned int da9062_buck_b_limits[] = { 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 }; -static int da9062_set_current_limit(struct regulator_dev *rdev, - int min_ua, int max_ua) -{ - struct da9062_regulator *regl = rdev_get_drvdata(rdev); - const struct da9062_regulator_info *rinfo = regl->info; - int n, tval; - - for (n = 0; n < rinfo->n_current_limits; n++) { - tval = rinfo->current_limits[n]; - if (tval >= min_ua && tval <= max_ua) - return regmap_field_write(regl->ilimit, n); - } - - return -EINVAL; -} - -static int da9062_get_current_limit(struct regulator_dev *rdev) -{ - struct da9062_regulator *regl = rdev_get_drvdata(rdev); - const struct da9062_regulator_info *rinfo = regl->info; - unsigned int sel; - int ret; - - ret = regmap_field_read(regl->ilimit, &sel); - if (ret < 0) - return ret; - - if (sel >= rinfo->n_current_limits) - sel = rinfo->n_current_limits - 1; - - return rinfo->current_limits[sel]; -} - static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode) { struct da9062_regulator *regl = rdev_get_drvdata(rdev); @@ -395,8 +348,8 @@ static const struct regulator_ops da9062_buck_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = da9062_set_current_limit, - .get_current_limit = da9062_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .set_mode = da9062_buck_set_mode, .get_mode = da9062_buck_get_mode, .get_status = da9062_buck_get_status, @@ -433,8 +386,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.min_uV = (300) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1570) - (300))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_C, + .desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK1_CONT, .desc.enable_mask = DA9062AA_BUCK1_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK1_A, @@ -457,10 +412,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, - __builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1), }, { .desc.id = DA9061_ID_BUCK2, @@ -471,8 +422,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.min_uV = (800) * 1000, .desc.uV_step = (20) * 1000, .desc.n_voltages = ((3340) - (800))/(20) + 1, - .current_limits = da9062_buck_b_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.curr_table = da9062_buck_b_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_A, + .desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK3_CONT, .desc.enable_mask = DA9062AA_BUCK3_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK3_A, @@ -495,10 +448,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A, - __builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1), }, { .desc.id = DA9061_ID_BUCK3, @@ -509,8 +458,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.min_uV = (530) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1800) - (530))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_B, + .desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK4_CONT, .desc.enable_mask = DA9062AA_BUCK4_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK4_A, @@ -533,10 +484,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B, - __builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1), }, { .desc.id = DA9061_ID_LDO1, @@ -679,8 +626,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (300) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1570) - (300))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_C, + .desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK1_CONT, .desc.enable_mask = DA9062AA_BUCK1_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK1_A, @@ -703,10 +652,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, - __builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_BUCK2, @@ -717,8 +662,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (300) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1570) - (300))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_C, + .desc.csel_mask = DA9062AA_BUCK2_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK2_CONT, .desc.enable_mask = DA9062AA_BUCK2_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK2_A, @@ -741,10 +688,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, - __builtin_ffs((int)DA9062AA_BUCK2_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK2_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_BUCK3, @@ -755,8 +698,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (800) * 1000, .desc.uV_step = (20) * 1000, .desc.n_voltages = ((3340) - (800))/(20) + 1, - .current_limits = da9062_buck_b_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.curr_table = da9062_buck_b_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_A, + .desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK3_CONT, .desc.enable_mask = DA9062AA_BUCK3_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK3_A, @@ -779,10 +724,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A, - __builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_BUCK4, @@ -793,8 +734,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (530) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1800) - (530))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_B, + .desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK4_CONT, .desc.enable_mask = DA9062AA_BUCK4_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK4_A, @@ -817,10 +760,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B, - __builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_LDO1, @@ -974,8 +913,10 @@ static irqreturn_t da9062_ldo_lim_event(int irq, void *data) continue; if (BIT(regl->info->oc_event.lsb) & bits) { + regulator_lock(regl->rdev); regulator_notifier_call_chain(regl->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(regl->rdev); handled = IRQ_HANDLED; } } @@ -992,7 +933,6 @@ static int da9062_regulator_probe(struct platform_device *pdev) struct regulator_config config = { }; const struct da9062_regulator_info *rinfo; int irq, n, ret; - size_t size; int max_regulators; switch (chip->chip_type) { @@ -1010,9 +950,8 @@ static int da9062_regulator_probe(struct platform_device *pdev) } /* Allocate memory required by usable regulators */ - size = sizeof(struct da9062_regulators) + - max_regulators * sizeof(struct da9062_regulator); - regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + regulators = devm_kzalloc(&pdev->dev, struct_size(regulators, regulator, + max_regulators), GFP_KERNEL); if (!regulators) return -ENOMEM; @@ -1029,31 +968,41 @@ static int da9062_regulator_probe(struct platform_device *pdev) regl->desc.type = REGULATOR_VOLTAGE; regl->desc.owner = THIS_MODULE; - if (regl->info->mode.reg) + if (regl->info->mode.reg) { regl->mode = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->mode); - if (regl->info->suspend.reg) + if (IS_ERR(regl->mode)) + return PTR_ERR(regl->mode); + } + + if (regl->info->suspend.reg) { regl->suspend = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->suspend); - if (regl->info->sleep.reg) + if (IS_ERR(regl->suspend)) + return PTR_ERR(regl->suspend); + } + + if (regl->info->sleep.reg) { regl->sleep = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->sleep); - if (regl->info->suspend_sleep.reg) + if (IS_ERR(regl->sleep)) + return PTR_ERR(regl->sleep); + } + + if (regl->info->suspend_sleep.reg) { regl->suspend_sleep = devm_regmap_field_alloc( &pdev->dev, chip->regmap, regl->info->suspend_sleep); - if (regl->info->ilimit.reg) - regl->ilimit = devm_regmap_field_alloc( - &pdev->dev, - chip->regmap, - regl->info->ilimit); + if (IS_ERR(regl->suspend_sleep)) + return PTR_ERR(regl->suspend_sleep); + } /* Register regulator */ memset(&config, 0, sizeof(config)); diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 8cbcd2a3eb20..6f9ce1a6e44d 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -1,18 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator driver for DA9063 PMIC series +// +// Copyright 2012 Dialog Semiconductors Ltd. +// Copyright 2013 Philipp Zabel, Pengutronix +// +// Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> -/* - * Regulator driver for DA9063 PMIC series - * - * Copyright 2012 Dialog Semiconductors Ltd. - * Copyright 2013 Philipp Zabel, Pengutronix - * - * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -38,17 +32,12 @@ struct da9063_regulator_info { struct regulator_desc desc; - /* Current limiting */ - unsigned n_current_limits; - const int *current_limits; - /* DA9063 main register fields */ struct reg_field mode; /* buck mode of operation */ struct reg_field suspend; struct reg_field sleep; struct reg_field suspend_sleep; unsigned int suspend_vsel_reg; - struct reg_field ilimit; /* DA9063 event detection bit */ struct reg_field oc_event; @@ -73,15 +62,18 @@ struct da9063_regulator_info { .suspend_vsel_reg = DA9063_REG_V##regl_name##_B /* Macros for voltage DC/DC converters (BUCKs) */ -#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array) \ +#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array, \ + creg, cmask) \ .desc.id = chip##_ID_##regl_name, \ .desc.name = __stringify(chip##_##regl_name), \ .desc.ops = &da9063_buck_ops, \ .desc.min_uV = (min_mV) * 1000, \ .desc.uV_step = (step_mV) * 1000, \ .desc.n_voltages = ((max_mV) - (min_mV))/(step_mV) + 1, \ - .current_limits = limits_array, \ - .n_current_limits = ARRAY_SIZE(limits_array) + .desc.csel_reg = (creg), \ + .desc.csel_mask = (cmask), \ + .desc.curr_table = limits_array, \ + .desc.n_current_limits = ARRAY_SIZE(limits_array) #define DA9063_BUCK_COMMON_FIELDS(regl_name) \ .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ @@ -112,7 +104,6 @@ struct da9063_regulator { struct regmap_field *suspend; struct regmap_field *sleep; struct regmap_field *suspend_sleep; - struct regmap_field *ilimit; }; /* Encapsulates all information for the regulators driver */ @@ -134,65 +125,32 @@ enum { /* Current limits array (in uA) for BCORE1, BCORE2, BPRO. Entry indexes corresponds to register values. */ -static const int da9063_buck_a_limits[] = { +static const unsigned int da9063_buck_a_limits[] = { 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 }; /* Current limits array (in uA) for BMEM, BIO, BPERI. Entry indexes corresponds to register values. */ -static const int da9063_buck_b_limits[] = { +static const unsigned int da9063_buck_b_limits[] = { 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 }; /* Current limits array (in uA) for merged BCORE1 and BCORE2. Entry indexes corresponds to register values. */ -static const int da9063_bcores_merged_limits[] = { +static const unsigned int da9063_bcores_merged_limits[] = { 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000 }; /* Current limits array (in uA) for merged BMEM and BIO. Entry indexes corresponds to register values. */ -static const int da9063_bmem_bio_merged_limits[] = { +static const unsigned int da9063_bmem_bio_merged_limits[] = { 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 }; -static int da9063_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct da9063_regulator *regl = rdev_get_drvdata(rdev); - const struct da9063_regulator_info *rinfo = regl->info; - int n, tval; - - for (n = 0; n < rinfo->n_current_limits; n++) { - tval = rinfo->current_limits[n]; - if (tval >= min_uA && tval <= max_uA) - return regmap_field_write(regl->ilimit, n); - } - - return -EINVAL; -} - -static int da9063_get_current_limit(struct regulator_dev *rdev) -{ - struct da9063_regulator *regl = rdev_get_drvdata(rdev); - const struct da9063_regulator_info *rinfo = regl->info; - unsigned int sel; - int ret; - - ret = regmap_field_read(regl->ilimit, &sel); - if (ret < 0) - return ret; - - if (sel >= rinfo->n_current_limits) - sel = rinfo->n_current_limits - 1; - - return rinfo->current_limits[sel]; -} - static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned mode) { struct da9063_regulator *regl = rdev_get_drvdata(rdev); @@ -434,8 +392,8 @@ static const struct regulator_ops da9063_buck_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = da9063_set_current_limit, - .get_current_limit = da9063_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .set_mode = da9063_buck_set_mode, .get_mode = da9063_buck_get_mode, .get_status = da9063_buck_get_status, @@ -465,69 +423,61 @@ static const struct regulator_ops da9063_ldo_ops = { static const struct da9063_regulator_info da9063_regulator_info[] = { { DA9063_BUCK(DA9063, BCORE1, 300, 10, 1570, - da9063_buck_a_limits), + da9063_buck_a_limits, + DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BCORE1), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE1_ILIM_MASK), }, { DA9063_BUCK(DA9063, BCORE2, 300, 10, 1570, - da9063_buck_a_limits), + da9063_buck_a_limits, + DA9063_REG_BUCK_ILIM_C, DA9063_BCORE2_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BCORE2), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE2_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE2_ILIM_MASK), }, { DA9063_BUCK(DA9063, BPRO, 530, 10, 1800, - da9063_buck_a_limits), + da9063_buck_a_limits, + DA9063_REG_BUCK_ILIM_B, DA9063_BPRO_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BPRO), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPRO_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_B, - DA9063_BPRO_ILIM_MASK), }, { DA9063_BUCK(DA9063, BMEM, 800, 20, 3340, - da9063_buck_b_limits), + da9063_buck_b_limits, + DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BMEM), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A, - DA9063_BMEM_ILIM_MASK), }, { DA9063_BUCK(DA9063, BIO, 800, 20, 3340, - da9063_buck_b_limits), + da9063_buck_b_limits, + DA9063_REG_BUCK_ILIM_A, DA9063_BIO_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BIO), .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VBIO_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A, - DA9063_BIO_ILIM_MASK), }, { DA9063_BUCK(DA9063, BPERI, 800, 20, 3340, - da9063_buck_b_limits), + da9063_buck_b_limits, + DA9063_REG_BUCK_ILIM_B, DA9063_BPERI_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BPERI), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPERI_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_B, - DA9063_BPERI_ILIM_MASK), }, { DA9063_BUCK(DA9063, BCORES_MERGED, 300, 10, 1570, - da9063_bcores_merged_limits), + da9063_bcores_merged_limits, + DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK), /* BCORES_MERGED uses the same register fields as BCORE1 */ DA9063_BUCK_COMMON_FIELDS(BCORE1), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE1_ILIM_MASK), }, { DA9063_BUCK(DA9063, BMEM_BIO_MERGED, 800, 20, 3340, - da9063_bmem_bio_merged_limits), + da9063_bmem_bio_merged_limits, + DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK), /* BMEM_BIO_MERGED uses the same register fields as BMEM */ DA9063_BUCK_COMMON_FIELDS(BMEM), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A, - DA9063_BMEM_ILIM_MASK), }, { DA9063_LDO(DA9063, LDO3, 900, 20, 3440), @@ -615,9 +565,12 @@ static irqreturn_t da9063_ldo_lim_event(int irq, void *data) if (regl->info->oc_event.reg != DA9063_REG_STATUS_D) continue; - if (BIT(regl->info->oc_event.lsb) & bits) + if (BIT(regl->info->oc_event.lsb) & bits) { + regulator_lock(regl->rdev); regulator_notifier_call_chain(regl->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(regl->rdev); + } } return IRQ_HANDLED; @@ -739,7 +692,6 @@ static int da9063_regulator_probe(struct platform_device *pdev) struct regulator_config config; bool bcores_merged, bmem_bio_merged; int id, irq, n, n_regulators, ret, val; - size_t size; regl_pdata = da9063_pdata ? da9063_pdata->regulators_pdata : NULL; @@ -784,9 +736,8 @@ static int da9063_regulator_probe(struct platform_device *pdev) n_regulators--; /* remove BMEM_BIO_MERGED */ /* Allocate memory required by usable regulators */ - size = sizeof(struct da9063_regulators) + - n_regulators * sizeof(struct da9063_regulator); - regulators = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + regulators = devm_kzalloc(&pdev->dev, struct_size(regulators, + regulator, n_regulators), GFP_KERNEL); if (!regulators) return -ENOMEM; @@ -835,21 +786,33 @@ static int da9063_regulator_probe(struct platform_device *pdev) regl->desc.type = REGULATOR_VOLTAGE; regl->desc.owner = THIS_MODULE; - if (regl->info->mode.reg) + if (regl->info->mode.reg) { regl->mode = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->mode); - if (regl->info->suspend.reg) + if (IS_ERR(regl->mode)) + return PTR_ERR(regl->mode); + } + + if (regl->info->suspend.reg) { regl->suspend = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->suspend); - if (regl->info->sleep.reg) + if (IS_ERR(regl->suspend)) + return PTR_ERR(regl->suspend); + } + + if (regl->info->sleep.reg) { regl->sleep = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->sleep); - if (regl->info->suspend_sleep.reg) + if (IS_ERR(regl->sleep)) + return PTR_ERR(regl->sleep); + } + + if (regl->info->suspend_sleep.reg) { regl->suspend_sleep = devm_regmap_field_alloc(&pdev->dev, da9063->regmap, regl->info->suspend_sleep); - if (regl->info->ilimit.reg) - regl->ilimit = devm_regmap_field_alloc(&pdev->dev, - da9063->regmap, regl->info->ilimit); + if (IS_ERR(regl->suspend_sleep)) + return PTR_ERR(regl->suspend_sleep); + } /* Register regulator */ memset(&config, 0, sizeof(config)); diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 84dba64ed11e..f9448ed50e05 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -1,22 +1,7 @@ -/* - * da9210-regulator.c - Regulator device driver for DA9210 - * Copyright (C) 2013 Dialog Semiconductor Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// da9210-regulator.c - Regulator device driver for DA9210 +// Copyright (C) 2013 Dialog Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -41,10 +26,6 @@ static const struct regmap_config da9210_regmap_config = { .val_bits = 8, }; -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 const struct regulator_ops da9210_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -52,8 +33,8 @@ static const struct regulator_ops da9210_buck_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = da9210_set_current_limit, - .get_current_limit = da9210_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; /* Default limits measured in millivolts and milliamps */ @@ -62,7 +43,7 @@ static const struct regulator_ops da9210_buck_ops = { #define DA9210_STEP_MV 10 /* Current limits for buck (uA) indices corresponds with register values */ -static const int da9210_buck_limits[] = { +static const unsigned int da9210_buck_limits[] = { 1600000, 1800000, 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, 4600000 }; @@ -80,47 +61,12 @@ static const struct regulator_desc da9210_reg = { .enable_reg = DA9210_REG_BUCK_CONT, .enable_mask = DA9210_BUCK_EN, .owner = THIS_MODULE, + .curr_table = da9210_buck_limits, + .n_current_limits = ARRAY_SIZE(da9210_buck_limits), + .csel_reg = DA9210_REG_BUCK_ILIM, + .csel_mask = DA9210_BUCK_ILIM_MASK, }; -static int da9210_set_current_limit(struct regulator_dev *rdev, int min_uA, - int max_uA) -{ - struct da9210 *chip = rdev_get_drvdata(rdev); - unsigned int sel; - int i; - - /* search for closest to maximum */ - for (i = ARRAY_SIZE(da9210_buck_limits)-1; i >= 0; i--) { - if (min_uA <= da9210_buck_limits[i] && - max_uA >= da9210_buck_limits[i]) { - sel = i; - sel = sel << DA9210_BUCK_ILIM_SHIFT; - return regmap_update_bits(chip->regmap, - DA9210_REG_BUCK_ILIM, - DA9210_BUCK_ILIM_MASK, sel); - } - } - - return -EINVAL; -} - -static int da9210_get_current_limit(struct regulator_dev *rdev) -{ - struct da9210 *chip = rdev_get_drvdata(rdev); - unsigned int data; - unsigned int sel; - int ret; - - ret = regmap_read(chip->regmap, DA9210_REG_BUCK_ILIM, &data); - if (ret < 0) - return ret; - - /* select one of 16 values: 0000 (1600mA) to 1111 (4600mA) */ - sel = (data & DA9210_BUCK_ILIM_MASK) >> DA9210_BUCK_ILIM_SHIFT; - - return da9210_buck_limits[sel]; -} - static irqreturn_t da9210_irq_handler(int irq, void *data) { struct da9210 *chip = data; diff --git a/drivers/regulator/da9210-regulator.h b/drivers/regulator/da9210-regulator.h index 749c550808b6..b1f1a607c208 100644 --- a/drivers/regulator/da9210-regulator.h +++ b/drivers/regulator/da9210-regulator.h @@ -1,22 +1,7 @@ - +/* SPDX-License-Identifier: GPL-2.0+ */ /* * da9210-regulator.h - Regulator definitions for DA9210 * Copyright (C) 2013 Dialog Semiconductor Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef __DA9210_REGISTERS_H__ diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 109ee12d4362..da37b4ccd834 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -1,18 +1,8 @@ -/* - * da9211-regulator.c - Regulator device driver for DA9211/DA9212 - * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 - * Copyright (C) 2015 Dialog Semiconductor Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// da9211-regulator.c - Regulator device driver for DA9211/DA9212 +// /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 +// Copyright (C) 2015 Dialog Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -322,8 +312,10 @@ static irqreturn_t da9211_irq_handler(int irq, void *data) goto error_i2c; if (reg_val & DA9211_E_OV_CURR_A) { + regulator_lock(chip->rdev[0]); regulator_notifier_call_chain(chip->rdev[0], REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(chip->rdev[0]); err = regmap_write(chip->regmap, DA9211_REG_EVENT_B, DA9211_E_OV_CURR_A); @@ -334,8 +326,10 @@ static irqreturn_t da9211_irq_handler(int irq, void *data) } if (reg_val & DA9211_E_OV_CURR_B) { + regulator_lock(chip->rdev[1]); regulator_notifier_call_chain(chip->rdev[1], REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(chip->rdev[1]); err = regmap_write(chip->regmap, DA9211_REG_EVENT_B, DA9211_E_OV_CURR_B); diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h index 2cb32aab4f82..1201e7cc056c 100644 --- a/drivers/regulator/da9211-regulator.h +++ b/drivers/regulator/da9211-regulator.h @@ -1,17 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * da9211-regulator.h - Regulator definitions for DA9211/DA9212 * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 * Copyright (C) 2015 Dialog Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __DA9211_REGISTERS_H__ diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 7cec535cf0bc..88a2dcb9fe8a 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * - * License Terms: GNU General Public License v2 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson * @@ -75,7 +75,7 @@ static int db8500_regulator_is_enabled(struct regulator_dev *rdev) } /* db8500 regulator operations */ -static struct regulator_ops db8500_regulator_ops = { +static const struct regulator_ops db8500_regulator_ops = { .enable = db8500_regulator_enable, .disable = db8500_regulator_disable, .is_enabled = db8500_regulator_is_enabled, @@ -200,7 +200,7 @@ static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) return info->is_enabled; } -static struct regulator_ops db8500_regulator_switch_ops = { +static const struct regulator_ops db8500_regulator_switch_ops = { .enable = db8500_regulator_switch_enable, .disable = db8500_regulator_switch_disable, .is_enabled = db8500_regulator_switch_is_enabled, @@ -214,6 +214,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VAPE] = { .desc = { .name = "db8500-vape", + .of_match = of_match_ptr("db8500_vape"), .id = DB8500_REGULATOR_VAPE, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -223,6 +224,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VARM] = { .desc = { .name = "db8500-varm", + .of_match = of_match_ptr("db8500_varm"), .id = DB8500_REGULATOR_VARM, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -232,6 +234,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VMODEM] = { .desc = { .name = "db8500-vmodem", + .of_match = of_match_ptr("db8500_vmodem"), .id = DB8500_REGULATOR_VMODEM, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -241,6 +244,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VPLL] = { .desc = { .name = "db8500-vpll", + .of_match = of_match_ptr("db8500_vpll"), .id = DB8500_REGULATOR_VPLL, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -250,6 +254,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VSMPS1] = { .desc = { .name = "db8500-vsmps1", + .of_match = of_match_ptr("db8500_vsmps1"), .id = DB8500_REGULATOR_VSMPS1, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -259,6 +264,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VSMPS2] = { .desc = { .name = "db8500-vsmps2", + .of_match = of_match_ptr("db8500_vsmps2"), .id = DB8500_REGULATOR_VSMPS2, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -271,6 +277,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VSMPS3] = { .desc = { .name = "db8500-vsmps3", + .of_match = of_match_ptr("db8500_vsmps3"), .id = DB8500_REGULATOR_VSMPS3, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -280,6 +287,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VRF1] = { .desc = { .name = "db8500-vrf1", + .of_match = of_match_ptr("db8500_vrf1"), .id = DB8500_REGULATOR_VRF1, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -289,6 +297,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { .desc = { .name = "db8500-sva-mmdsp", + .of_match = of_match_ptr("db8500_sva_mmdsp"), .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -299,6 +308,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { .desc = { .name = "db8500-sva-mmdsp-ret", + .of_match = of_match_ptr("db8500_sva_mmdsp_ret"), .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -310,6 +320,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SVAPIPE] = { .desc = { .name = "db8500-sva-pipe", + .of_match = of_match_ptr("db8500_sva_pipe"), .id = DB8500_REGULATOR_SWITCH_SVAPIPE, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -320,6 +331,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { .desc = { .name = "db8500-sia-mmdsp", + .of_match = of_match_ptr("db8500_sia_mmdsp"), .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -330,6 +342,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { .desc = { .name = "db8500-sia-mmdsp-ret", + .of_match = of_match_ptr("db8500_sia_mmdsp_ret"), .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -341,6 +354,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SIAPIPE] = { .desc = { .name = "db8500-sia-pipe", + .of_match = of_match_ptr("db8500_sia_pipe"), .id = DB8500_REGULATOR_SWITCH_SIAPIPE, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -351,6 +365,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SGA] = { .desc = { .name = "db8500-sga", + .of_match = of_match_ptr("db8500_sga"), .id = DB8500_REGULATOR_SWITCH_SGA, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -361,6 +376,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { .desc = { .name = "db8500-b2r2-mcde", + .of_match = of_match_ptr("db8500_b2r2_mcde"), .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -371,6 +387,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM12] = { .desc = { .name = "db8500-esram12", + .of_match = of_match_ptr("db8500_esram12"), .id = DB8500_REGULATOR_SWITCH_ESRAM12, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -382,6 +399,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { .desc = { .name = "db8500-esram12-ret", + .of_match = of_match_ptr("db8500_esram12_ret"), .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -393,6 +411,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM34] = { .desc = { .name = "db8500-esram34", + .of_match = of_match_ptr("db8500_esram34"), .id = DB8500_REGULATOR_SWITCH_ESRAM34, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -404,6 +423,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { .desc = { .name = "db8500-esram34-ret", + .of_match = of_match_ptr("db8500_esram34_ret"), .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -414,113 +434,38 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { }, }; -static int db8500_regulator_register(struct platform_device *pdev, - struct regulator_init_data *init_data, - int id, - struct device_node *np) +static int db8500_regulator_probe(struct platform_device *pdev) { + struct regulator_init_data *db8500_init_data; struct dbx500_regulator_info *info; struct regulator_config config = { }; - int err; - - /* assign per-regulator data */ - info = &dbx500_regulator_info[id]; - info->dev = &pdev->dev; - - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = info; - config.of_node = np; - - /* register with the regulator framework */ - info->rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); - if (IS_ERR(info->rdev)) { - err = PTR_ERR(info->rdev); - dev_err(&pdev->dev, "failed to register %s: err %i\n", - info->desc.name, err); - return err; - } - - dev_dbg(rdev_get_dev(info->rdev), - "regulator-%s-probed\n", info->desc.name); + struct regulator_dev *rdev; + int err, i; - return 0; -} - -static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, -}; - -static int -db8500_regulator_of_probe(struct platform_device *pdev, - struct device_node *np) -{ - int i, err; + db8500_init_data = dev_get_platdata(&pdev->dev); for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { - err = db8500_regulator_register( - pdev, db8500_regulator_matches[i].init_data, - i, db8500_regulator_matches[i].of_node); - if (err) + /* assign per-regulator data */ + info = &dbx500_regulator_info[i]; + + config.driver_data = info; + config.dev = &pdev->dev; + if (db8500_init_data) + config.init_data = &db8500_init_data[i]; + + rdev = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(rdev)) { + err = PTR_ERR(rdev); + dev_err(&pdev->dev, "failed to register %s: err %i\n", + info->desc.name, err); return err; - } - - return 0; -} - -static int db8500_regulator_probe(struct platform_device *pdev) -{ - struct regulator_init_data *db8500_init_data = - dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; - int i, err; - - /* register all regulators */ - if (np) { - err = of_regulator_match(&pdev->dev, np, - db8500_regulator_matches, - ARRAY_SIZE(db8500_regulator_matches)); - if (err < 0) { - dev_err(&pdev->dev, - "Error parsing regulator init data: %d\n", err); - return err; - } - - err = db8500_regulator_of_probe(pdev, np); - if (err) - return err; - } else { - for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { - err = db8500_regulator_register(pdev, - &db8500_init_data[i], - i, NULL); - if (err) - return err; } + dev_dbg(&pdev->dev, "regulator-%s-probed\n", info->desc.name); } - err = ux500_regulator_debug_init(pdev, - dbx500_regulator_info, - ARRAY_SIZE(dbx500_regulator_info)); + ux500_regulator_debug_init(pdev, dbx500_regulator_info, + ARRAY_SIZE(dbx500_regulator_info)); return 0; } diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index 308e3ff0a1bd..f604c8db6d0e 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * - * License Terms: GNU General Public License v2 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson * diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h index c8e51ace9f06..2fb3aaef9dbb 100644 --- a/drivers/regulator/dbx500-prcmu.h +++ b/drivers/regulator/dbx500-prcmu.h @@ -1,11 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) ST-Ericsson SA 2010 * * Author: Bengt Jonsson <bengt.jonsson@stericsson.com> for ST-Ericsson, * Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson - * - * License Terms: GNU General Public License v2 - * */ #ifndef DBX500_REGULATOR_H @@ -15,18 +13,14 @@ /** * struct dbx500_regulator_info - dbx500 regulator information - * @dev: device pointer * @desc: regulator description - * @rdev: regulator device pointer * @is_enabled: status of the regulator * @epod_id: id for EPOD (power domain) * @is_ramret: RAM retention switch for EPOD (power domain) * */ struct dbx500_regulator_info { - struct device *dev; struct regulator_desc desc; - struct regulator_dev *rdev; bool is_enabled; u16 epod_id; bool is_ramret; diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 784e3bf32210..3ea1c170f840 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -1,13 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * devres.c -- Voltage/Current Regulator framework devres implementation. * * Copyright 2013 Linaro Ltd - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/kernel.h> diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index cde749778774..74de6983c61a 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * dummy.c * @@ -5,11 +6,6 @@ * * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * * This is useful for systems with mixed controllable and * non-controllable regulators, as well as for allowing testing on * systems with no controllable regulators. diff --git a/drivers/regulator/dummy.h b/drivers/regulator/dummy.h index 97a11b7e8882..c79e28209025 100644 --- a/drivers/regulator/dummy.h +++ b/drivers/regulator/dummy.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * dummy.h * @@ -5,11 +6,6 @@ * * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * * This is useful for systems with mixed controllable and * non-controllable regulators, as well as for allowing testing on * systems with no controllable regulators. diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index a3bc8037153e..dbe477da4e55 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -1,17 +1,13 @@ -/* - * FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver. - * - * Supported Part Numbers: - * FAN53555UC00X/01X/03X/04X/05X - * - * Copyright (c) 2012 Marvell Technology Ltd. - * Yunfan Zhang <yfzhang@marvell.com> - * - * This package 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. - * - */ +// SPDX-License-Identifier: GPL-2.0 +// +// FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver. +// +// Supported Part Numbers: +// FAN53555UC00X/01X/03X/04X/05X +// +// Copyright (c) 2012 Marvell Technology Ltd. +// Yunfan Zhang <yfzhang@marvell.com> + #include <linux/module.h> #include <linux/param.h> #include <linux/err.h> @@ -40,7 +36,6 @@ /* VSEL bit definitions */ #define VSEL_BUCK_EN (1 << 7) #define VSEL_MODE (1 << 6) -#define VSEL_NSEL_MASK 0x3F /* Chip ID and Verison */ #define DIE_ID 0x0F /* ID1 */ #define DIE_REV 0x0F /* ID2 */ @@ -49,14 +44,26 @@ #define CTL_SLEW_MASK (0x7 << 4) #define CTL_SLEW_SHIFT 4 #define CTL_RESET (1 << 2) +#define CTL_MODE_VSEL0_MODE BIT(0) +#define CTL_MODE_VSEL1_MODE BIT(1) #define FAN53555_NVOLTAGES 64 /* Numbers of voltages */ +#define FAN53526_NVOLTAGES 128 enum fan53555_vendor { - FAN53555_VENDOR_FAIRCHILD = 0, + FAN53526_VENDOR_FAIRCHILD = 0, + FAN53555_VENDOR_FAIRCHILD, FAN53555_VENDOR_SILERGY, }; +enum { + FAN53526_CHIP_ID_01 = 1, +}; + +enum { + FAN53526_CHIP_REV_08 = 8, +}; + /* IC Type */ enum { FAN53555_CHIP_ID_00 = 0, @@ -80,10 +87,8 @@ enum { struct fan53555_device_info { enum fan53555_vendor vendor; - struct regmap *regmap; struct device *dev; struct regulator_desc desc; - struct regulator_dev *rdev; struct regulator_init_data *regulator; /* IC Type and Rev */ int chip_id; @@ -94,8 +99,10 @@ struct fan53555_device_info { /* Voltage range and step(linear) */ unsigned int vsel_min; unsigned int vsel_step; - /* Voltage slew rate limiting */ - unsigned int slew_rate; + unsigned int vsel_count; + /* Mode */ + unsigned int mode_reg; + unsigned int mode_mask; /* Sleep voltage cache */ unsigned int sleep_vol_cache; }; @@ -110,8 +117,8 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) ret = regulator_map_voltage_linear(rdev, uV, uV); if (ret < 0) return ret; - ret = regmap_update_bits(di->regmap, di->sleep_reg, - VSEL_NSEL_MASK, ret); + ret = regmap_update_bits(rdev->regmap, di->sleep_reg, + di->desc.vsel_mask, ret); if (ret < 0) return ret; /* Cache the sleep voltage setting. @@ -125,7 +132,7 @@ 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, + return regmap_update_bits(rdev->regmap, di->sleep_reg, VSEL_BUCK_EN, VSEL_BUCK_EN); } @@ -133,7 +140,7 @@ 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, + return regmap_update_bits(rdev->regmap, di->sleep_reg, VSEL_BUCK_EN, 0); } @@ -143,11 +150,11 @@ static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode) switch (mode) { case REGULATOR_MODE_FAST: - regmap_update_bits(di->regmap, di->vol_reg, - VSEL_MODE, VSEL_MODE); + regmap_update_bits(rdev->regmap, di->mode_reg, + di->mode_mask, di->mode_mask); break; case REGULATOR_MODE_NORMAL: - regmap_update_bits(di->regmap, di->vol_reg, VSEL_MODE, 0); + regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0); break; default: return -EINVAL; @@ -161,10 +168,10 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev) unsigned int val; int ret = 0; - ret = regmap_read(di->regmap, di->vol_reg, &val); + ret = regmap_read(rdev->regmap, di->mode_reg, &val); if (ret < 0) return ret; - if (val & VSEL_MODE) + if (val & di->mode_mask) return REGULATOR_MODE_FAST; else return REGULATOR_MODE_NORMAL; @@ -198,7 +205,7 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) return -EINVAL; } - return regmap_update_bits(di->regmap, FAN53555_CONTROL, + return regmap_update_bits(rdev->regmap, FAN53555_CONTROL, CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT); } @@ -219,6 +226,34 @@ static const struct regulator_ops fan53555_regulator_ops = { .set_suspend_disable = fan53555_set_suspend_disable, }; +static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di) +{ + /* Init voltage range and step */ + switch (di->chip_id) { + case FAN53526_CHIP_ID_01: + switch (di->chip_rev) { + case FAN53526_CHIP_REV_08: + di->vsel_min = 600000; + di->vsel_step = 6250; + break; + default: + dev_err(di->dev, + "Chip ID %d with rev %d not supported!\n", + di->chip_id, di->chip_rev); + return -EINVAL; + } + break; + default: + dev_err(di->dev, + "Chip ID %d not supported!\n", di->chip_id); + return -EINVAL; + } + + di->vsel_count = FAN53526_NVOLTAGES; + + return 0; +} + static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) { /* Init voltage range and step */ @@ -257,6 +292,8 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di) return -EINVAL; } + di->vsel_count = FAN53555_NVOLTAGES; + return 0; } @@ -274,6 +311,8 @@ static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di) return -EINVAL; } + di->vsel_count = FAN53555_NVOLTAGES; + return 0; } @@ -302,7 +341,35 @@ static int fan53555_device_setup(struct fan53555_device_info *di, return -EINVAL; } + /* Setup mode control register */ + switch (di->vendor) { + case FAN53526_VENDOR_FAIRCHILD: + di->mode_reg = FAN53555_CONTROL; + + switch (pdata->sleep_vsel_id) { + case FAN53555_VSEL_ID_0: + di->mode_mask = CTL_MODE_VSEL1_MODE; + break; + case FAN53555_VSEL_ID_1: + di->mode_mask = CTL_MODE_VSEL0_MODE; + break; + } + break; + case FAN53555_VENDOR_FAIRCHILD: + case FAN53555_VENDOR_SILERGY: + di->mode_reg = di->vol_reg; + di->mode_mask = VSEL_MODE; + break; + default: + dev_err(di->dev, "vendor %d not supported!\n", di->vendor); + return -EINVAL; + } + + /* Setup voltage range */ switch (di->vendor) { + case FAN53526_VENDOR_FAIRCHILD: + ret = fan53526_voltages_setup_fairchild(di); + break; case FAN53555_VENDOR_FAIRCHILD: ret = fan53555_voltages_setup_fairchild(di); break; @@ -321,22 +388,23 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, struct regulator_config *config) { struct regulator_desc *rdesc = &di->desc; + struct regulator_dev *rdev; rdesc->name = "fan53555-reg"; rdesc->supply_name = "vin"; rdesc->ops = &fan53555_regulator_ops; rdesc->type = REGULATOR_VOLTAGE; - rdesc->n_voltages = FAN53555_NVOLTAGES; + rdesc->n_voltages = di->vsel_count; rdesc->enable_reg = di->vol_reg; rdesc->enable_mask = VSEL_BUCK_EN; rdesc->min_uV = di->vsel_min; rdesc->uV_step = di->vsel_step; rdesc->vsel_reg = di->vol_reg; - rdesc->vsel_mask = VSEL_NSEL_MASK; + rdesc->vsel_mask = di->vsel_count - 1; rdesc->owner = THIS_MODULE; - di->rdev = devm_regulator_register(di->dev, &di->desc, config); - return PTR_ERR_OR_ZERO(di->rdev); + rdev = devm_regulator_register(di->dev, &di->desc, config); + return PTR_ERR_OR_ZERO(rdev); } static const struct regmap_config fan53555_regmap_config = { @@ -368,6 +436,9 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, static const struct of_device_id fan53555_dt_ids[] = { { + .compatible = "fcs,fan53526", + .data = (void *)FAN53526_VENDOR_FAIRCHILD, + }, { .compatible = "fcs,fan53555", .data = (void *)FAN53555_VENDOR_FAIRCHILD }, { @@ -388,6 +459,7 @@ static int fan53555_regulator_probe(struct i2c_client *client, struct fan53555_device_info *di; struct fan53555_platform_data *pdata; struct regulator_config config = { }; + struct regmap *regmap; unsigned int val; int ret; @@ -412,32 +484,34 @@ static int fan53555_regulator_probe(struct i2c_client *client, } else { /* if no ramp constraint set, get the pdata ramp_delay */ if (!di->regulator->constraints.ramp_delay) { - int slew_idx = (pdata->slew_rate & 0x7) - ? pdata->slew_rate : 0; + if (pdata->slew_rate >= ARRAY_SIZE(slew_rates)) { + dev_err(&client->dev, "Invalid slew_rate\n"); + return -EINVAL; + } di->regulator->constraints.ramp_delay - = slew_rates[slew_idx]; + = slew_rates[pdata->slew_rate]; } di->vendor = id->driver_data; } - di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); - if (IS_ERR(di->regmap)) { + regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); + if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to allocate regmap!\n"); - return PTR_ERR(di->regmap); + return PTR_ERR(regmap); } di->dev = &client->dev; i2c_set_clientdata(client, di); /* Get chip ID */ - ret = regmap_read(di->regmap, FAN53555_ID1, &val); + ret = regmap_read(regmap, FAN53555_ID1, &val); if (ret < 0) { dev_err(&client->dev, "Failed to get chip ID!\n"); return ret; } di->chip_id = val & DIE_ID; /* Get chip revision */ - ret = regmap_read(di->regmap, FAN53555_ID2, &val); + ret = regmap_read(regmap, FAN53555_ID2, &val); if (ret < 0) { dev_err(&client->dev, "Failed to get chip Rev!\n"); return ret; @@ -454,7 +528,7 @@ static int fan53555_regulator_probe(struct i2c_client *client, /* Register regulator */ config.dev = di->dev; config.init_data = di->regulator; - config.regmap = di->regmap; + config.regmap = regmap; config.driver_data = di; config.of_node = np; @@ -467,6 +541,9 @@ static int fan53555_regulator_probe(struct i2c_client *client, static const struct i2c_device_id fan53555_id[] = { { + .name = "fan53526", + .driver_data = FAN53526_VENDOR_FAIRCHILD + }, { .name = "fan53555", .driver_data = FAN53555_VENDOR_FAIRCHILD }, { diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 9abdb9130766..999547dde99d 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * fixed.c * @@ -8,11 +9,6 @@ * Copyright (c) 2009 Nokia Corporation * Roger Quadros <ext-roger.quadros@nokia.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * * This is useful for systems with mixed controllable and * non-controllable regulators, as well as for allowing testing on * systems with no controllable regulators. @@ -79,15 +75,6 @@ of_get_fixed_voltage_config(struct device *dev, of_property_read_u32(np, "startup-delay-us", &config->startup_delay); - /* - * FIXME: we pulled active low/high and open drain handling into - * gpiolib so it will be handled there. Delete this in the second - * step when we also remove the custom inversion handling for all - * legacy boardfiles. - */ - config->enable_high = 1; - config->gpio_is_open_drain = 0; - if (of_find_property(np, "vin-supply", NULL)) config->input_supply = "vin"; @@ -151,24 +138,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) drvdata->desc.fixed_uV = config->microvolts; - cfg.ena_gpio_invert = !config->enable_high; - if (config->enabled_at_boot) { - if (config->enable_high) - gflags = GPIOD_OUT_HIGH; - else - gflags = GPIOD_OUT_LOW; - } else { - if (config->enable_high) - gflags = GPIOD_OUT_LOW; - else - gflags = GPIOD_OUT_HIGH; - } - if (config->gpio_is_open_drain) { - if (gflags == GPIOD_OUT_HIGH) - gflags = GPIOD_OUT_HIGH_OPEN_DRAIN; - else - gflags = GPIOD_OUT_LOW_OPEN_DRAIN; - } + /* + * The signal will be inverted by the GPIO core if flagged so in the + * decriptor. + */ + if (config->enabled_at_boot) + gflags = GPIOD_OUT_HIGH; + else + gflags = GPIOD_OUT_LOW; /* * Some fixed regulators share the enable line between two diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index b2f5ec4f658a..110ee6fe76c4 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * gpio-regulator.c * @@ -12,11 +13,6 @@ * Copyright (c) 2009 Nokia Corporation * Roger Quadros <ext-roger.quadros@nokia.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * * This is useful for systems with mixed controllable and * non-controllable regulators, as well as for allowing testing on * systems with no controllable regulators. @@ -30,16 +26,14 @@ #include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> #include <linux/regulator/gpio-regulator.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/of.h> -#include <linux/of_gpio.h> struct gpio_regulator_data { struct regulator_desc desc; - struct regulator_dev *dev; - struct gpio *gpios; + struct gpio_desc **gpiods; int nr_gpios; struct gpio_regulator_state *states; @@ -82,7 +76,7 @@ static int gpio_regulator_set_voltage(struct regulator_dev *dev, for (ptr = 0; ptr < data->nr_gpios; ptr++) { state = (target & (1 << ptr)) >> ptr; - gpio_set_value_cansleep(data->gpios[ptr].gpio, state); + gpiod_set_value_cansleep(data->gpiods[ptr], state); } data->state = target; @@ -119,14 +113,14 @@ static int gpio_regulator_set_current_limit(struct regulator_dev *dev, for (ptr = 0; ptr < data->nr_gpios; ptr++) { state = (target & (1 << ptr)) >> ptr; - gpio_set_value_cansleep(data->gpios[ptr].gpio, state); + gpiod_set_value_cansleep(data->gpiods[ptr], state); } data->state = target; return 0; } -static struct regulator_ops gpio_regulator_voltage_ops = { +static const struct regulator_ops gpio_regulator_voltage_ops = { .get_voltage = gpio_regulator_get_value, .set_voltage = gpio_regulator_set_voltage, .list_voltage = gpio_regulator_list_voltage, @@ -138,7 +132,8 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, { struct gpio_regulator_config *config; const char *regtype; - int proplen, gpio, i; + int proplen, i; + int ngpios; int ret; config = devm_kzalloc(dev, @@ -153,59 +148,36 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, config->supply_name = config->init_data->constraints.name; - if (of_property_read_bool(np, "enable-active-high")) - config->enable_high = true; - if (of_property_read_bool(np, "enable-at-boot")) config->enabled_at_boot = true; of_property_read_u32(np, "startup-delay-us", &config->startup_delay); - config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); - if (config->enable_gpio < 0 && config->enable_gpio != -ENOENT) - return ERR_PTR(config->enable_gpio); - - /* Fetch GPIOs. - optional property*/ - ret = of_gpio_count(np); - if ((ret < 0) && (ret != -ENOENT)) - return ERR_PTR(ret); - - if (ret > 0) { - config->nr_gpios = ret; - config->gpios = devm_kcalloc(dev, - config->nr_gpios, sizeof(struct gpio), - GFP_KERNEL); - if (!config->gpios) + /* Fetch GPIO init levels */ + ngpios = gpiod_count(dev, NULL); + if (ngpios > 0) { + config->gflags = devm_kzalloc(dev, + sizeof(enum gpiod_flags) + * ngpios, + GFP_KERNEL); + if (!config->gflags) return ERR_PTR(-ENOMEM); - proplen = of_property_count_u32_elems(np, "gpios-states"); - /* optional property */ - if (proplen < 0) - proplen = 0; + for (i = 0; i < ngpios; i++) { + u32 val; - if (proplen > 0 && proplen != config->nr_gpios) { - dev_warn(dev, "gpios <-> gpios-states mismatch\n"); - proplen = 0; - } + ret = of_property_read_u32_index(np, "gpios-states", i, + &val); - for (i = 0; i < config->nr_gpios; i++) { - gpio = of_get_named_gpio(np, "gpios", i); - if (gpio < 0) { - if (gpio != -ENOENT) - return ERR_PTR(gpio); - break; - } - config->gpios[i].gpio = gpio; - config->gpios[i].label = config->supply_name; - if (proplen > 0) { - of_property_read_u32_index(np, "gpios-states", - i, &ret); - if (ret) - config->gpios[i].flags = - GPIOF_OUT_INIT_HIGH; - } + /* Default to high per specification */ + if (ret) + config->gflags[i] = GPIOD_OUT_HIGH; + else + config->gflags[i] = + val ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; } } + config->ngpios = ngpios; /* Fetch states. */ proplen = of_property_count_u32_elems(np, "states"); @@ -244,66 +216,64 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, return config; } -static struct regulator_ops gpio_regulator_current_ops = { +static const struct regulator_ops gpio_regulator_current_ops = { .get_current_limit = gpio_regulator_get_value, .set_current_limit = gpio_regulator_set_current_limit, }; static int gpio_regulator_probe(struct platform_device *pdev) { - struct gpio_regulator_config *config = dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct gpio_regulator_config *config = dev_get_platdata(dev); + struct device_node *np = dev->of_node; struct gpio_regulator_data *drvdata; struct regulator_config cfg = { }; - int ptr, ret, state; + struct regulator_dev *rdev; + enum gpiod_flags gflags; + int ptr, ret, state, i; - drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), + drvdata = devm_kzalloc(dev, sizeof(struct gpio_regulator_data), GFP_KERNEL); if (drvdata == NULL) return -ENOMEM; if (np) { - config = of_get_gpio_regulator_config(&pdev->dev, np, + config = of_get_gpio_regulator_config(dev, np, &drvdata->desc); if (IS_ERR(config)) return PTR_ERR(config); } - drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); + drvdata->desc.name = devm_kstrdup(dev, config->supply_name, GFP_KERNEL); if (drvdata->desc.name == NULL) { - dev_err(&pdev->dev, "Failed to allocate supply name\n"); + dev_err(dev, "Failed to allocate supply name\n"); return -ENOMEM; } - if (config->nr_gpios != 0) { - drvdata->gpios = kmemdup(config->gpios, - config->nr_gpios * sizeof(struct gpio), - GFP_KERNEL); - if (drvdata->gpios == NULL) { - dev_err(&pdev->dev, "Failed to allocate gpio data\n"); - ret = -ENOMEM; - goto err_name; - } - - drvdata->nr_gpios = config->nr_gpios; - ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(&pdev->dev, - "Could not obtain regulator setting GPIOs: %d\n", - ret); - goto err_memgpio; - } + drvdata->gpiods = devm_kzalloc(dev, sizeof(struct gpio_desc *), + GFP_KERNEL); + if (!drvdata->gpiods) + return -ENOMEM; + for (i = 0; i < config->ngpios; i++) { + drvdata->gpiods[i] = devm_gpiod_get_index(dev, + NULL, + i, + config->gflags[i]); + if (IS_ERR(drvdata->gpiods[i])) + return PTR_ERR(drvdata->gpiods[i]); + /* This is good to know */ + gpiod_set_consumer_name(drvdata->gpiods[i], drvdata->desc.name); } + drvdata->nr_gpios = config->ngpios; - drvdata->states = kmemdup(config->states, - config->nr_states * - sizeof(struct gpio_regulator_state), - GFP_KERNEL); + drvdata->states = devm_kmemdup(dev, + config->states, + config->nr_states * + sizeof(struct gpio_regulator_state), + GFP_KERNEL); if (drvdata->states == NULL) { - dev_err(&pdev->dev, "Failed to allocate state data\n"); - ret = -ENOMEM; - goto err_stategpio; + dev_err(dev, "Failed to allocate state data\n"); + return -ENOMEM; } drvdata->nr_states = config->nr_states; @@ -322,77 +292,46 @@ static int gpio_regulator_probe(struct platform_device *pdev) drvdata->desc.ops = &gpio_regulator_current_ops; break; default: - dev_err(&pdev->dev, "No regulator type set\n"); - ret = -EINVAL; - goto err_memstate; + dev_err(dev, "No regulator type set\n"); + return -EINVAL; } /* build initial state from gpio init data. */ state = 0; for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) { - if (config->gpios[ptr].flags & GPIOF_OUT_INIT_HIGH) + if (config->gflags[ptr] == GPIOD_OUT_HIGH) state |= (1 << ptr); } drvdata->state = state; - cfg.dev = &pdev->dev; + cfg.dev = dev; cfg.init_data = config->init_data; cfg.driver_data = drvdata; cfg.of_node = np; - if (gpio_is_valid(config->enable_gpio)) { - cfg.ena_gpio = config->enable_gpio; - cfg.ena_gpio_initialized = true; - } - cfg.ena_gpio_invert = !config->enable_high; - if (config->enabled_at_boot) { - if (config->enable_high) - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - else - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; - } else { - if (config->enable_high) - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW; - else - cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; - } - - drvdata->dev = regulator_register(&drvdata->desc, &cfg); - if (IS_ERR(drvdata->dev)) { - ret = PTR_ERR(drvdata->dev); - dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); - goto err_memstate; + /* + * The signal will be inverted by the GPIO core if flagged so in the + * decriptor. + */ + if (config->enabled_at_boot) + gflags = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE; + else + gflags = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE; + + cfg.ena_gpiod = gpiod_get_optional(dev, "enable", gflags); + if (IS_ERR(cfg.ena_gpiod)) + return PTR_ERR(cfg.ena_gpiod); + + rdev = devm_regulator_register(dev, &drvdata->desc, &cfg); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(dev, "Failed to register regulator: %d\n", ret); + return ret; } platform_set_drvdata(pdev, drvdata); return 0; - -err_memstate: - kfree(drvdata->states); -err_stategpio: - gpio_free_array(drvdata->gpios, drvdata->nr_gpios); -err_memgpio: - kfree(drvdata->gpios); -err_name: - kfree(drvdata->desc.name); - return ret; -} - -static int gpio_regulator_remove(struct platform_device *pdev) -{ - struct gpio_regulator_data *drvdata = platform_get_drvdata(pdev); - - regulator_unregister(drvdata->dev); - - gpio_free_array(drvdata->gpios, drvdata->nr_gpios); - - kfree(drvdata->states); - kfree(drvdata->gpios); - - kfree(drvdata->desc.name); - - return 0; } #if defined(CONFIG_OF) @@ -405,7 +344,6 @@ MODULE_DEVICE_TABLE(of, regulator_gpio_of_match); static struct platform_driver gpio_regulator_driver = { .probe = gpio_regulator_probe, - .remove = gpio_regulator_remove, .driver = { .name = "gpio-regulator", .of_match_table = of_match_ptr(regulator_gpio_of_match), diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index 5686a1335bd3..b9ae45d2d199 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c @@ -1,14 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * helpers.c -- Voltage/Current Regulator framework helper functions. * * Copyright 2007, 2008 Wolfson Microelectronics PLC. * Copyright 2008 SlimLogic Ltd. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/kernel.h> @@ -594,28 +589,30 @@ int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev, EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range); /** - * regulator_list_voltage_linear_range - List voltages for linear ranges + * regulator_desc_list_voltage_linear_range - List voltages for linear ranges * - * @rdev: Regulator device + * @desc: Regulator desc for regulator which volatges are to be listed * @selector: Selector to convert into a voltage * * Regulators with a series of simple linear mappings between voltages - * and selectors can set linear_ranges in the regulator descriptor and - * then use this function as their list_voltage() operation, + * and selectors who have set linear_ranges in the regulator descriptor + * can use this function prior regulator registration to list voltages. + * This is useful when voltages need to be listed during device-tree + * parsing. */ -int regulator_list_voltage_linear_range(struct regulator_dev *rdev, - unsigned int selector) +int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc, + unsigned int selector) { const struct regulator_linear_range *range; int i; - if (!rdev->desc->n_linear_ranges) { - BUG_ON(!rdev->desc->n_linear_ranges); + if (!desc->n_linear_ranges) { + BUG_ON(!desc->n_linear_ranges); return -EINVAL; } - for (i = 0; i < rdev->desc->n_linear_ranges; i++) { - range = &rdev->desc->linear_ranges[i]; + for (i = 0; i < desc->n_linear_ranges; i++) { + range = &desc->linear_ranges[i]; if (!(selector >= range->min_sel && selector <= range->max_sel)) @@ -628,6 +625,23 @@ int regulator_list_voltage_linear_range(struct regulator_dev *rdev, return -EINVAL; } +EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range); + +/** + * regulator_list_voltage_linear_range - List voltages for linear ranges + * + * @rdev: Regulator device + * @selector: Selector to convert into a voltage + * + * Regulators with a series of simple linear mappings between voltages + * and selectors can set linear_ranges in the regulator descriptor and + * then use this function as their list_voltage() operation, + */ +int regulator_list_voltage_linear_range(struct regulator_dev *rdev, + unsigned int selector) +{ + return regulator_desc_list_voltage_linear_range(rdev->desc, selector); +} EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range); /** @@ -761,3 +775,89 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev, rdev->desc->active_discharge_mask, val); } EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap); + +/** + * regulator_set_current_limit_regmap - set_current_limit for regmap users + * + * @rdev: regulator to operate on + * @min_uA: Lower bound for current limit + * @max_uA: Upper bound for current limit + * + * Regulators that use regmap for their register I/O can set curr_table, + * csel_reg and csel_mask fields in their descriptor and then use this + * as their set_current_limit operation, saving some code. + */ +int regulator_set_current_limit_regmap(struct regulator_dev *rdev, + int min_uA, int max_uA) +{ + unsigned int n_currents = rdev->desc->n_current_limits; + int i, sel = -1; + + if (n_currents == 0) + return -EINVAL; + + if (rdev->desc->curr_table) { + const unsigned int *curr_table = rdev->desc->curr_table; + bool ascend = curr_table[n_currents - 1] > curr_table[0]; + + /* search for closest to maximum */ + if (ascend) { + for (i = n_currents - 1; i >= 0; i--) { + if (min_uA <= curr_table[i] && + curr_table[i] <= max_uA) { + sel = i; + break; + } + } + } else { + for (i = 0; i < n_currents; i++) { + if (min_uA <= curr_table[i] && + curr_table[i] <= max_uA) { + sel = i; + break; + } + } + } + } + + if (sel < 0) + return -EINVAL; + + sel <<= ffs(rdev->desc->csel_mask) - 1; + + return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg, + rdev->desc->csel_mask, sel); +} +EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap); + +/** + * regulator_get_current_limit_regmap - get_current_limit for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * csel_reg and csel_mask fields in their descriptor and then use this + * as their get_current_limit operation, saving some code. + */ +int regulator_get_current_limit_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val); + if (ret != 0) + return ret; + + val &= rdev->desc->csel_mask; + val >>= ffs(rdev->desc->csel_mask) - 1; + + if (rdev->desc->curr_table) { + if (val >= rdev->desc->n_current_limits) + return -EINVAL; + + return rdev->desc->curr_table[val]; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap); diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index 259c3a865ac6..5ac3d7c29725 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -1,17 +1,13 @@ -/* - * Device driver for regulators in Hi6421 IC - * - * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. - * http://www.hisilicon.com - * Copyright (c) <2013-2014> Linaro Ltd. - * http://www.linaro.org - * - * Author: Guodong Xu <guodong.xu@linaro.org> - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Device driver for regulators in Hi6421 IC +// +// Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. +// http://www.hisilicon.com +// Copyright (c) <2013-2014> Linaro Ltd. +// http://www.linaro.org +// +// Author: Guodong Xu <guodong.xu@linaro.org> #include <linux/slab.h> #include <linux/device.h> @@ -78,43 +74,6 @@ enum hi6421_regulator_id { HI6421_NUM_REGULATORS, }; -#define HI6421_REGULATOR_OF_MATCH(_name, id) \ -{ \ - .name = #_name, \ - .driver_data = (void *) HI6421_##id, \ -} - -static struct of_regulator_match hi6421_regulator_match[] = { - HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0), - HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1), - HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2), - HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3), - HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4), - HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5), - HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6), - HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7), - HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8), - HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9), - HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10), - HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11), - HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12), - HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13), - HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14), - HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15), - HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16), - HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17), - HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18), - HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19), - HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20), - HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO), - HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0), - HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1), - HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2), - HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3), - HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4), - HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5), -}; - /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */ static const unsigned int ldo_0_voltages[] = { 1500000, 1800000, 2400000, 2500000, @@ -157,6 +116,7 @@ static const struct regulator_ops hi6421_buck345_ops; #define HI6421_LDO_ENABLE_TIME (350) /* * _id - LDO id name string + * _match - of match name string * v_table - voltage table * vreg - voltage select register * vmask - voltage select mask @@ -166,11 +126,13 @@ static const struct regulator_ops hi6421_buck345_ops; * ecomask - eco mode mask * ecoamp - eco mode load uppler limit in uA */ -#define HI6421_LDO(_id, v_table, vreg, vmask, ereg, emask, \ +#define HI6421_LDO(_id, _match, v_table, vreg, vmask, ereg, emask, \ odelay, ecomask, ecoamp) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -191,6 +153,7 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step * * _id - LDO id name string + * _match - of match name string * _min_uV - minimum voltage supported in uV * n_volt - number of votages available * vstep - voltage increase in each linear step in uV @@ -202,11 +165,13 @@ static const struct regulator_ops hi6421_buck345_ops; * ecomask - eco mode mask * ecoamp - eco mode load uppler limit in uA */ -#define HI6421_LDO_LINEAR(_id, _min_uV, n_volt, vstep, vreg, vmask, \ +#define HI6421_LDO_LINEAR(_id, _match, _min_uV, n_volt, vstep, vreg, vmask,\ ereg, emask, odelay, ecomask, ecoamp) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_ldo_linear_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -228,6 +193,7 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges * * _id - LDO id name string + * _match - of match name string * n_volt - number of votages available * volt_ranges - array of regulator_linear_range * vstep - voltage increase in each linear step in uV @@ -239,11 +205,13 @@ static const struct regulator_ops hi6421_buck345_ops; * ecomask - eco mode mask * ecoamp - eco mode load uppler limit in uA */ -#define HI6421_LDO_LINEAR_RANGE(_id, n_volt, volt_ranges, vreg, vmask, \ +#define HI6421_LDO_LINEAR_RANGE(_id, _match, n_volt, volt_ranges, vreg, vmask,\ ereg, emask, odelay, ecomask, ecoamp) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_ldo_linear_range_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -265,6 +233,7 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step * * _id - BUCK0/1/2 id name string + * _match - of match name string * vreg - voltage select register * vmask - voltage select mask * ereg - enable register @@ -273,11 +242,13 @@ static const struct regulator_ops hi6421_buck345_ops; * etime - enable time * odelay - off/on delay time in uS */ -#define HI6421_BUCK012(_id, vreg, vmask, ereg, emask, sleepmask, \ +#define HI6421_BUCK012(_id, _match, vreg, vmask, ereg, emask, sleepmask,\ etime, odelay) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_buck012_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -299,6 +270,7 @@ static const struct regulator_ops hi6421_buck345_ops; * that it supports SLEEP mode, so has different .ops. * * _id - LDO id name string + * _match - of match name string * v_table - voltage table * vreg - voltage select register * vmask - voltage select mask @@ -307,11 +279,13 @@ static const struct regulator_ops hi6421_buck345_ops; * odelay - off/on delay time in uS * sleepmask - mask of sleep mode */ -#define HI6421_BUCK345(_id, v_table, vreg, vmask, ereg, emask, \ +#define HI6421_BUCK345(_id, _match, v_table, vreg, vmask, ereg, emask, \ odelay, sleepmask) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_buck345_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -331,59 +305,63 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 regulator information */ static struct hi6421_regulator_info hi6421_regulator_info[HI6421_NUM_REGULATORS] = { - HI6421_LDO(LDO0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10, + HI6421_LDO(LDO0, hi6421_vout0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10, 10000, 0x20, 8000), - HI6421_LDO_LINEAR(LDO1, 1700000, 4, 100000, 0x21, 0x03, 0x21, 0x10, - 10000, 0x20, 5000), - HI6421_LDO_LINEAR(LDO2, 1050000, 8, 50000, 0x22, 0x07, 0x22, 0x10, - 20000, 0x20, 8000), - HI6421_LDO_LINEAR(LDO3, 1050000, 8, 50000, 0x23, 0x07, 0x23, 0x10, - 20000, 0x20, 8000), - HI6421_LDO(LDO4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10, + HI6421_LDO_LINEAR(LDO1, hi6421_vout1, 1700000, 4, 100000, 0x21, 0x03, + 0x21, 0x10, 10000, 0x20, 5000), + HI6421_LDO_LINEAR(LDO2, hi6421_vout2, 1050000, 8, 50000, 0x22, 0x07, + 0x22, 0x10, 20000, 0x20, 8000), + HI6421_LDO_LINEAR(LDO3, hi6421_vout3, 1050000, 8, 50000, 0x23, 0x07, + 0x23, 0x10, 20000, 0x20, 8000), + HI6421_LDO(LDO4, hi6421_vout4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10, + HI6421_LDO(LDO5, hi6421_vout5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10, + HI6421_LDO(LDO6, hi6421_vout6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10, + HI6421_LDO(LDO7, hi6421_vout7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10, 20000, 0x20, 5000), - HI6421_LDO(LDO8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10, + HI6421_LDO(LDO8, hi6421_vout8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10, + HI6421_LDO(LDO9, hi6421_vout9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10, + HI6421_LDO(LDO10, hi6421_vout10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10, + HI6421_LDO(LDO11, hi6421_vout11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10, + HI6421_LDO(LDO12, hi6421_vout12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10, + HI6421_LDO(LDO13, hi6421_vout13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10, + HI6421_LDO(LDO14, hi6421_vout14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10, + HI6421_LDO(LDO15, hi6421_vout15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10, + HI6421_LDO(LDO16, hi6421_vout16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10, + HI6421_LDO(LDO17, hi6421_vout17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10, + HI6421_LDO(LDO18, hi6421_vout18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10, + HI6421_LDO(LDO19, hi6421_vout19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10, + HI6421_LDO(LDO20, hi6421_vout20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10, 40000, 0x20, 8000), - HI6421_LDO_LINEAR_RANGE(LDOAUDIO, 8, ldo_audio_volt_range, 0x36, - 0x70, 0x36, 0x01, 40000, 0x02, 5000), - HI6421_BUCK012(BUCK0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, 20000), - HI6421_BUCK012(BUCK1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, 20000), - HI6421_BUCK012(BUCK2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, 100), - HI6421_BUCK345(BUCK3, buck_3_voltages, 0x13, 0x07, 0x12, 0x01, - 20000, 0x10), - HI6421_BUCK345(BUCK4, buck_4_voltages, 0x15, 0x07, 0x14, 0x01, - 20000, 0x10), - HI6421_BUCK345(BUCK5, buck_5_voltages, 0x17, 0x07, 0x16, 0x01, - 20000, 0x10), + HI6421_LDO_LINEAR_RANGE(LDOAUDIO, hi6421_vout_audio, 8, + ldo_audio_volt_range, 0x36, 0x70, 0x36, 0x01, + 40000, 0x02, 5000), + HI6421_BUCK012(BUCK0, hi6421_buck0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, + 20000), + HI6421_BUCK012(BUCK1, hi6421_buck1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, + 20000), + HI6421_BUCK012(BUCK2, hi6421_buck2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, + 100), + HI6421_BUCK345(BUCK3, hi6421_buck3, buck_3_voltages, 0x13, 0x07, 0x12, + 0x01, 20000, 0x10), + HI6421_BUCK345(BUCK4, hi6421_buck4, buck_4_voltages, 0x15, 0x07, 0x14, + 0x01, 20000, 0x10), + HI6421_BUCK345(BUCK5, hi6421_buck5, buck_5_voltages, 0x17, 0x07, 0x16, + 0x01, 20000, 0x10), }; static int hi6421_regulator_enable(struct regulator_dev *rdev) @@ -552,42 +530,14 @@ static const struct regulator_ops hi6421_buck345_ops = { .set_mode = hi6421_regulator_buck_set_mode, }; -static int hi6421_regulator_register(struct platform_device *pdev, - struct regmap *rmap, - struct regulator_init_data *init_data, - int id, struct device_node *np) -{ - struct hi6421_regulator_info *info = NULL; - struct regulator_config config = { }; - struct regulator_dev *rdev; - - /* assign per-regulator data */ - info = &hi6421_regulator_info[id]; - - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = info; - config.regmap = rmap; - config.of_node = np; - - /* register regulator with framework */ - rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - info->desc.name); - return PTR_ERR(rdev); - } - - return 0; -} - static int hi6421_regulator_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct device_node *np; - struct hi6421_pmic *pmic; + struct hi6421_pmic *pmic = dev_get_drvdata(pdev->dev.parent); struct hi6421_regulator_pdata *pdata; - int i, ret = 0; + struct hi6421_regulator_info *info; + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -595,27 +545,21 @@ static int hi6421_regulator_probe(struct platform_device *pdev) mutex_init(&pdata->lock); platform_set_drvdata(pdev, pdata); - np = of_get_child_by_name(dev->parent->of_node, "regulators"); - if (!np) - return -ENODEV; - - ret = of_regulator_match(dev, np, - hi6421_regulator_match, - ARRAY_SIZE(hi6421_regulator_match)); - of_node_put(np); - if (ret < 0) { - dev_err(dev, "Error parsing regulator init data: %d\n", ret); - return ret; - } - - pmic = dev_get_drvdata(dev->parent); - for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { - ret = hi6421_regulator_register(pdev, pmic->regmap, - hi6421_regulator_match[i].init_data, i, - hi6421_regulator_match[i].of_node); - if (ret) - return ret; + /* assign per-regulator data */ + info = &hi6421_regulator_info[i]; + + config.dev = pdev->dev.parent; + config.driver_data = info; + config.regmap = pmic->regmap; + + rdev = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + info->desc.name); + return PTR_ERR(rdev); + } } return 0; diff --git a/drivers/regulator/hi6421v530-regulator.c b/drivers/regulator/hi6421v530-regulator.c index c09bc71538a5..06ae65199afd 100644 --- a/drivers/regulator/hi6421v530-regulator.c +++ b/drivers/regulator/hi6421v530-regulator.c @@ -1,18 +1,14 @@ -/* - * Device driver for regulators in Hi6421V530 IC - * - * Copyright (c) <2017> HiSilicon Technologies Co., Ltd. - * http://www.hisilicon.com - * Copyright (c) <2017> Linaro Ltd. - * http://www.linaro.org - * - * Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com> - * Guodong Xu <guodong.xu@linaro.org> - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Device driver for regulators in Hi6421V530 IC +// +// Copyright (c) <2017> HiSilicon Technologies Co., Ltd. +// http://www.hisilicon.com +// Copyright (c) <2017> Linaro Ltd. +// http://www.linaro.org +// +// Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com> +// Guodong Xu <guodong.xu@linaro.org> #include <linux/mfd/hi6421-pmic.h> #include <linux/module.h> diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index 36ae54b53814..ac2ee2030211 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -1,16 +1,12 @@ -/* - * 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. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Device driver for regulators in Hi655x IC +// +// Copyright (c) 2016 Hisilicon. +// +// Authors: +// Chen Feng <puck.chen@hisilicon.com> +// Fei Wang <w.f@huawei.com> #include <linux/bitops.h> #include <linux/device.h> @@ -28,8 +24,6 @@ struct hi655x_regulator { unsigned int disable_reg; unsigned int status_reg; - unsigned int ctrl_regs; - unsigned int ctrl_mask; struct regulator_desc rdesc; }; @@ -78,22 +72,18 @@ enum hi655x_regulator_id { 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)); + return (value & rdev->desc->enable_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; + return regmap_write(rdev->regmap, regulator->disable_reg, + rdev->desc->enable_mask); } static const struct regulator_ops hi655x_regulator_ops = { @@ -133,7 +123,6 @@ static const struct regulator_ops hi655x_ldo_linear_ops = { }, \ .disable_reg = HI655X_BUS_ADDR(dreg), \ .status_reg = HI655X_BUS_ADDR(sreg), \ - .ctrl_mask = cmask, \ } #define HI655X_LDO_LINEAR(_ID, vreg, vmask, ereg, dreg, \ @@ -156,10 +145,9 @@ static const struct regulator_ops hi655x_ldo_linear_ops = { }, \ .disable_reg = HI655X_BUS_ADDR(dreg), \ .status_reg = HI655X_BUS_ADDR(sreg), \ - .ctrl_mask = cmask, \ } -static struct hi655x_regulator regulators[] = { +static const 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), diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 6017f15c5d75..83ae442f515b 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * internal.h -- Voltage/Current Regulator framework internal code * @@ -5,12 +6,6 @@ * Copyright 2008 SlimLogic Ltd. * * Author: Liam Girdwood <lrg@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #ifndef __REGULATOR_INTERNAL_H diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c index 4abd8e9c81e5..6f28bba81d13 100644 --- a/drivers/regulator/isl6271a-regulator.c +++ b/drivers/regulator/isl6271a-regulator.c @@ -31,7 +31,6 @@ /* PMIC details */ struct isl_pmic { struct i2c_client *client; - struct regulator_dev *rdev[3]; struct mutex mtx; }; @@ -66,14 +65,14 @@ static int isl6271a_set_voltage_sel(struct regulator_dev *dev, return err; } -static struct regulator_ops isl_core_ops = { +static const struct regulator_ops isl_core_ops = { .get_voltage_sel = isl6271a_get_voltage_sel, .set_voltage_sel = isl6271a_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; -static struct regulator_ops isl_fixed_ops = { +static const struct regulator_ops isl_fixed_ops = { .list_voltage = regulator_list_voltage_linear, }; @@ -109,6 +108,7 @@ static const struct regulator_desc isl_rd[] = { static int isl6271a_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct regulator_dev *rdev; struct regulator_config config = { }; struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev); struct isl_pmic *pmic; @@ -133,11 +133,10 @@ static int isl6271a_probe(struct i2c_client *i2c, config.init_data = NULL; config.driver_data = pmic; - pmic->rdev[i] = devm_regulator_register(&i2c->dev, &isl_rd[i], - &config); - if (IS_ERR(pmic->rdev[i])) { + rdev = devm_regulator_register(&i2c->dev, &isl_rd[i], &config); + if (IS_ERR(rdev)) { dev_err(&i2c->dev, "failed to register %s\n", id->name); - return PTR_ERR(pmic->rdev[i]); + return PTR_ERR(rdev); } } diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c index 9c2607e912cf..978f5e903cae 100644 --- a/drivers/regulator/isl9305.c +++ b/drivers/regulator/isl9305.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * isl9305 - Intersil ISL9305 DCDC regulator * * Copyright 2014 Linaro Ltd * * Author: Mark Brown <broonie@kernel.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/module.h> diff --git a/drivers/regulator/lm363x-regulator.c b/drivers/regulator/lm363x-regulator.c index 8c0e8419c43f..60f15a722760 100644 --- a/drivers/regulator/lm363x-regulator.c +++ b/drivers/regulator/lm363x-regulator.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * 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> @@ -48,7 +45,7 @@ static const int ldo_cont_enable_time[] = { static int lm363x_regulator_enable_time(struct regulator_dev *rdev) { enum lm363x_regulator_id id = rdev_get_id(rdev); - u8 val, addr, mask; + unsigned int val, addr, mask; switch (id) { case LM3631_LDO_CONT: @@ -71,7 +68,7 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev) return 0; } - if (regmap_read(rdev->regmap, addr, (unsigned int *)&val)) + if (regmap_read(rdev->regmap, addr, &val)) return -EINVAL; val = (val & mask) >> LM3631_ENTIME_SHIFT; @@ -82,13 +79,13 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev) return ENABLE_TIME_USEC * val; } -static struct regulator_ops lm363x_boost_voltage_table_ops = { +static const 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 = { +static const 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, @@ -258,6 +255,9 @@ static int lm363x_regulator_probe(struct platform_device *pdev) * Register update is required if the pin is used. */ gpiod = lm363x_regulator_of_get_enable_gpio(dev, id); + if (IS_ERR(gpiod)) + return PTR_ERR(gpiod); + if (gpiod) { cfg.ena_gpiod = gpiod; @@ -265,8 +265,7 @@ static int lm363x_regulator_probe(struct platform_device *pdev) LM3632_EXT_EN_MASK, LM3632_EXT_EN_MASK); if (ret) { - if (gpiod) - gpiod_put(gpiod); + gpiod_put(gpiod); dev_err(dev, "External pin err: %d\n", ret); return ret; } diff --git a/drivers/regulator/lochnagar-regulator.c b/drivers/regulator/lochnagar-regulator.c index 5a89e6d4b9a6..ff97cc50f2eb 100644 --- a/drivers/regulator/lochnagar-regulator.c +++ b/drivers/regulator/lochnagar-regulator.c @@ -194,7 +194,7 @@ static const struct regulator_desc lochnagar_regulators[] = { .name = "VDDCORE", .supply_name = "SYSVDD", .type = REGULATOR_VOLTAGE, - .n_voltages = 57, + .n_voltages = 66, .ops = &lochnagar_vddcore_ops, .id = LOCHNAGAR_VDDCORE, @@ -226,14 +226,15 @@ static const struct of_device_id lochnagar_of_match[] = { }, { .compatible = "cirrus,lochnagar2-mic2vdd", - .data = &lochnagar_regulators[LOCHNAGAR_MIC1VDD], + .data = &lochnagar_regulators[LOCHNAGAR_MIC2VDD], }, { .compatible = "cirrus,lochnagar2-vddcore", .data = &lochnagar_regulators[LOCHNAGAR_VDDCORE], }, - {}, + {} }; +MODULE_DEVICE_TABLE(of, lochnagar_of_match); static int lochnagar_regulator_probe(struct platform_device *pdev) { diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 204b5c5270e0..bc96e65ef7c0 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for National Semiconductors LP3971 PMIC chip * @@ -5,11 +6,6 @@ * Author: Marek Szyprowski <m.szyprowski@samsung.com> * * Based on wm8350.c - * - * 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/bug.h> @@ -159,7 +155,7 @@ static int lp3971_ldo_set_voltage_sel(struct regulator_dev *dev, selector << LDO_VOL_CONTR_SHIFT(ldo)); } -static struct regulator_ops lp3971_ldo_ops = { +static const struct regulator_ops lp3971_ldo_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .is_enabled = lp3971_ldo_is_enabled, @@ -233,7 +229,7 @@ static int lp3971_dcdc_set_voltage_sel(struct regulator_dev *dev, 0 << BUCK_VOL_CHANGE_SHIFT(buck)); } -static struct regulator_ops lp3971_dcdc_ops = { +static const struct regulator_ops lp3971_dcdc_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .is_enabled = lp3971_dcdc_is_enabled, diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c index ff0c275f902e..2d276bbeedf2 100644 --- a/drivers/regulator/lp3972.c +++ b/drivers/regulator/lp3972.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for National Semiconductors LP3972 PMIC chip * * Based on lp3971.c - * - * 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/bug.h> @@ -305,7 +301,7 @@ static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev, return ret; } -static struct regulator_ops lp3972_ldo_ops = { +static const struct regulator_ops lp3972_ldo_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .is_enabled = lp3972_ldo_is_enabled, @@ -386,7 +382,7 @@ static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev, LP3972_VOL_CHANGE_FLAG_MASK, 0); } -static struct regulator_ops lp3972_dcdc_ops = { +static const struct regulator_ops lp3972_dcdc_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .is_enabled = lp3972_dcdc_is_enabled, diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 38992112fd6e..303d7e2dc838 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2012 Texas Instruments * * Author: Milo(Woogyom) 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/module.h> @@ -353,64 +349,6 @@ static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev) return val & LP872X_VOUT_M; } -static int lp8725_buck_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - int i; - u8 addr; - - switch (buck) { - case LP8725_ID_BUCK1: - addr = LP8725_BUCK1_VOUT2; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK2_VOUT2; - break; - default: - return -EINVAL; - } - - for (i = ARRAY_SIZE(lp8725_buck_uA) - 1; i >= 0; i--) { - if (lp8725_buck_uA[i] >= min_uA && - lp8725_buck_uA[i] <= max_uA) - return lp872x_update_bits(lp, addr, - LP8725_BUCK_CL_M, - i << LP8725_BUCK_CL_S); - } - - return -EINVAL; -} - -static int lp8725_buck_get_current_limit(struct regulator_dev *rdev) -{ - struct lp872x *lp = rdev_get_drvdata(rdev); - enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, val; - int ret; - - switch (buck) { - case LP8725_ID_BUCK1: - addr = LP8725_BUCK1_VOUT2; - break; - case LP8725_ID_BUCK2: - addr = LP8725_BUCK2_VOUT2; - break; - default: - return -EINVAL; - } - - ret = lp872x_read_byte(lp, addr, &val); - if (ret) - return ret; - - val = (val & LP8725_BUCK_CL_M) >> LP8725_BUCK_CL_S; - - return (val < ARRAY_SIZE(lp8725_buck_uA)) ? - lp8725_buck_uA[val] : -EINVAL; -} - static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct lp872x *lp = rdev_get_drvdata(rdev); @@ -478,7 +416,7 @@ static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) return val & mask ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; } -static struct regulator_ops lp872x_ldo_ops = { +static const struct regulator_ops lp872x_ldo_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -489,7 +427,7 @@ static struct regulator_ops lp872x_ldo_ops = { .enable_time = lp872x_regulator_enable_time, }; -static struct regulator_ops lp8720_buck_ops = { +static const struct regulator_ops lp8720_buck_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = lp872x_buck_set_voltage_sel, @@ -502,7 +440,7 @@ static struct regulator_ops lp8720_buck_ops = { .get_mode = lp872x_buck_get_mode, }; -static struct regulator_ops lp8725_buck_ops = { +static const struct regulator_ops lp8725_buck_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = lp872x_buck_set_voltage_sel, @@ -513,11 +451,11 @@ static struct regulator_ops lp8725_buck_ops = { .enable_time = lp872x_regulator_enable_time, .set_mode = lp872x_buck_set_mode, .get_mode = lp872x_buck_get_mode, - .set_current_limit = lp8725_buck_set_current_limit, - .get_current_limit = lp8725_buck_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; -static struct regulator_desc lp8720_regulator_desc[] = { +static const struct regulator_desc lp8720_regulator_desc[] = { { .name = "ldo1", .of_match = of_match_ptr("ldo1"), @@ -602,7 +540,7 @@ static struct regulator_desc lp8720_regulator_desc[] = { }, }; -static struct regulator_desc lp8725_regulator_desc[] = { +static const struct regulator_desc lp8725_regulator_desc[] = { { .name = "ldo1", .of_match = of_match_ptr("ldo1"), @@ -712,6 +650,10 @@ static struct regulator_desc lp8725_regulator_desc[] = { .owner = THIS_MODULE, .enable_reg = LP872X_GENERAL_CFG, .enable_mask = LP8725_BUCK1_EN_M, + .curr_table = lp8725_buck_uA, + .n_current_limits = ARRAY_SIZE(lp8725_buck_uA), + .csel_reg = LP8725_BUCK1_VOUT2, + .csel_mask = LP8725_BUCK_CL_M, }, { .name = "buck2", @@ -724,6 +666,10 @@ static struct regulator_desc lp8725_regulator_desc[] = { .owner = THIS_MODULE, .enable_reg = LP872X_GENERAL_CFG, .enable_mask = LP8725_BUCK2_EN_M, + .curr_table = lp8725_buck_uA, + .n_current_limits = ARRAY_SIZE(lp8725_buck_uA), + .csel_reg = LP8725_BUCK2_VOUT2, + .csel_mask = LP8725_BUCK_CL_M, }, }; @@ -820,7 +766,7 @@ static struct regulator_init_data static int lp872x_regulator_register(struct lp872x *lp) { - struct regulator_desc *desc; + const struct regulator_desc *desc; struct regulator_config cfg = { }; struct regulator_dev *rdev; int i; diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c index 70e3df653381..b55de293ca7a 100644 --- a/drivers/regulator/lp873x-regulator.c +++ b/drivers/regulator/lp873x-regulator.c @@ -39,6 +39,10 @@ .ramp_delay = _delay, \ .linear_ranges = _lr, \ .n_linear_ranges = ARRAY_SIZE(_lr), \ + .curr_table = lp873x_buck_uA, \ + .n_current_limits = ARRAY_SIZE(lp873x_buck_uA), \ + .csel_reg = (_cr), \ + .csel_mask = LP873X_BUCK0_CTRL_2_BUCK0_ILIM,\ }, \ .ctrl2_reg = _cr, \ } @@ -61,7 +65,7 @@ static const struct regulator_linear_range ldo0_ldo1_ranges[] = { REGULATOR_LINEAR_RANGE(800000, 0x0, 0x19, 100000), }; -static unsigned int lp873x_buck_ramp_delay[] = { +static const unsigned int lp873x_buck_ramp_delay[] = { 30000, 15000, 10000, 7500, 3800, 1900, 940, 470 }; @@ -108,45 +112,8 @@ static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev, return 0; } -static int lp873x_buck_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - int id = rdev_get_id(rdev); - struct lp873x *lp873 = rdev_get_drvdata(rdev); - int i; - - for (i = ARRAY_SIZE(lp873x_buck_uA) - 1; i >= 0; i--) { - if (lp873x_buck_uA[i] >= min_uA && - lp873x_buck_uA[i] <= max_uA) - return regmap_update_bits(lp873->regmap, - regulators[id].ctrl2_reg, - LP873X_BUCK0_CTRL_2_BUCK0_ILIM, - i << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM)); - } - - return -EINVAL; -} - -static int lp873x_buck_get_current_limit(struct regulator_dev *rdev) -{ - int id = rdev_get_id(rdev); - struct lp873x *lp873 = rdev_get_drvdata(rdev); - int ret; - unsigned int val; - - ret = regmap_read(lp873->regmap, regulators[id].ctrl2_reg, &val); - if (ret) - return ret; - - val = (val & LP873X_BUCK0_CTRL_2_BUCK0_ILIM) >> - __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM); - - return (val < ARRAY_SIZE(lp873x_buck_uA)) ? - lp873x_buck_uA[val] : -EINVAL; -} - /* Operations permitted on BUCK0, BUCK1 */ -static struct regulator_ops lp873x_buck01_ops = { +static const struct regulator_ops lp873x_buck01_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -156,12 +123,12 @@ static struct regulator_ops lp873x_buck01_ops = { .map_voltage = regulator_map_voltage_linear_range, .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_ramp_delay = lp873x_buck_set_ramp_delay, - .set_current_limit = lp873x_buck_set_current_limit, - .get_current_limit = lp873x_buck_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; /* Operations permitted on LDO0 and LDO1 */ -static struct regulator_ops lp873x_ldo01_ops = { +static const struct regulator_ops lp873x_ldo01_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 244822bb63cd..4291df077c39 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * LP8755 High Performance Power Management Unit : System Interface Driver * (based on rev. 0.26) * Copyright 2012 Texas Instruments * * Author: Daniel(Geon Si) Jeong <daniel.jeong@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/module.h> @@ -315,7 +311,7 @@ out_i2c_error: .vsel_mask = LP8755_BUCK_VOUT_M,\ } -static struct regulator_desc lp8755_regulators[] = { +static const struct regulator_desc lp8755_regulators[] = { lp8755_buck_desc(0), lp8755_buck_desc(1), lp8755_buck_desc(2), @@ -372,10 +368,13 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) if ((flag0 & (0x4 << icnt)) && (pchip->irqmask & (0x04 << icnt)) - && (pchip->rdev[icnt] != NULL)) + && (pchip->rdev[icnt] != NULL)) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_PWR_FAULT, NULL); + regulator_unlock(pchip->rdev[icnt]); + } /* read flag1 register */ ret = lp8755_read(pchip, 0x0E, &flag1); @@ -386,21 +385,27 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) if (ret < 0) goto err_i2c; - /* send OCP event to all regualtor devices */ + /* send OCP event to all regulator devices */ if ((flag1 & 0x01) && (pchip->irqmask & 0x01)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - if (pchip->rdev[icnt] != NULL) + if (pchip->rdev[icnt] != NULL) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OCP, NULL); + regulator_unlock(pchip->rdev[icnt]); + } - /* send OVP event to all regualtor devices */ + /* send OVP event to all regulator devices */ if ((flag1 & 0x02) && (pchip->irqmask & 0x02)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - if (pchip->rdev[icnt] != NULL) + if (pchip->rdev[icnt] != NULL) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OVP, NULL); + regulator_unlock(pchip->rdev[icnt]); + } return IRQ_HANDLED; err_i2c: diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index c192357d1dea..225e5448c926 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for LP87565 PMIC * * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation version 2. */ #include <linux/module.h> @@ -34,6 +31,10 @@ .ramp_delay = _delay, \ .linear_ranges = _lr, \ .n_linear_ranges = ARRAY_SIZE(_lr), \ + .curr_table = lp87565_buck_uA, \ + .n_current_limits = ARRAY_SIZE(lp87565_buck_uA),\ + .csel_reg = (_cr), \ + .csel_mask = LP87565_BUCK_CTRL_2_ILIM, \ }, \ .ctrl2_reg = _cr, \ } @@ -51,7 +52,7 @@ static const struct regulator_linear_range buck0_1_2_3_ranges[] = { REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), }; -static unsigned int lp87565_buck_ramp_delay[] = { +static const unsigned int lp87565_buck_ramp_delay[] = { 30000, 15000, 10000, 7500, 3800, 1900, 940, 470 }; @@ -102,45 +103,8 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev, return 0; } -static int lp87565_buck_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - int id = rdev_get_id(rdev); - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); - int i; - - for (i = ARRAY_SIZE(lp87565_buck_uA) - 1; i >= 0; i--) { - if (lp87565_buck_uA[i] >= min_uA && - lp87565_buck_uA[i] <= max_uA) - return regmap_update_bits(lp87565->regmap, - regulators[id].ctrl2_reg, - LP87565_BUCK_CTRL_2_ILIM, - i << __ffs(LP87565_BUCK_CTRL_2_ILIM)); - } - - return -EINVAL; -} - -static int lp87565_buck_get_current_limit(struct regulator_dev *rdev) -{ - int id = rdev_get_id(rdev); - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); - int ret; - unsigned int val; - - ret = regmap_read(lp87565->regmap, regulators[id].ctrl2_reg, &val); - if (ret) - return ret; - - val = (val & LP87565_BUCK_CTRL_2_ILIM) >> - __ffs(LP87565_BUCK_CTRL_2_ILIM); - - return (val < ARRAY_SIZE(lp87565_buck_uA)) ? - lp87565_buck_uA[val] : -EINVAL; -} - -/* Operations permitted on BUCK0, BUCK1 */ -static struct regulator_ops lp87565_buck_ops = { +/* Operations permitted on BUCKs */ +static const struct regulator_ops lp87565_buck_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -150,8 +114,8 @@ static struct regulator_ops lp87565_buck_ops = { .map_voltage = regulator_map_voltage_linear_range, .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_ramp_delay = lp87565_buck_set_ramp_delay, - .set_current_limit = lp87565_buck_set_current_limit, - .get_current_limit = lp87565_buck_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static const struct lp87565_regulator regulators[] = { @@ -193,7 +157,7 @@ static int lp87565_regulator_probe(struct platform_device *pdev) struct lp87565 *lp87565 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct regulator_dev *rdev; - int i, min_idx = LP87565_BUCK_1, max_idx = LP87565_BUCK_3; + int i, min_idx = LP87565_BUCK_0, max_idx = LP87565_BUCK_3; platform_set_drvdata(pdev, lp87565); diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c index ec46290b647e..222502a29658 100644 --- a/drivers/regulator/lp8788-buck.c +++ b/drivers/regulator/lp8788-buck.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * TI LP8788 MFD - buck regulator driver * * Copyright 2012 Texas Instruments * * Author: Milo(Woogyom) 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/module.h> @@ -95,12 +91,10 @@ struct lp8788_buck { void *dvs; }; -/* BUCK 1 ~ 4 voltage table */ -static const int lp8788_buck_vtbl[] = { - 500000, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000, - 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000, - 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, 1900000, - 1950000, 2000000, +/* BUCK 1 ~ 4 voltage ranges */ +static const struct regulator_linear_range buck_volt_ranges[] = { + REGULATOR_LINEAR_RANGE(500000, 0, 0, 0), + REGULATOR_LINEAR_RANGE(800000, 1, 25, 50000), }; static void lp8788_buck1_set_dvs(struct lp8788_buck *buck) @@ -345,8 +339,8 @@ static unsigned int lp8788_buck_get_mode(struct regulator_dev *rdev) } static const struct regulator_ops lp8788_buck12_ops = { - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_ascend, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = lp8788_buck12_set_voltage_sel, .get_voltage_sel = lp8788_buck12_get_voltage_sel, .enable = regulator_enable_regmap, @@ -358,8 +352,8 @@ static const struct regulator_ops lp8788_buck12_ops = { }; static const struct regulator_ops lp8788_buck34_ops = { - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_ascend, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .enable = regulator_enable_regmap, @@ -370,13 +364,14 @@ static const struct regulator_ops lp8788_buck34_ops = { .get_mode = lp8788_buck_get_mode, }; -static struct regulator_desc lp8788_buck_desc[] = { +static const struct regulator_desc lp8788_buck_desc[] = { { .name = "buck1", .id = BUCK1, .ops = &lp8788_buck12_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, + .n_voltages = 26, + .linear_ranges = buck_volt_ranges, + .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, .enable_reg = LP8788_EN_BUCK, @@ -386,8 +381,9 @@ static struct regulator_desc lp8788_buck_desc[] = { .name = "buck2", .id = BUCK2, .ops = &lp8788_buck12_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, + .n_voltages = 26, + .linear_ranges = buck_volt_ranges, + .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, .enable_reg = LP8788_EN_BUCK, @@ -397,8 +393,9 @@ static struct regulator_desc lp8788_buck_desc[] = { .name = "buck3", .id = BUCK3, .ops = &lp8788_buck34_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, + .n_voltages = 26, + .linear_ranges = buck_volt_ranges, + .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, .vsel_reg = LP8788_BUCK3_VOUT, @@ -410,8 +407,9 @@ static struct regulator_desc lp8788_buck_desc[] = { .name = "buck4", .id = BUCK4, .ops = &lp8788_buck34_ops, - .n_voltages = ARRAY_SIZE(lp8788_buck_vtbl), - .volt_table = lp8788_buck_vtbl, + .n_voltages = 26, + .linear_ranges = buck_volt_ranges, + .n_linear_ranges = ARRAY_SIZE(buck_volt_ranges), .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, .vsel_reg = LP8788_BUCK4_VOUT, diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c index 2ee22e7ea675..1b00f3638996 100644 --- a/drivers/regulator/lp8788-ldo.c +++ b/drivers/regulator/lp8788-ldo.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * TI LP8788 MFD - ldo regulator driver * * Copyright 2012 Texas Instruments * * Author: Milo(Woogyom) 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/module.h> @@ -186,7 +182,7 @@ static const struct regulator_ops lp8788_ldo_voltage_fixed_ops = { .enable_time = lp8788_ldo_enable_time, }; -static struct regulator_desc lp8788_dldo_desc[] = { +static const struct regulator_desc lp8788_dldo_desc[] = { { .name = "dldo1", .id = DLDO1, @@ -343,7 +339,7 @@ static struct regulator_desc lp8788_dldo_desc[] = { }, }; -static struct regulator_desc lp8788_aldo_desc[] = { +static const struct regulator_desc lp8788_aldo_desc[] = { { .name = "aldo1", .id = ALDO1, diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index 63f724f260ef..9a037fdc5fc5 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -1,21 +1,9 @@ -/* - * Linear Technology LTC3589,LTC3589-1 regulator support - * - * Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Linear Technology LTC3589,LTC3589-1 regulator support +// +// Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix + #include <linux/i2c.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -84,19 +72,11 @@ enum ltc3589_reg { LTC3589_NUM_REGULATORS, }; -struct ltc3589_regulator { - struct regulator_desc desc; - - /* External feedback voltage divider */ - unsigned int r1; - unsigned int r2; -}; - struct ltc3589 { struct regmap *regmap; struct device *dev; enum ltc3589_variant variant; - struct ltc3589_regulator regulator_descs[LTC3589_NUM_REGULATORS]; + struct regulator_desc regulator_descs[LTC3589_NUM_REGULATORS]; struct regulator_dev *regulators[LTC3589_NUM_REGULATORS]; }; @@ -196,131 +176,90 @@ static const struct regulator_ops ltc3589_table_regulator_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; +static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) +{ + uint64_t tmp; -#define LTC3589_REG(_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit) \ - [LTC3589_ ## _name] = { \ - .desc = { \ - .name = #_name, \ - .n_voltages = (dtv_mask) + 1, \ - .min_uV = (go_bit) ? 362500 : 0, \ - .uV_step = (go_bit) ? 12500 : 0, \ - .ramp_delay = (go_bit) ? 1750 : 0, \ - .fixed_uV = (dtv_mask) ? 0 : 800000, \ - .ops = <c3589_ ## _ops ## _regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = LTC3589_ ## _name, \ - .owner = THIS_MODULE, \ - .vsel_reg = (dtv1_reg), \ - .vsel_mask = (dtv_mask), \ - .apply_reg = (go_bit) ? LTC3589_VCCR : 0, \ - .apply_bit = (go_bit), \ - .enable_reg = (en_bit) ? LTC3589_OVEN : 0, \ - .enable_mask = (en_bit), \ - }, \ - } - -#define LTC3589_LINEAR_REG(_name, _dtv1) \ - LTC3589_REG(_name, linear, LTC3589_OVEN_ ## _name, \ - LTC3589_ ## _dtv1, 0x1f, \ - LTC3589_VCCR_ ## _name ## _GO) - -#define LTC3589_FIXED_REG(_name) \ - LTC3589_REG(_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) - -static struct ltc3589_regulator ltc3589_regulators[LTC3589_NUM_REGULATORS] = { - LTC3589_LINEAR_REG(SW1, B1DTV1), - LTC3589_LINEAR_REG(SW2, B2DTV1), - LTC3589_LINEAR_REG(SW3, B3DTV1), - LTC3589_FIXED_REG(BB_OUT), - LTC3589_REG(LDO1, fixed_standby, 0, 0, 0, 0), - LTC3589_LINEAR_REG(LDO2, L2DTV1), - LTC3589_FIXED_REG(LDO3), - LTC3589_REG(LDO4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60, 0), -}; + if (uV == 0) + return 0; -#ifdef CONFIG_OF -static struct of_regulator_match ltc3589_matches[LTC3589_NUM_REGULATORS] = { - { .name = "sw1", }, - { .name = "sw2", }, - { .name = "sw3", }, - { .name = "bb-out", }, - { .name = "ldo1", }, /* standby */ - { .name = "ldo2", }, - { .name = "ldo3", }, - { .name = "ldo4", }, -}; + tmp = (uint64_t)uV * r1; + do_div(tmp, r2); + return uV + (unsigned int)tmp; +} -static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) +static int ltc3589_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *config) { - struct device *dev = ltc3589->dev; - struct device_node *node; - int i, ret; + struct ltc3589 *ltc3589 = config->driver_data; + struct regulator_desc *rdesc = <c3589->regulator_descs[desc->id]; + u32 r[2]; + int ret; - node = of_get_child_by_name(dev->of_node, "regulators"); - if (!node) { - dev_err(dev, "regulators node not found\n"); - return -EINVAL; - } + /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ + if (desc->id >= LTC3589_LDO3) + return 0; - ret = of_regulator_match(dev, node, ltc3589_matches, - ARRAY_SIZE(ltc3589_matches)); - of_node_put(node); - if (ret < 0) { - dev_err(dev, "Error parsing regulator init data: %d\n", ret); - return ret; - } - if (ret != LTC3589_NUM_REGULATORS) { - dev_err(dev, "Only %d regulators described in device tree\n", + ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", r, 2); + if (ret) { + dev_err(ltc3589->dev, "Failed to parse voltage divider: %d\n", ret); - return -EINVAL; + return ret; } - /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ - for (i = 0; i < LTC3589_LDO3; i++) { - struct ltc3589_regulator *desc = <c3589->regulator_descs[i]; - struct device_node *np = ltc3589_matches[i].of_node; - u32 vdiv[2]; - - ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", - vdiv, 2); - if (ret) { - dev_err(dev, "Failed to parse voltage divider: %d\n", - ret); - return ret; - } + if (!r[0] || !r[1]) + return 0; - desc->r1 = vdiv[0]; - desc->r2 = vdiv[1]; - } + rdesc->min_uV = ltc3589_scale(desc->min_uV, r[0], r[1]); + rdesc->uV_step = ltc3589_scale(desc->uV_step, r[0], r[1]); + rdesc->fixed_uV = ltc3589_scale(desc->fixed_uV, r[0], r[1]); return 0; } -static inline struct regulator_init_data *match_init_data(int index) -{ - return ltc3589_matches[index].init_data; -} - -static inline struct device_node *match_of_node(int index) -{ - return ltc3589_matches[index].of_node; -} -#else -static inline int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) -{ - return 0; -} +#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit)\ + [LTC3589_ ## _name] = { \ + .name = #_name, \ + .of_match = of_match_ptr(#_of_name), \ + .regulators_node = of_match_ptr("regulators"), \ + .of_parse_cb = ltc3589_of_parse_cb, \ + .n_voltages = (dtv_mask) + 1, \ + .min_uV = (go_bit) ? 362500 : 0, \ + .uV_step = (go_bit) ? 12500 : 0, \ + .ramp_delay = (go_bit) ? 1750 : 0, \ + .fixed_uV = (dtv_mask) ? 0 : 800000, \ + .ops = <c3589_ ## _ops ## _regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = LTC3589_ ## _name, \ + .owner = THIS_MODULE, \ + .vsel_reg = (dtv1_reg), \ + .vsel_mask = (dtv_mask), \ + .apply_reg = (go_bit) ? LTC3589_VCCR : 0, \ + .apply_bit = (go_bit), \ + .enable_reg = (en_bit) ? LTC3589_OVEN : 0, \ + .enable_mask = (en_bit), \ + } -static inline struct regulator_init_data *match_init_data(int index) -{ - return NULL; -} +#define LTC3589_LINEAR_REG(_name, _of_name, _dtv1) \ + LTC3589_REG(_name, _of_name, linear, LTC3589_OVEN_ ## _name, \ + LTC3589_ ## _dtv1, 0x1f, \ + LTC3589_VCCR_ ## _name ## _GO) -static inline struct device_node *match_of_node(int index) -{ - return NULL; -} -#endif +#define LTC3589_FIXED_REG(_name, _of_name) \ + LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) + +static const struct regulator_desc ltc3589_regulators[] = { + LTC3589_LINEAR_REG(SW1, sw1, B1DTV1), + LTC3589_LINEAR_REG(SW2, sw2, B2DTV1), + LTC3589_LINEAR_REG(SW3, sw3, B3DTV1), + LTC3589_FIXED_REG(BB_OUT, bb-out), + LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0), + LTC3589_LINEAR_REG(LDO2, ldo2, L2DTV1), + LTC3589_FIXED_REG(LDO3, ldo3), + LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, + 0x60, 0), +}; static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg) { @@ -409,7 +348,6 @@ static const struct regmap_config ltc3589_regmap_config = { .cache_type = REGCACHE_RBTREE, }; - static irqreturn_t ltc3589_isr(int irq, void *dev_id) { struct ltc3589 *ltc3589 = dev_id; @@ -419,16 +357,22 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id) if (irqstat & LTC3589_IRQSTAT_THERMAL_WARN) { event = REGULATOR_EVENT_OVER_TEMP; - for (i = 0; i < LTC3589_NUM_REGULATORS; i++) + for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { + regulator_lock(ltc3589->regulators[i]); regulator_notifier_call_chain(ltc3589->regulators[i], event, NULL); + regulator_unlock(ltc3589->regulators[i]); + } } if (irqstat & LTC3589_IRQSTAT_UNDERVOLT_WARN) { event = REGULATOR_EVENT_UNDER_VOLTAGE; - for (i = 0; i < LTC3589_NUM_REGULATORS; i++) + for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { + regulator_lock(ltc3589->regulators[i]); regulator_notifier_call_chain(ltc3589->regulators[i], event, NULL); + regulator_unlock(ltc3589->regulators[i]); + } } /* Clear warning condition */ @@ -437,33 +381,11 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) -{ - uint64_t tmp; - if (uV == 0) - return 0; - tmp = (uint64_t)uV * r1; - do_div(tmp, r2); - return uV + (unsigned int)tmp; -} - -static void ltc3589_apply_fb_voltage_divider(struct ltc3589_regulator *rdesc) -{ - struct regulator_desc *desc = &rdesc->desc; - - if (!rdesc->r1 || !rdesc->r2) - return; - - desc->min_uV = ltc3589_scale(desc->min_uV, rdesc->r1, rdesc->r2); - desc->uV_step = ltc3589_scale(desc->uV_step, rdesc->r1, rdesc->r2); - desc->fixed_uV = ltc3589_scale(desc->fixed_uV, rdesc->r1, rdesc->r2); -} - static int ltc3589_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; - struct ltc3589_regulator *descs; + struct regulator_desc *descs; struct ltc3589 *ltc3589; int i, ret; @@ -482,11 +404,11 @@ static int ltc3589_probe(struct i2c_client *client, descs = ltc3589->regulator_descs; memcpy(descs, ltc3589_regulators, sizeof(ltc3589_regulators)); if (ltc3589->variant == LTC3589) { - descs[LTC3589_LDO3].desc.fixed_uV = 1800000; - descs[LTC3589_LDO4].desc.volt_table = ltc3589_ldo4; + descs[LTC3589_LDO3].fixed_uV = 1800000; + descs[LTC3589_LDO4].volt_table = ltc3589_ldo4; } else { - descs[LTC3589_LDO3].desc.fixed_uV = 2800000; - descs[LTC3589_LDO4].desc.volt_table = ltc3589_12_ldo4; + descs[LTC3589_LDO3].fixed_uV = 2800000; + descs[LTC3589_LDO4].volt_table = ltc3589_12_ldo4; } ltc3589->regmap = devm_regmap_init_i2c(client, <c3589_regmap_config); @@ -496,25 +418,12 @@ static int ltc3589_probe(struct i2c_client *client, return ret; } - ret = ltc3589_parse_regulators_dt(ltc3589); - if (ret) - return ret; - for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { - struct ltc3589_regulator *rdesc = <c3589->regulator_descs[i]; - struct regulator_desc *desc = &rdesc->desc; - struct regulator_init_data *init_data; + struct regulator_desc *desc = <c3589->regulator_descs[i]; struct regulator_config config = { }; - init_data = match_init_data(i); - - if (i < LTC3589_LDO3) - ltc3589_apply_fb_voltage_divider(rdesc); - config.dev = dev; - config.init_data = init_data; config.driver_data = ltc3589; - config.of_node = match_of_node(i); ltc3589->regulators[i] = devm_regulator_register(dev, desc, &config); diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c index 71fd0f2a4b76..d934540eb8c4 100644 --- a/drivers/regulator/ltc3676.c +++ b/drivers/regulator/ltc3676.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2016 Gateworks Corporation, Inc. All Rights Reserved. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/i2c.h> #include <linux/init.h> @@ -241,61 +232,10 @@ static struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = { LTC3676_FIXED_REG(LDO4, ldo4, LDOB, 2), }; -static bool ltc3676_writeable_reg(struct device *dev, unsigned int reg) +static bool ltc3676_readable_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { - case LTC3676_IRQSTAT: - case LTC3676_BUCK1: - case LTC3676_BUCK2: - case LTC3676_BUCK3: - case LTC3676_BUCK4: - case LTC3676_LDOA: - case LTC3676_LDOB: - case LTC3676_SQD1: - case LTC3676_SQD2: - case LTC3676_CNTRL: - case LTC3676_DVB1A: - case LTC3676_DVB1B: - case LTC3676_DVB2A: - case LTC3676_DVB2B: - case LTC3676_DVB3A: - case LTC3676_DVB3B: - case LTC3676_DVB4A: - case LTC3676_DVB4B: - case LTC3676_MSKIRQ: - case LTC3676_MSKPG: - case LTC3676_USER: - case LTC3676_HRST: - case LTC3676_CLIRQ: - return true; - } - return false; -} - -static bool ltc3676_readable_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case LTC3676_IRQSTAT: - case LTC3676_BUCK1: - case LTC3676_BUCK2: - case LTC3676_BUCK3: - case LTC3676_BUCK4: - case LTC3676_LDOA: - case LTC3676_LDOB: - case LTC3676_SQD1: - case LTC3676_SQD2: - case LTC3676_CNTRL: - case LTC3676_DVB1A: - case LTC3676_DVB1B: - case LTC3676_DVB2A: - case LTC3676_DVB2B: - case LTC3676_DVB3A: - case LTC3676_DVB3B: - case LTC3676_DVB4A: - case LTC3676_DVB4B: - case LTC3676_MSKIRQ: - case LTC3676_MSKPG: - case LTC3676_USER: + case LTC3676_BUCK1 ... LTC3676_IRQSTAT: case LTC3676_HRST: case LTC3676_CLIRQ: return true; @@ -306,9 +246,7 @@ static bool ltc3676_readable_reg(struct device *dev, unsigned int reg) static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { - case LTC3676_IRQSTAT: - case LTC3676_PGSTATL: - case LTC3676_PGSTATRT: + case LTC3676_IRQSTAT ... LTC3676_PGSTATRT: return true; } return false; @@ -317,8 +255,8 @@ static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg) static const struct regmap_config ltc3676_regmap_config = { .reg_bits = 8, .val_bits = 8, - .writeable_reg = ltc3676_writeable_reg, - .readable_reg = ltc3676_readable_reg, + .writeable_reg = ltc3676_readable_writeable_reg, + .readable_reg = ltc3676_readable_writeable_reg, .volatile_reg = ltc3676_volatile_reg, .max_register = LTC3676_CLIRQ, .use_single_read = true, @@ -338,17 +276,23 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id) if (irqstat & LTC3676_IRQSTAT_THERMAL_WARN) { dev_warn(dev, "Over-temperature Warning\n"); event = REGULATOR_EVENT_OVER_TEMP; - for (i = 0; i < LTC3676_NUM_REGULATORS; i++) + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) { + regulator_lock(ltc3676->regulators[i]); regulator_notifier_call_chain(ltc3676->regulators[i], event, NULL); + regulator_unlock(ltc3676->regulators[i]); + } } if (irqstat & LTC3676_IRQSTAT_UNDERVOLT_WARN) { dev_info(dev, "Undervoltage Warning\n"); event = REGULATOR_EVENT_UNDER_VOLTAGE; - for (i = 0; i < LTC3676_NUM_REGULATORS; i++) + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) { + regulator_lock(ltc3676->regulators[i]); regulator_notifier_call_chain(ltc3676->regulators[i], event, NULL); + regulator_unlock(ltc3676->regulators[i]); + } } /* Clear warning condition */ @@ -442,5 +386,5 @@ static struct i2c_driver ltc3676_driver = { module_i2c_driver(ltc3676_driver); MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>"); -MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC1376"); +MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC3676"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c index bc7f4751bf9c..07a150c9bbf2 100644 --- a/drivers/regulator/max14577-regulator.c +++ b/drivers/regulator/max14577-regulator.c @@ -155,58 +155,6 @@ static const struct regulator_desc max77836_supported_regulators[] = { [MAX77836_LDO2] = MAX77836_LDO_REG(2), }; -#ifdef CONFIG_OF -static struct of_regulator_match max14577_regulator_matches[] = { - { .name = "SAFEOUT", }, - { .name = "CHARGER", }, -}; - -static struct of_regulator_match max77836_regulator_matches[] = { - { .name = "SAFEOUT", }, - { .name = "CHARGER", }, - { .name = "LDO1", }, - { .name = "LDO2", }, -}; - -static inline struct regulator_init_data *match_init_data(int index, - enum maxim_device_type dev_type) -{ - switch (dev_type) { - case MAXIM_DEVICE_TYPE_MAX77836: - return max77836_regulator_matches[index].init_data; - - case MAXIM_DEVICE_TYPE_MAX14577: - default: - return max14577_regulator_matches[index].init_data; - } -} - -static inline struct device_node *match_of_node(int index, - enum maxim_device_type dev_type) -{ - switch (dev_type) { - case MAXIM_DEVICE_TYPE_MAX77836: - return max77836_regulator_matches[index].of_node; - - case MAXIM_DEVICE_TYPE_MAX14577: - default: - return max14577_regulator_matches[index].of_node; - } -} -#else /* CONFIG_OF */ -static inline struct regulator_init_data *match_init_data(int index, - enum maxim_device_type dev_type) -{ - return NULL; -} - -static inline struct device_node *match_of_node(int index, - enum maxim_device_type dev_type) -{ - return NULL; -} -#endif /* CONFIG_OF */ - /** * Registers for regulators of max77836 use different I2C slave addresses so * different regmaps must be used for them. @@ -265,9 +213,6 @@ static int max14577_regulator_probe(struct platform_device *pdev) if (pdata && pdata->regulators) { config.init_data = pdata->regulators[i].initdata; config.of_node = pdata->regulators[i].of_node; - } else { - config.init_data = match_init_data(i, dev_type); - config.of_node = match_of_node(i, dev_type); } config.regmap = max14577_get_regmap(max14577, supported_regulators[i].id); @@ -324,4 +269,3 @@ module_exit(max14577_regulator_exit); MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); MODULE_DESCRIPTION("Maxim 14577/77836 regulator driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:max14577-regulator"); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index cc52779b53f7..f8941025780b 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * max1586.c -- Voltage and current regulation for the Maxim 1586 * * Copyright (C) 2008 Robert Jarzmik - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/module.h> #include <linux/err.h> diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index b94e3a721721..0db367b54ae7 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -1,14 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Maxim MAX77620 Regulator driver * - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. * * Author: Mallikarjun Kasoju <mkasoju@nvidia.com> * Laxman Dewangan <ldewangan@nvidia.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. */ #include <linux/init.h> @@ -690,6 +687,7 @@ static const struct regulator_ops max77620_regulator_ops = { .active_discharge_mask = MAX77620_SD_CFG1_ADE_MASK, \ .active_discharge_reg = MAX77620_REG_##_id##_CFG, \ .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ }, \ } @@ -721,6 +719,7 @@ static const struct regulator_ops max77620_regulator_ops = { .active_discharge_mask = MAX77620_LDO_CFG2_ADE_MASK, \ .active_discharge_reg = MAX77620_REG_##_id##_CFG2, \ .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ }, \ } @@ -801,8 +800,16 @@ static int max77620_regulator_probe(struct platform_device *pdev) continue; rdesc = &rinfo[id].desc; - pmic->rinfo[id] = &max77620_regs_info[id]; + pmic->rinfo[id] = &rinfo[id]; pmic->enable_power_mode[id] = MAX77620_POWER_MODE_NORMAL; + pmic->reg_pdata[id].active_fps_src = -1; + pmic->reg_pdata[id].active_fps_pd_slot = -1; + pmic->reg_pdata[id].active_fps_pu_slot = -1; + pmic->reg_pdata[id].suspend_fps_src = -1; + pmic->reg_pdata[id].suspend_fps_pd_slot = -1; + pmic->reg_pdata[id].suspend_fps_pu_slot = -1; + pmic->reg_pdata[id].power_ok = -1; + pmic->reg_pdata[id].ramp_rate_setting = -1; ret = max77620_read_slew_rate(pmic, id); if (ret < 0) diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c new file mode 100644 index 000000000000..5c4f86c98510 --- /dev/null +++ b/drivers/regulator/max77650-regulator.c @@ -0,0 +1,498 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2018 BayLibre SAS +// Author: Bartosz Golaszewski <bgolaszewski@baylibre.com> +// +// Regulator driver for MAXIM 77650/77651 charger/power-supply. + +#include <linux/of.h> +#include <linux/mfd/max77650.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/driver.h> + +#define MAX77650_REGULATOR_EN_CTRL_MASK GENMASK(3, 0) +#define MAX77650_REGULATOR_EN_CTRL_BITS(_reg) \ + ((_reg) & MAX77650_REGULATOR_EN_CTRL_MASK) +#define MAX77650_REGULATOR_ENABLED GENMASK(2, 1) +#define MAX77650_REGULATOR_DISABLED BIT(2) + +#define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0) +#define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0) + +#define MAX77650_REGULATOR_AD_MASK BIT(3) +#define MAX77650_REGULATOR_AD_DISABLED 0x00 +#define MAX77650_REGULATOR_AD_ENABLED BIT(3) + +#define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6) + +enum { + MAX77650_REGULATOR_ID_LDO = 0, + MAX77650_REGULATOR_ID_SBB0, + MAX77650_REGULATOR_ID_SBB1, + MAX77650_REGULATOR_ID_SBB2, + MAX77650_REGULATOR_NUM_REGULATORS, +}; + +struct max77650_regulator_desc { + struct regulator_desc desc; + unsigned int regA; + unsigned int regB; +}; + +static const unsigned int max77651_sbb1_regulator_volt_table[] = { + 2400000, 3200000, 4000000, 4800000, + 2450000, 3250000, 4050000, 4850000, + 2500000, 3300000, 4100000, 4900000, + 2550000, 3350000, 4150000, 4950000, + 2600000, 3400000, 4200000, 5000000, + 2650000, 3450000, 4250000, 5050000, + 2700000, 3500000, 4300000, 5100000, + 2750000, 3550000, 4350000, 5150000, + 2800000, 3600000, 4400000, 5200000, + 2850000, 3650000, 4450000, 5250000, + 2900000, 3700000, 4500000, 0, + 2950000, 3750000, 4550000, 0, + 3000000, 3800000, 4600000, 0, + 3050000, 3850000, 4650000, 0, + 3100000, 3900000, 4700000, 0, + 3150000, 3950000, 4750000, 0, +}; + +#define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \ + (((_val & 0x3c) >> 2) | ((_val & 0x03) << 4)) +#define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \ + (((_val & 0x30) >> 4) | ((_val & 0x0f) << 2)) + +#define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \ + do { \ + _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ + _val--; \ + _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ + } while (0) + +#define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \ + do { \ + _val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ + _val++; \ + _val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ + } while (0) + +static const unsigned int max77650_current_limit_table[] = { + 1000000, 866000, 707000, 500000, +}; + +static int max77650_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct max77650_regulator_desc *rdesc; + struct regmap *map; + int val, rv, en; + + rdesc = rdev_get_drvdata(rdev); + map = rdev_get_regmap(rdev); + + rv = regmap_read(map, rdesc->regB, &val); + if (rv) + return rv; + + en = MAX77650_REGULATOR_EN_CTRL_BITS(val); + + return en != MAX77650_REGULATOR_DISABLED; +} + +static int max77650_regulator_enable(struct regulator_dev *rdev) +{ + struct max77650_regulator_desc *rdesc; + struct regmap *map; + + rdesc = rdev_get_drvdata(rdev); + map = rdev_get_regmap(rdev); + + return regmap_update_bits(map, rdesc->regB, + MAX77650_REGULATOR_EN_CTRL_MASK, + MAX77650_REGULATOR_ENABLED); +} + +static int max77650_regulator_disable(struct regulator_dev *rdev) +{ + struct max77650_regulator_desc *rdesc; + struct regmap *map; + + rdesc = rdev_get_drvdata(rdev); + map = rdev_get_regmap(rdev); + + return regmap_update_bits(map, rdesc->regB, + MAX77650_REGULATOR_EN_CTRL_MASK, + MAX77650_REGULATOR_DISABLED); +} + +static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, + unsigned int sel) +{ + int rv = 0, curr, diff; + bool ascending; + + /* + * If the regulator is disabled, we can program the desired + * voltage right away. + */ + if (!max77650_regulator_is_enabled(rdev)) + return regulator_set_voltage_sel_regmap(rdev, sel); + + /* + * Otherwise we need to manually ramp the output voltage up/down + * one step at a time. + */ + + curr = regulator_get_voltage_sel_regmap(rdev); + if (curr < 0) + return curr; + + diff = curr - sel; + if (diff == 0) + return 0; /* Already there. */ + else if (diff > 0) + ascending = false; + else + ascending = true; + + /* + * Make sure we'll get to the right voltage and break the loop even if + * the selector equals 0. + */ + for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) { + rv = regulator_set_voltage_sel_regmap(rdev, curr); + if (rv) + return rv; + + if (curr == sel) + break; + } + + return 0; +} + +/* + * Special case: non-linear voltage table for max77651 SBB1 - software + * must ensure the voltage is ramped in 50mV increments. + */ +static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev, + unsigned int sel) +{ + int rv = 0, curr, vcurr, vdest, vdiff; + + /* + * If the regulator is disabled, we can program the desired + * voltage right away. + */ + if (!max77650_regulator_is_enabled(rdev)) + return regulator_set_voltage_sel_regmap(rdev, sel); + + curr = regulator_get_voltage_sel_regmap(rdev); + if (curr < 0) + return curr; + + if (curr == sel) + return 0; /* Already there. */ + + vcurr = max77651_sbb1_regulator_volt_table[curr]; + vdest = max77651_sbb1_regulator_volt_table[sel]; + vdiff = vcurr - vdest; + + for (;;) { + if (vdiff > 0) + MAX77650_REGULATOR_SBB1_SEL_DECR(curr); + else + MAX77650_REGULATOR_SBB1_SEL_INCR(curr); + + rv = regulator_set_voltage_sel_regmap(rdev, curr); + if (rv) + return rv; + + if (curr == sel) + break; + }; + + return 0; +} + +static const struct regulator_ops max77650_regulator_LDO_ops = { + .is_enabled = max77650_regulator_is_enabled, + .enable = max77650_regulator_enable, + .disable = max77650_regulator_disable, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = max77650_regulator_set_voltage_sel, + .set_active_discharge = regulator_set_active_discharge_regmap, +}; + +static const struct regulator_ops max77650_regulator_SBB_ops = { + .is_enabled = max77650_regulator_is_enabled, + .enable = max77650_regulator_enable, + .disable = max77650_regulator_disable, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = max77650_regulator_set_voltage_sel, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, + .set_active_discharge = regulator_set_active_discharge_regmap, +}; + +/* Special case for max77651 SBB1 - non-linear voltage mapping. */ +static const struct regulator_ops max77651_SBB1_regulator_ops = { + .is_enabled = max77650_regulator_is_enabled, + .enable = max77650_regulator_enable, + .disable = max77650_regulator_disable, + .list_voltage = regulator_list_voltage_table, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = max77651_regulator_sbb1_set_voltage_sel, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, + .set_active_discharge = regulator_set_active_discharge_regmap, +}; + +static struct max77650_regulator_desc max77650_LDO_desc = { + .desc = { + .name = "ldo", + .of_match = of_match_ptr("ldo"), + .regulators_node = of_match_ptr("regulators"), + .supply_name = "in-ldo", + .id = MAX77650_REGULATOR_ID_LDO, + .ops = &max77650_regulator_LDO_ops, + .min_uV = 1350000, + .uV_step = 12500, + .n_voltages = 128, + .vsel_mask = MAX77650_REGULATOR_V_LDO_MASK, + .vsel_reg = MAX77650_REG_CNFG_LDO_A, + .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, + .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, + .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, + .active_discharge_reg = MAX77650_REG_CNFG_LDO_B, + .enable_time = 100, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .regA = MAX77650_REG_CNFG_LDO_A, + .regB = MAX77650_REG_CNFG_LDO_B, +}; + +static struct max77650_regulator_desc max77650_SBB0_desc = { + .desc = { + .name = "sbb0", + .of_match = of_match_ptr("sbb0"), + .regulators_node = of_match_ptr("regulators"), + .supply_name = "in-sbb0", + .id = MAX77650_REGULATOR_ID_SBB0, + .ops = &max77650_regulator_SBB_ops, + .min_uV = 800000, + .uV_step = 25000, + .n_voltages = 64, + .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, + .vsel_reg = MAX77650_REG_CNFG_SBB0_A, + .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, + .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, + .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, + .active_discharge_reg = MAX77650_REG_CNFG_SBB0_B, + .enable_time = 100, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .csel_reg = MAX77650_REG_CNFG_SBB0_A, + .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, + .curr_table = max77650_current_limit_table, + .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), + }, + .regA = MAX77650_REG_CNFG_SBB0_A, + .regB = MAX77650_REG_CNFG_SBB0_B, +}; + +static struct max77650_regulator_desc max77650_SBB1_desc = { + .desc = { + .name = "sbb1", + .of_match = of_match_ptr("sbb1"), + .regulators_node = of_match_ptr("regulators"), + .supply_name = "in-sbb1", + .id = MAX77650_REGULATOR_ID_SBB1, + .ops = &max77650_regulator_SBB_ops, + .min_uV = 800000, + .uV_step = 12500, + .n_voltages = 64, + .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, + .vsel_reg = MAX77650_REG_CNFG_SBB1_A, + .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, + .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, + .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, + .active_discharge_reg = MAX77650_REG_CNFG_SBB1_B, + .enable_time = 100, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .csel_reg = MAX77650_REG_CNFG_SBB1_A, + .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, + .curr_table = max77650_current_limit_table, + .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), + }, + .regA = MAX77650_REG_CNFG_SBB1_A, + .regB = MAX77650_REG_CNFG_SBB1_B, +}; + +static struct max77650_regulator_desc max77651_SBB1_desc = { + .desc = { + .name = "sbb1", + .of_match = of_match_ptr("sbb1"), + .regulators_node = of_match_ptr("regulators"), + .supply_name = "in-sbb1", + .id = MAX77650_REGULATOR_ID_SBB1, + .ops = &max77651_SBB1_regulator_ops, + .volt_table = max77651_sbb1_regulator_volt_table, + .n_voltages = ARRAY_SIZE(max77651_sbb1_regulator_volt_table), + .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, + .vsel_reg = MAX77650_REG_CNFG_SBB1_A, + .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, + .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, + .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, + .active_discharge_reg = MAX77650_REG_CNFG_SBB1_B, + .enable_time = 100, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .csel_reg = MAX77650_REG_CNFG_SBB1_A, + .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, + .curr_table = max77650_current_limit_table, + .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), + }, + .regA = MAX77650_REG_CNFG_SBB1_A, + .regB = MAX77650_REG_CNFG_SBB1_B, +}; + +static struct max77650_regulator_desc max77650_SBB2_desc = { + .desc = { + .name = "sbb2", + .of_match = of_match_ptr("sbb2"), + .regulators_node = of_match_ptr("regulators"), + .supply_name = "in-sbb0", + .id = MAX77650_REGULATOR_ID_SBB2, + .ops = &max77650_regulator_SBB_ops, + .min_uV = 800000, + .uV_step = 50000, + .n_voltages = 64, + .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, + .vsel_reg = MAX77650_REG_CNFG_SBB2_A, + .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, + .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, + .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, + .active_discharge_reg = MAX77650_REG_CNFG_SBB2_B, + .enable_time = 100, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .csel_reg = MAX77650_REG_CNFG_SBB2_A, + .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, + .curr_table = max77650_current_limit_table, + .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), + }, + .regA = MAX77650_REG_CNFG_SBB2_A, + .regB = MAX77650_REG_CNFG_SBB2_B, +}; + +static struct max77650_regulator_desc max77651_SBB2_desc = { + .desc = { + .name = "sbb2", + .of_match = of_match_ptr("sbb2"), + .regulators_node = of_match_ptr("regulators"), + .supply_name = "in-sbb0", + .id = MAX77650_REGULATOR_ID_SBB2, + .ops = &max77650_regulator_SBB_ops, + .min_uV = 2400000, + .uV_step = 50000, + .n_voltages = 64, + .vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, + .vsel_reg = MAX77650_REG_CNFG_SBB2_A, + .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, + .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, + .active_discharge_mask = MAX77650_REGULATOR_AD_MASK, + .active_discharge_reg = MAX77650_REG_CNFG_SBB2_B, + .enable_time = 100, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .csel_reg = MAX77650_REG_CNFG_SBB2_A, + .csel_mask = MAX77650_REGULATOR_CURR_LIM_MASK, + .curr_table = max77650_current_limit_table, + .n_current_limits = ARRAY_SIZE(max77650_current_limit_table), + }, + .regA = MAX77650_REG_CNFG_SBB2_A, + .regB = MAX77650_REG_CNFG_SBB2_B, +}; + +static int max77650_regulator_probe(struct platform_device *pdev) +{ + struct max77650_regulator_desc **rdescs; + struct max77650_regulator_desc *rdesc; + struct regulator_config config = { }; + struct device *dev, *parent; + struct regulator_dev *rdev; + struct regmap *map; + unsigned int val; + int i, rv; + + dev = &pdev->dev; + parent = dev->parent; + + if (!dev->of_node) + dev->of_node = parent->of_node; + + rdescs = devm_kcalloc(dev, MAX77650_REGULATOR_NUM_REGULATORS, + sizeof(*rdescs), GFP_KERNEL); + if (!rdescs) + return -ENOMEM; + + map = dev_get_regmap(parent, NULL); + if (!map) + return -ENODEV; + + rv = regmap_read(map, MAX77650_REG_CID, &val); + if (rv) + return rv; + + rdescs[MAX77650_REGULATOR_ID_LDO] = &max77650_LDO_desc; + rdescs[MAX77650_REGULATOR_ID_SBB0] = &max77650_SBB0_desc; + + switch (MAX77650_CID_BITS(val)) { + case MAX77650_CID_77650A: + case MAX77650_CID_77650C: + rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77650_SBB1_desc; + rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77650_SBB2_desc; + break; + case MAX77650_CID_77651A: + case MAX77650_CID_77651B: + rdescs[MAX77650_REGULATOR_ID_SBB1] = &max77651_SBB1_desc; + rdescs[MAX77650_REGULATOR_ID_SBB2] = &max77651_SBB2_desc; + break; + default: + return -ENODEV; + } + + config.dev = parent; + + for (i = 0; i < MAX77650_REGULATOR_NUM_REGULATORS; i++) { + rdesc = rdescs[i]; + config.driver_data = rdesc; + + rdev = devm_regulator_register(dev, &rdesc->desc, &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + } + + return 0; +} + +static struct platform_driver max77650_regulator_driver = { + .driver = { + .name = "max77650-regulator", + }, + .probe = max77650_regulator_probe, +}; +module_platform_driver(max77650_regulator_driver); + +MODULE_DESCRIPTION("MAXIM 77650/77651 regulator driver"); +MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c index c30cf5c9f2de..ea7b50397300 100644 --- a/drivers/regulator/max77802-regulator.c +++ b/drivers/regulator/max77802-regulator.c @@ -248,9 +248,9 @@ static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev, unsigned int ramp_value; if (id > MAX77802_BUCK4) { - dev_warn(&rdev->dev, - "%s: regulator: ramp delay not supported\n", - rdev->desc->name); + dev_warn(&rdev->dev, + "%s: regulator: ramp delay not supported\n", + rdev->desc->name); return -EINVAL; } ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit, diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 81229579ece9..e86d8bd25fdc 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulators driver for Maxim max8649 * * Copyright (C) 2009-2010 Marvell International Ltd. * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> #include <linux/module.h> diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 4cf6897a401f..4bca54446287 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * max8660.c -- Voltage regulation for the Maxim 8660/8661 * @@ -5,19 +6,6 @@ * * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * * Some info: * * Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8660-MAX8661.pdf @@ -34,7 +22,6 @@ * If the driver is feature complete, it might be worth to check if one set of * functions for V3-V7 is sufficient. For maximum flexibility during * development, they are separated for now. - * */ #include <linux/module.h> diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 860400d2cd85..76152aaa330b 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * max8907-regulator.c -- support regulators in max8907 * @@ -8,10 +9,6 @@ * Copyright 2010 Texas Instruments Inc. * Author: Graeme Gregory <gg@slimlogic.co.uk> * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> - * - * 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> diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 39b63ddefeb2..d953b6b0db77 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulators driver for Maxim max8925 * * Copyright (C) 2009 Marvell International Ltd. * Haojian Zhuang <haojian.zhuang@marvell.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/kernel.h> #include <linux/module.h> @@ -159,6 +156,8 @@ static const struct regulator_ops max8925_regulator_ldo_ops = { { \ .desc = { \ .name = "SDV" #_id, \ + .of_match = of_match_ptr("SDV" #_id), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &max8925_regulator_sdv_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MAX8925_ID_SD##_id, \ @@ -175,6 +174,8 @@ static const struct regulator_ops max8925_regulator_ldo_ops = { { \ .desc = { \ .name = "LDO" #_id, \ + .of_match = of_match_ptr("LDO" #_id), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &max8925_regulator_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MAX8925_ID_LDO##_id, \ @@ -187,34 +188,6 @@ static const struct regulator_ops max8925_regulator_ldo_ops = { .enable_reg = MAX8925_LDOCTL##_id, \ } -#ifdef CONFIG_OF -static struct of_regulator_match max8925_regulator_matches[] = { - { .name = "SDV1",}, - { .name = "SDV2",}, - { .name = "SDV3",}, - { .name = "LDO1",}, - { .name = "LDO2",}, - { .name = "LDO3",}, - { .name = "LDO4",}, - { .name = "LDO5",}, - { .name = "LDO6",}, - { .name = "LDO7",}, - { .name = "LDO8",}, - { .name = "LDO9",}, - { .name = "LDO10",}, - { .name = "LDO11",}, - { .name = "LDO12",}, - { .name = "LDO13",}, - { .name = "LDO14",}, - { .name = "LDO15",}, - { .name = "LDO16",}, - { .name = "LDO17",}, - { .name = "LDO18",}, - { .name = "LDO19",}, - { .name = "LDO20",}, -}; -#endif - static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_SDV(1, 637.5, 1425, 12.5), MAX8925_SDV(2, 650, 2225, 25), @@ -242,37 +215,6 @@ static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_LDO(20, 750, 3900, 50), }; -#ifdef CONFIG_OF -static int max8925_regulator_dt_init(struct platform_device *pdev, - struct regulator_config *config, - int ridx) -{ - struct device_node *nproot, *np; - int rcount; - - nproot = pdev->dev.parent->of_node; - if (!nproot) - return -ENODEV; - np = of_get_child_by_name(nproot, "regulators"); - if (!np) { - dev_err(&pdev->dev, "failed to find regulators node\n"); - return -ENODEV; - } - - rcount = of_regulator_match(&pdev->dev, np, - &max8925_regulator_matches[ridx], 1); - of_node_put(np); - if (rcount < 0) - return rcount; - config->init_data = max8925_regulator_matches[ridx].init_data; - config->of_node = max8925_regulator_matches[ridx].of_node; - - return 0; -} -#else -#define max8925_regulator_dt_init(x, y, z) (-1) -#endif - static int max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -281,7 +223,7 @@ static int max8925_regulator_probe(struct platform_device *pdev) struct max8925_regulator_info *ri; struct resource *res; struct regulator_dev *rdev; - int i, regulator_idx; + int i; res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (!res) { @@ -290,10 +232,8 @@ static int max8925_regulator_probe(struct platform_device *pdev) } for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { ri = &max8925_regulator_info[i]; - if (ri->vol_reg == res->start) { - regulator_idx = i; + if (ri->vol_reg == res->start) break; - } } if (i == ARRAY_SIZE(max8925_regulator_info)) { @@ -303,12 +243,11 @@ static int max8925_regulator_probe(struct platform_device *pdev) } ri->i2c = chip->i2c; - config.dev = &pdev->dev; + config.dev = chip->dev; config.driver_data = ri; - if (max8925_regulator_dt_init(pdev, &config, regulator_idx)) - if (pdata) - config.init_data = pdata; + if (pdata) + config.init_data = pdata; rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); if (IS_ERR(rdev)) { diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index cf2a2912cb1b..2a123b87d9f2 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * max8952.c - Voltage and current regulation for the Maxim 8952 * * Copyright (C) 2010 Samsung Electronics * MyungJoo Ham <myungjoo.ham@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/module.h> diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 271bb736f3f5..60599c3bb845 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -33,72 +33,6 @@ struct max8998_data { unsigned int buck2_idx; }; -struct voltage_map_desc { - int min; - int max; - int step; -}; - -/* Voltage maps in uV*/ -static const struct voltage_map_desc ldo23_voltage_map_desc = { - .min = 800000, .step = 50000, .max = 1300000, -}; -static const struct voltage_map_desc ldo456711_voltage_map_desc = { - .min = 1600000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc ldo8_voltage_map_desc = { - .min = 3000000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc ldo9_voltage_map_desc = { - .min = 2800000, .step = 100000, .max = 3100000, -}; -static const struct voltage_map_desc ldo10_voltage_map_desc = { - .min = 950000, .step = 50000, .max = 1300000, -}; -static const struct voltage_map_desc ldo1213_voltage_map_desc = { - .min = 800000, .step = 100000, .max = 3300000, -}; -static const struct voltage_map_desc ldo1415_voltage_map_desc = { - .min = 1200000, .step = 100000, .max = 3300000, -}; -static const struct voltage_map_desc ldo1617_voltage_map_desc = { - .min = 1600000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc buck12_voltage_map_desc = { - .min = 750000, .step = 25000, .max = 1525000, -}; -static const struct voltage_map_desc buck3_voltage_map_desc = { - .min = 1600000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc buck4_voltage_map_desc = { - .min = 800000, .step = 100000, .max = 2300000, -}; - -static const struct voltage_map_desc *ldo_voltage_map[] = { - NULL, - NULL, - &ldo23_voltage_map_desc, /* LDO2 */ - &ldo23_voltage_map_desc, /* LDO3 */ - &ldo456711_voltage_map_desc, /* LDO4 */ - &ldo456711_voltage_map_desc, /* LDO5 */ - &ldo456711_voltage_map_desc, /* LDO6 */ - &ldo456711_voltage_map_desc, /* LDO7 */ - &ldo8_voltage_map_desc, /* LDO8 */ - &ldo9_voltage_map_desc, /* LDO9 */ - &ldo10_voltage_map_desc, /* LDO10 */ - &ldo456711_voltage_map_desc, /* LDO11 */ - &ldo1213_voltage_map_desc, /* LDO12 */ - &ldo1213_voltage_map_desc, /* LDO13 */ - &ldo1415_voltage_map_desc, /* LDO14 */ - &ldo1415_voltage_map_desc, /* LDO15 */ - &ldo1617_voltage_map_desc, /* LDO16 */ - &ldo1617_voltage_map_desc, /* LDO17 */ - &buck12_voltage_map_desc, /* BUCK1 */ - &buck12_voltage_map_desc, /* BUCK2 */ - &buck3_voltage_map_desc, /* BUCK3 */ - &buck4_voltage_map_desc, /* BUCK4 */ -}; - static int max8998_get_enable_register(struct regulator_dev *rdev, int *reg, int *shift) { @@ -400,7 +334,6 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c; - const struct voltage_map_desc *desc; int buck = rdev_get_id(rdev); u8 val = 0; int difference, ret; @@ -408,8 +341,6 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4) return -EINVAL; - desc = ldo_voltage_map[buck]; - /* Voltage stabilization */ ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); if (ret) @@ -420,14 +351,14 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP)) return 0; - difference = (new_selector - old_selector) * desc->step / 1000; + difference = (new_selector - old_selector) * rdev->desc->uV_step / 1000; if (difference > 0) return DIV_ROUND_UP(difference, (val & 0x0f) + 1); return 0; } -static struct regulator_ops max8998_ldo_ops = { +static const struct regulator_ops max8998_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = max8998_ldo_is_enabled, @@ -437,7 +368,7 @@ static struct regulator_ops max8998_ldo_ops = { .set_voltage_sel = max8998_set_voltage_ldo_sel, }; -static struct regulator_ops max8998_buck_ops = { +static const struct regulator_ops max8998_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = max8998_ldo_is_enabled, @@ -448,164 +379,59 @@ static struct regulator_ops max8998_buck_ops = { .set_voltage_time_sel = max8998_set_voltage_buck_time_sel, }; -static struct regulator_ops max8998_others_ops = { +static const struct regulator_ops max8998_others_ops = { .is_enabled = max8998_ldo_is_enabled, .enable = max8998_ldo_enable, .disable = max8998_ldo_disable, }; -static struct regulator_desc regulators[] = { - { - .name = "LDO2", - .id = MAX8998_LDO2, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO3", - .id = MAX8998_LDO3, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO4", - .id = MAX8998_LDO4, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO5", - .id = MAX8998_LDO5, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO6", - .id = MAX8998_LDO6, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO7", - .id = MAX8998_LDO7, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO8", - .id = MAX8998_LDO8, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO9", - .id = MAX8998_LDO9, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO10", - .id = MAX8998_LDO10, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO11", - .id = MAX8998_LDO11, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO12", - .id = MAX8998_LDO12, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO13", - .id = MAX8998_LDO13, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO14", - .id = MAX8998_LDO14, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO15", - .id = MAX8998_LDO15, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO16", - .id = MAX8998_LDO16, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO17", - .id = MAX8998_LDO17, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK1", - .id = MAX8998_BUCK1, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK2", - .id = MAX8998_BUCK2, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK3", - .id = MAX8998_BUCK3, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK4", - .id = MAX8998_BUCK4, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "EN32KHz-AP", - .id = MAX8998_EN32KHZ_AP, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "EN32KHz-CP", - .id = MAX8998_EN32KHZ_CP, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "ENVICHG", - .id = MAX8998_ENVICHG, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "ESAFEOUT1", - .id = MAX8998_ESAFEOUT1, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "ESAFEOUT2", - .id = MAX8998_ESAFEOUT2, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, +#define MAX8998_LINEAR_REG(_name, _ops, _min, _step, _max) \ + { \ + .name = #_name, \ + .id = MAX8998_##_name, \ + .ops = _ops, \ + .min_uV = (_min), \ + .uV_step = (_step), \ + .n_voltages = ((_max) - (_min)) / (_step) + 1, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ } + +#define MAX8998_OTHERS_REG(_name, _id) \ + { \ + .name = #_name, \ + .id = _id, \ + .ops = &max8998_others_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +static const struct regulator_desc regulators[] = { + MAX8998_LINEAR_REG(LDO2, &max8998_ldo_ops, 800000, 50000, 1300000), + MAX8998_LINEAR_REG(LDO3, &max8998_ldo_ops, 800000, 50000, 1300000), + MAX8998_LINEAR_REG(LDO4, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO5, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO6, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO7, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO8, &max8998_ldo_ops, 3000000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO9, &max8998_ldo_ops, 2800000, 100000, 3100000), + MAX8998_LINEAR_REG(LDO10, &max8998_ldo_ops, 950000, 50000, 1300000), + MAX8998_LINEAR_REG(LDO11, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO12, &max8998_ldo_ops, 800000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO13, &max8998_ldo_ops, 800000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO14, &max8998_ldo_ops, 1200000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO15, &max8998_ldo_ops, 1200000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO16, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO17, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(BUCK1, &max8998_buck_ops, 750000, 25000, 1525000), + MAX8998_LINEAR_REG(BUCK2, &max8998_buck_ops, 750000, 25000, 1525000), + MAX8998_LINEAR_REG(BUCK3, &max8998_buck_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(BUCK4, &max8998_buck_ops, 800000, 100000, 2300000), + MAX8998_OTHERS_REG(EN32KHz-AP, MAX8998_EN32KHZ_AP), + MAX8998_OTHERS_REG(EN32KHz-CP, MAX8998_EN32KHZ_CP), + MAX8998_OTHERS_REG(ENVICHG, MAX8998_ENVICHG), + MAX8998_OTHERS_REG(ESAFEOUT1, MAX8998_ESAFEOUT1), + MAX8998_OTHERS_REG(ESAFEOUT2, MAX8998_ESAFEOUT2), }; static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev, @@ -796,9 +622,11 @@ static int max8998_pmic_probe(struct platform_device *pdev) /* Set predefined values for BUCK1 registers */ for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) { + int index = MAX8998_BUCK1 - MAX8998_LDO2; + i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i + while (regulators[index].min_uV + + regulators[index].uV_step * i < pdata->buck1_voltage[v]) i++; @@ -824,9 +652,11 @@ static int max8998_pmic_probe(struct platform_device *pdev) /* Set predefined values for BUCK2 registers */ for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) { + int index = MAX8998_BUCK2 - MAX8998_LDO2; + i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i + while (regulators[index].min_uV + + regulators[index].uV_step * i < pdata->buck2_voltage[v]) i++; @@ -839,18 +669,7 @@ static int max8998_pmic_probe(struct platform_device *pdev) } for (i = 0; i < pdata->num_regulators; i++) { - const struct voltage_map_desc *desc; - int id = pdata->regulators[i].id; - int index = id - MAX8998_LDO2; - - desc = ldo_voltage_map[id]; - if (desc && regulators[index].ops != &max8998_others_ops) { - int count = (desc->max - desc->min) / desc->step + 1; - - regulators[index].n_voltages = count; - regulators[index].min_uV = desc->min; - regulators[index].uV_step = desc->step; - } + int index = pdata->regulators[i].id - MAX8998_LDO2; config.dev = max8998->dev; config.of_node = pdata->regulators[i].reg_node; @@ -867,7 +686,6 @@ static int max8998_pmic_probe(struct platform_device *pdev) } } - return 0; } diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c index 8fd1adc9c9a9..ab558b26cd7c 100644 --- a/drivers/regulator/mc13783-regulator.c +++ b/drivers/regulator/mc13783-regulator.c @@ -226,69 +226,69 @@ static const unsigned int mc13783_pwgtdrv_val[] = { 5500000, }; -static struct regulator_ops mc13783_gpo_regulator_ops; +static const struct regulator_ops mc13783_gpo_regulator_ops; -#define MC13783_DEFINE(prefix, name, reg, vsel_reg, voltages) \ - MC13xxx_DEFINE(MC13783_REG_, name, reg, vsel_reg, voltages, \ +#define MC13783_DEFINE(prefix, name, node, reg, vsel_reg, voltages) \ + MC13xxx_DEFINE(MC13783_REG_, name, node, reg, vsel_reg, voltages, \ mc13xxx_regulator_ops) -#define MC13783_FIXED_DEFINE(prefix, name, reg, voltages) \ - MC13xxx_FIXED_DEFINE(MC13783_REG_, name, reg, voltages, \ +#define MC13783_FIXED_DEFINE(prefix, name, node, reg, voltages) \ + MC13xxx_FIXED_DEFINE(MC13783_REG_, name, node, reg, voltages, \ mc13xxx_fixed_regulator_ops) -#define MC13783_GPO_DEFINE(prefix, name, reg, voltages) \ - MC13xxx_GPO_DEFINE(MC13783_REG_, name, reg, voltages, \ +#define MC13783_GPO_DEFINE(prefix, name, node, reg, voltages) \ + MC13xxx_GPO_DEFINE(MC13783_REG_, name, node, reg, voltages, \ mc13783_gpo_regulator_ops) -#define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages) \ - MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages) -#define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages) \ - MC13783_DEFINE(REG, _name, _reg, _vsel_reg, _voltages) +#define MC13783_DEFINE_SW(_name, _node, _reg, _vsel_reg, _voltages) \ + MC13783_DEFINE(REG, _name, _node, _reg, _vsel_reg, _voltages) +#define MC13783_DEFINE_REGU(_name, _node, _reg, _vsel_reg, _voltages) \ + MC13783_DEFINE(REG, _name, _node, _reg, _vsel_reg, _voltages) static struct mc13xxx_regulator mc13783_regulators[] = { - MC13783_DEFINE_SW(SW1A, SWITCHERS0, SWITCHERS0, mc13783_sw1x_val), - MC13783_DEFINE_SW(SW1B, SWITCHERS1, SWITCHERS1, mc13783_sw1x_val), - MC13783_DEFINE_SW(SW2A, SWITCHERS2, SWITCHERS2, mc13783_sw2x_val), - MC13783_DEFINE_SW(SW2B, SWITCHERS3, SWITCHERS3, mc13783_sw2x_val), - MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), - - MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val), - MC13783_FIXED_DEFINE(REG, VIOHI, REGULATORMODE0, mc13783_viohi_val), - MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0, + MC13783_DEFINE_SW(SW1A, sw1a, SWITCHERS0, SWITCHERS0, mc13783_sw1x_val), + MC13783_DEFINE_SW(SW1B, sw1b, SWITCHERS1, SWITCHERS1, mc13783_sw1x_val), + MC13783_DEFINE_SW(SW2A, sw2a, SWITCHERS2, SWITCHERS2, mc13783_sw2x_val), + MC13783_DEFINE_SW(SW2B, sw2b, SWITCHERS3, SWITCHERS3, mc13783_sw2x_val), + MC13783_DEFINE_SW(SW3, sw3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), + + MC13783_FIXED_DEFINE(REG, VAUDIO, vaudio, REGULATORMODE0, mc13783_vaudio_val), + MC13783_FIXED_DEFINE(REG, VIOHI, viohi, REGULATORMODE0, mc13783_viohi_val), + MC13783_DEFINE_REGU(VIOLO, violo, REGULATORMODE0, REGULATORSETTING0, mc13783_violo_val), - MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, + MC13783_DEFINE_REGU(VDIG, vdig, REGULATORMODE0, REGULATORSETTING0, mc13783_vdig_val), - MC13783_DEFINE_REGU(VGEN, REGULATORMODE0, REGULATORSETTING0, + MC13783_DEFINE_REGU(VGEN, vgen, REGULATORMODE0, REGULATORSETTING0, mc13783_vgen_val), - MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0, REGULATORSETTING0, + MC13783_DEFINE_REGU(VRFDIG, vrfdig, REGULATORMODE0, REGULATORSETTING0, mc13783_vrfdig_val), - MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0, REGULATORSETTING0, + MC13783_DEFINE_REGU(VRFREF, vrfref, REGULATORMODE0, REGULATORSETTING0, mc13783_vrfref_val), - MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0, REGULATORSETTING0, + MC13783_DEFINE_REGU(VRFCP, vrfcp, REGULATORMODE0, REGULATORSETTING0, mc13783_vrfcp_val), - MC13783_DEFINE_REGU(VSIM, REGULATORMODE1, REGULATORSETTING0, + MC13783_DEFINE_REGU(VSIM, vsim, REGULATORMODE1, REGULATORSETTING0, mc13783_vsim_val), - MC13783_DEFINE_REGU(VESIM, REGULATORMODE1, REGULATORSETTING0, + MC13783_DEFINE_REGU(VESIM, vesim, REGULATORMODE1, REGULATORSETTING0, mc13783_vesim_val), - MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, + MC13783_DEFINE_REGU(VCAM, vcam, REGULATORMODE1, REGULATORSETTING0, mc13783_vcam_val), - MC13783_FIXED_DEFINE(REG, VRFBG, REGULATORMODE1, mc13783_vrfbg_val), - MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1, + MC13783_FIXED_DEFINE(REG, VRFBG, vrfbg, REGULATORMODE1, mc13783_vrfbg_val), + MC13783_DEFINE_REGU(VVIB, vvib, REGULATORMODE1, REGULATORSETTING1, mc13783_vvib_val), - MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1, + MC13783_DEFINE_REGU(VRF1, vrf1, REGULATORMODE1, REGULATORSETTING1, mc13783_vrf_val), - MC13783_DEFINE_REGU(VRF2, REGULATORMODE1, REGULATORSETTING1, + MC13783_DEFINE_REGU(VRF2, vrf2, REGULATORMODE1, REGULATORSETTING1, mc13783_vrf_val), - MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1, REGULATORSETTING1, + MC13783_DEFINE_REGU(VMMC1, vmmc1, REGULATORMODE1, REGULATORSETTING1, mc13783_vmmc_val), - MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, + MC13783_DEFINE_REGU(VMMC2, vmmc2, REGULATORMODE1, REGULATORSETTING1, mc13783_vmmc_val), - MC13783_GPO_DEFINE(REG, GPO1, POWERMISC, mc13783_gpo_val), - MC13783_GPO_DEFINE(REG, GPO2, POWERMISC, mc13783_gpo_val), - MC13783_GPO_DEFINE(REG, GPO3, POWERMISC, mc13783_gpo_val), - MC13783_GPO_DEFINE(REG, GPO4, POWERMISC, mc13783_gpo_val), - MC13783_GPO_DEFINE(REG, PWGT1SPI, POWERMISC, mc13783_pwgtdrv_val), - MC13783_GPO_DEFINE(REG, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val), + MC13783_GPO_DEFINE(REG, GPO1, gpo1, POWERMISC, mc13783_gpo_val), + MC13783_GPO_DEFINE(REG, GPO2, gpo1, POWERMISC, mc13783_gpo_val), + MC13783_GPO_DEFINE(REG, GPO3, gpo1, POWERMISC, mc13783_gpo_val), + MC13783_GPO_DEFINE(REG, GPO4, gpo1, POWERMISC, mc13783_gpo_val), + MC13783_GPO_DEFINE(REG, PWGT1SPI, pwgt1spi, POWERMISC, mc13783_pwgtdrv_val), + MC13783_GPO_DEFINE(REG, PWGT2SPI, pwgt2spi, POWERMISC, mc13783_pwgtdrv_val), }; static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, @@ -380,7 +380,7 @@ static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev) return (val & mc13xxx_regulators[id].enable_bit) != 0; } -static struct regulator_ops mc13783_gpo_regulator_ops = { +static const struct regulator_ops mc13783_gpo_regulator_ops = { .enable = mc13783_gpo_regulator_enable, .disable = mc13783_gpo_regulator_disable, .is_enabled = mc13783_gpo_regulator_is_enabled, diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index f3fba1cc1379..a731e826a037 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -242,61 +242,61 @@ static const unsigned int mc13892_pwgtdrv[] = { 5000000, }; -static struct regulator_ops mc13892_gpo_regulator_ops; -static struct regulator_ops mc13892_sw_regulator_ops; +static const struct regulator_ops mc13892_gpo_regulator_ops; +static const struct regulator_ops mc13892_sw_regulator_ops; -#define MC13892_FIXED_DEFINE(name, reg, voltages) \ - MC13xxx_FIXED_DEFINE(MC13892_, name, reg, voltages, \ +#define MC13892_FIXED_DEFINE(name, node, reg, voltages) \ + MC13xxx_FIXED_DEFINE(MC13892_, name, node, reg, voltages, \ mc13xxx_fixed_regulator_ops) -#define MC13892_GPO_DEFINE(name, reg, voltages) \ - MC13xxx_GPO_DEFINE(MC13892_, name, reg, voltages, \ +#define MC13892_GPO_DEFINE(name, node, reg, voltages) \ + MC13xxx_GPO_DEFINE(MC13892_, name, node, reg, voltages, \ mc13892_gpo_regulator_ops) -#define MC13892_SW_DEFINE(name, reg, vsel_reg, voltages) \ - MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \ +#define MC13892_SW_DEFINE(name, node, reg, vsel_reg, voltages) \ + MC13xxx_DEFINE(MC13892_, name, node, reg, vsel_reg, voltages, \ mc13892_sw_regulator_ops) -#define MC13892_DEFINE_REGU(name, reg, vsel_reg, voltages) \ - MC13xxx_DEFINE(MC13892_, name, reg, vsel_reg, voltages, \ +#define MC13892_DEFINE_REGU(name, node, reg, vsel_reg, voltages) \ + MC13xxx_DEFINE(MC13892_, name, node, reg, vsel_reg, voltages, \ mc13xxx_regulator_ops) static struct mc13xxx_regulator mc13892_regulators[] = { - MC13892_DEFINE_REGU(VCOINCELL, POWERCTL0, POWERCTL0, mc13892_vcoincell), - MC13892_SW_DEFINE(SW1, SWITCHERS0, SWITCHERS0, mc13892_sw1), - MC13892_SW_DEFINE(SW2, SWITCHERS1, SWITCHERS1, mc13892_sw), - MC13892_SW_DEFINE(SW3, SWITCHERS2, SWITCHERS2, mc13892_sw), - MC13892_SW_DEFINE(SW4, SWITCHERS3, SWITCHERS3, mc13892_sw), - MC13892_FIXED_DEFINE(SWBST, SWITCHERS5, mc13892_swbst), - MC13892_FIXED_DEFINE(VIOHI, REGULATORMODE0, mc13892_viohi), - MC13892_DEFINE_REGU(VPLL, REGULATORMODE0, REGULATORSETTING0, + MC13892_DEFINE_REGU(VCOINCELL, vcoincell, POWERCTL0, POWERCTL0, mc13892_vcoincell), + MC13892_SW_DEFINE(SW1, sw1, SWITCHERS0, SWITCHERS0, mc13892_sw1), + MC13892_SW_DEFINE(SW2, sw2, SWITCHERS1, SWITCHERS1, mc13892_sw), + MC13892_SW_DEFINE(SW3, sw3, SWITCHERS2, SWITCHERS2, mc13892_sw), + MC13892_SW_DEFINE(SW4, sw4, SWITCHERS3, SWITCHERS3, mc13892_sw), + MC13892_FIXED_DEFINE(SWBST, swbst, SWITCHERS5, mc13892_swbst), + MC13892_FIXED_DEFINE(VIOHI, viohi, REGULATORMODE0, mc13892_viohi), + MC13892_DEFINE_REGU(VPLL, vpll, REGULATORMODE0, REGULATORSETTING0, mc13892_vpll), - MC13892_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, + MC13892_DEFINE_REGU(VDIG, vdig, REGULATORMODE0, REGULATORSETTING0, mc13892_vdig), - MC13892_DEFINE_REGU(VSD, REGULATORMODE1, REGULATORSETTING1, + MC13892_DEFINE_REGU(VSD, vsd, REGULATORMODE1, REGULATORSETTING1, mc13892_vsd), - MC13892_DEFINE_REGU(VUSB2, REGULATORMODE0, REGULATORSETTING0, + MC13892_DEFINE_REGU(VUSB2, vusb2, REGULATORMODE0, REGULATORSETTING0, mc13892_vusb2), - MC13892_DEFINE_REGU(VVIDEO, REGULATORMODE1, REGULATORSETTING1, + MC13892_DEFINE_REGU(VVIDEO, vvideo, REGULATORMODE1, REGULATORSETTING1, mc13892_vvideo), - MC13892_DEFINE_REGU(VAUDIO, REGULATORMODE1, REGULATORSETTING1, + MC13892_DEFINE_REGU(VAUDIO, vaudio, REGULATORMODE1, REGULATORSETTING1, mc13892_vaudio), - MC13892_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, + MC13892_DEFINE_REGU(VCAM, vcam, REGULATORMODE1, REGULATORSETTING0, mc13892_vcam), - MC13892_DEFINE_REGU(VGEN1, REGULATORMODE0, REGULATORSETTING0, + MC13892_DEFINE_REGU(VGEN1, vgen1, REGULATORMODE0, REGULATORSETTING0, mc13892_vgen1), - MC13892_DEFINE_REGU(VGEN2, REGULATORMODE0, REGULATORSETTING0, + MC13892_DEFINE_REGU(VGEN2, vgen2, REGULATORMODE0, REGULATORSETTING0, mc13892_vgen2), - MC13892_DEFINE_REGU(VGEN3, REGULATORMODE1, REGULATORSETTING0, + MC13892_DEFINE_REGU(VGEN3, vgen3, REGULATORMODE1, REGULATORSETTING0, mc13892_vgen3), - MC13892_FIXED_DEFINE(VUSB, USB1, mc13892_vusb), - MC13892_GPO_DEFINE(GPO1, POWERMISC, mc13892_gpo), - MC13892_GPO_DEFINE(GPO2, POWERMISC, mc13892_gpo), - MC13892_GPO_DEFINE(GPO3, POWERMISC, mc13892_gpo), - MC13892_GPO_DEFINE(GPO4, POWERMISC, mc13892_gpo), - MC13892_GPO_DEFINE(PWGT1SPI, POWERMISC, mc13892_pwgtdrv), - MC13892_GPO_DEFINE(PWGT2SPI, POWERMISC, mc13892_pwgtdrv), + MC13892_FIXED_DEFINE(VUSB, vusb, USB1, mc13892_vusb), + MC13892_GPO_DEFINE(GPO1, gpo1, POWERMISC, mc13892_gpo), + MC13892_GPO_DEFINE(GPO2, gpo2, POWERMISC, mc13892_gpo), + MC13892_GPO_DEFINE(GPO3, gpo3, POWERMISC, mc13892_gpo), + MC13892_GPO_DEFINE(GPO4, gpo4, POWERMISC, mc13892_gpo), + MC13892_GPO_DEFINE(PWGT1SPI, pwgt1spi, POWERMISC, mc13892_pwgtdrv), + MC13892_GPO_DEFINE(PWGT2SPI, pwgt2spi, POWERMISC, mc13892_pwgtdrv), }; static int mc13892_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, @@ -387,7 +387,7 @@ static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev) } -static struct regulator_ops mc13892_gpo_regulator_ops = { +static const struct regulator_ops mc13892_gpo_regulator_ops = { .enable = mc13892_gpo_regulator_enable, .disable = mc13892_gpo_regulator_disable, .is_enabled = mc13892_gpo_regulator_is_enabled, @@ -479,7 +479,7 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev, return ret; } -static struct regulator_ops mc13892_sw_regulator_ops = { +static const struct regulator_ops mc13892_sw_regulator_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = mc13892_sw_regulator_set_voltage_sel, diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 2243138d8a58..8ff19150ca92 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -99,7 +99,7 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) return rdev->desc->volt_table[val]; } -struct regulator_ops mc13xxx_regulator_ops = { +const struct regulator_ops mc13xxx_regulator_ops = { .enable = mc13xxx_regulator_enable, .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, @@ -127,7 +127,7 @@ int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, } EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); -struct regulator_ops mc13xxx_fixed_regulator_ops = { +const struct regulator_ops mc13xxx_fixed_regulator_ops = { .enable = mc13xxx_regulator_enable, .disable = mc13xxx_regulator_disable, .is_enabled = mc13xxx_regulator_is_enabled, diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h index 2ab9bfd93b4e..e03279dc43f4 100644 --- a/drivers/regulator/mc13xxx.h +++ b/drivers/regulator/mc13xxx.h @@ -1,12 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * mc13xxx.h - regulators for the Freescale mc13xxx PMIC * * Copyright (C) 2010 Yong Shen <yong.shen@linaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __LINUX_REGULATOR_MC13XXX_H @@ -53,13 +49,13 @@ static inline struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( } #endif -extern struct regulator_ops mc13xxx_regulator_ops; -extern struct regulator_ops mc13xxx_fixed_regulator_ops; +extern const struct regulator_ops mc13xxx_regulator_ops; +extern const struct regulator_ops mc13xxx_fixed_regulator_ops; -#define MC13xxx_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages, _ops) \ +#define MC13xxx_DEFINE(prefix, _name, _node, _reg, _vsel_reg, _voltages, _ops) \ [prefix ## _name] = { \ .desc = { \ - .name = #_name, \ + .name = #_node, \ .n_voltages = ARRAY_SIZE(_voltages), \ .volt_table = _voltages, \ .ops = &_ops, \ @@ -74,10 +70,10 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .vsel_mask = prefix ## _vsel_reg ## _ ## _name ## VSEL_M,\ } -#define MC13xxx_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops) \ +#define MC13xxx_FIXED_DEFINE(prefix, _name, _node, _reg, _voltages, _ops) \ [prefix ## _name] = { \ .desc = { \ - .name = #_name, \ + .name = #_node, \ .n_voltages = ARRAY_SIZE(_voltages), \ .volt_table = _voltages, \ .ops = &_ops, \ @@ -89,10 +85,10 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ } -#define MC13xxx_GPO_DEFINE(prefix, _name, _reg, _voltages, _ops) \ +#define MC13xxx_GPO_DEFINE(prefix, _name, _node, _reg, _voltages, _ops) \ [prefix ## _name] = { \ .desc = { \ - .name = #_name, \ + .name = #_node, \ .n_voltages = ARRAY_SIZE(_voltages), \ .volt_table = _voltages, \ .ops = &_ops, \ @@ -104,9 +100,9 @@ extern struct regulator_ops mc13xxx_fixed_regulator_ops; .enable_bit = prefix ## _reg ## _ ## _name ## EN, \ } -#define MC13xxx_DEFINE_SW(_name, _reg, _vsel_reg, _voltages, ops) \ - MC13xxx_DEFINE(SW, _name, _reg, _vsel_reg, _voltages, ops) -#define MC13xxx_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages, ops) \ - MC13xxx_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages, ops) +#define MC13xxx_DEFINE_SW(_name, _node, _reg, _vsel_reg, _voltages, ops) \ + MC13xxx_DEFINE(SW, _name, _node, _reg, _vsel_reg, _voltages, ops) +#define MC13xxx_DEFINE_REGU(_name, _node, _reg, _vsel_reg, _voltages, ops) \ + MC13xxx_DEFINE(REGU, _name, _node, _reg, _vsel_reg, _voltages, ops) #endif diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index 3479ae009b0b..e5a02711cb46 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -17,6 +17,7 @@ #include <linux/regmap.h> #include <linux/regulator/driver.h> #include <linux/suspend.h> +#include <linux/gpio/consumer.h> #define VDD_LOW_SEL 0x0D #define VDD_HIGH_SEL 0x3F @@ -118,8 +119,6 @@ enum { * @lpm: LPM GPIO descriptor */ struct mcp16502 { - struct regulator_dev *rdev[NUM_REGULATORS]; - struct regmap *rmap; struct gpio_desc *lpm; }; @@ -178,13 +177,12 @@ static unsigned int mcp16502_get_mode(struct regulator_dev *rdev) { unsigned int val; int ret, reg; - struct mcp16502 *mcp = rdev_get_drvdata(rdev); reg = mcp16502_get_reg(rdev, MCP16502_OPMODE_ACTIVE); if (reg < 0) return reg; - ret = regmap_read(mcp->rmap, reg, &val); + ret = regmap_read(rdev->regmap, reg, &val); if (ret) return ret; @@ -210,7 +208,6 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode, { int val; int reg; - struct mcp16502 *mcp = rdev_get_drvdata(rdev); reg = mcp16502_get_reg(rdev, op_mode); if (reg < 0) @@ -227,7 +224,7 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode, return -EINVAL; } - reg = regmap_update_bits(mcp->rmap, reg, MCP16502_MODE, val); + reg = regmap_update_bits(rdev->regmap, reg, MCP16502_MODE, val); return reg; } @@ -246,9 +243,8 @@ static int mcp16502_get_status(struct regulator_dev *rdev) { int ret; unsigned int val; - struct mcp16502 *mcp = rdev_get_drvdata(rdev); - ret = regmap_read(mcp->rmap, MCP16502_STAT_BASE(rdev_get_id(rdev)), + ret = regmap_read(rdev->regmap, MCP16502_STAT_BASE(rdev_get_id(rdev)), &val); if (ret) return ret; @@ -289,7 +285,6 @@ static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev) */ static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV) { - struct mcp16502 *mcp = rdev_get_drvdata(rdev); int sel = regulator_map_voltage_linear_range(rdev, uV, uV); int reg = mcp16502_suspend_get_target_reg(rdev); @@ -299,7 +294,7 @@ static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV) if (reg < 0) return reg; - return regmap_update_bits(mcp->rmap, reg, MCP16502_VSEL, sel); + return regmap_update_bits(rdev->regmap, reg, MCP16502_VSEL, sel); } /* @@ -327,13 +322,12 @@ static int mcp16502_set_suspend_mode(struct regulator_dev *rdev, */ static int mcp16502_set_suspend_enable(struct regulator_dev *rdev) { - struct mcp16502 *mcp = rdev_get_drvdata(rdev); int reg = mcp16502_suspend_get_target_reg(rdev); if (reg < 0) return reg; - return regmap_update_bits(mcp->rmap, reg, MCP16502_EN, MCP16502_EN); + return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, MCP16502_EN); } /* @@ -341,13 +335,12 @@ static int mcp16502_set_suspend_enable(struct regulator_dev *rdev) */ static int mcp16502_set_suspend_disable(struct regulator_dev *rdev) { - struct mcp16502 *mcp = rdev_get_drvdata(rdev); int reg = mcp16502_suspend_get_target_reg(rdev); if (reg < 0) return reg; - return regmap_update_bits(mcp->rmap, reg, MCP16502_EN, 0); + return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, 0); } #endif /* CONFIG_SUSPEND */ @@ -434,36 +427,15 @@ static const struct regmap_config mcp16502_regmap_config = { .wr_table = &mcp16502_yes_reg_table, }; -/* - * set_up_regulators() - initialize all regulators - */ -static int setup_regulators(struct mcp16502 *mcp, struct device *dev, - struct regulator_config config) -{ - int i; - - for (i = 0; i < NUM_REGULATORS; i++) { - mcp->rdev[i] = devm_regulator_register(dev, - &mcp16502_desc[i], - &config); - if (IS_ERR(mcp->rdev[i])) { - dev_err(dev, - "failed to register %s regulator %ld\n", - mcp16502_desc[i].name, PTR_ERR(mcp->rdev[i])); - return PTR_ERR(mcp->rdev[i]); - } - } - - return 0; -} - static int mcp16502_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regulator_config config = { }; + struct regulator_dev *rdev; struct device *dev; struct mcp16502 *mcp; - int ret = 0; + struct regmap *rmap; + int i, ret; dev = &client->dev; config.dev = dev; @@ -472,15 +444,15 @@ static int mcp16502_probe(struct i2c_client *client, if (!mcp) return -ENOMEM; - mcp->rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config); - if (IS_ERR(mcp->rmap)) { - ret = PTR_ERR(mcp->rmap); + rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config); + if (IS_ERR(rmap)) { + ret = PTR_ERR(rmap); dev_err(dev, "regmap init failed: %d\n", ret); return ret; } i2c_set_clientdata(client, mcp); - config.regmap = mcp->rmap; + config.regmap = rmap; config.driver_data = mcp; mcp->lpm = devm_gpiod_get(dev, "lpm", GPIOD_OUT_LOW); @@ -489,9 +461,15 @@ static int mcp16502_probe(struct i2c_client *client, return PTR_ERR(mcp->lpm); } - ret = setup_regulators(mcp, dev, config); - if (ret != 0) - return ret; + for (i = 0; i < NUM_REGULATORS; i++) { + rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config); + if (IS_ERR(rdev)) { + dev_err(dev, + "failed to register %s regulator %ld\n", + mcp16502_desc[i].name, PTR_ERR(rdev)); + return PTR_ERR(rdev); + } + } mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE); @@ -546,7 +524,6 @@ static struct i2c_driver mcp16502_drv = { module_i2c_driver(mcp16502_drv); -MODULE_VERSION("1.0"); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MCP16502 PMIC driver"); MODULE_AUTHOR("Andrei Stefanescu andrei.stefanescu@microchip.com"); diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c index 0495716fd35f..af95449d3590 100644 --- a/drivers/regulator/mt6311-regulator.c +++ b/drivers/regulator/mt6311-regulator.c @@ -1,16 +1,7 @@ -/* - * Copyright (c) 2015 MediaTek Inc. - * Author: Henry Chen <henryc.chen@mediatek.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2015 MediaTek Inc. +// Author: Henry Chen <henryc.chen@mediatek.com> #include <linux/err.h> #include <linux/gpio.h> @@ -38,13 +29,9 @@ static const struct regmap_config mt6311_regmap_config = { #define MT6311_MAX_UV 1393750 #define MT6311_STEP_UV 6250 -static const struct regulator_linear_range buck_volt_range[] = { - REGULATOR_LINEAR_RANGE(MT6311_MIN_UV, 0, 0x7f, MT6311_STEP_UV), -}; - static const struct regulator_ops mt6311_buck_ops = { - .list_voltage = regulator_list_voltage_linear_range, - .map_voltage = regulator_map_voltage_linear_range, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, @@ -71,8 +58,6 @@ static const struct regulator_ops mt6311_ldo_ops = { .min_uV = MT6311_MIN_UV,\ .uV_step = MT6311_STEP_UV,\ .owner = THIS_MODULE,\ - .linear_ranges = buck_volt_range, \ - .n_linear_ranges = ARRAY_SIZE(buck_volt_range), \ .enable_reg = MT6311_VDVFS11_CON9,\ .enable_mask = MT6311_PMIC_VDVFS11_EN_MASK,\ .vsel_reg = MT6311_VDVFS11_CON12,\ diff --git a/drivers/regulator/mt6311-regulator.h b/drivers/regulator/mt6311-regulator.h index 5218db46a798..4904d6751714 100644 --- a/drivers/regulator/mt6311-regulator.h +++ b/drivers/regulator/mt6311-regulator.h @@ -1,15 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015 MediaTek Inc. * Author: Henry Chen <henryc.chen@mediatek.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __MT6311_REGULATOR_H__ diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c index b7b9670f0979..893ea190788a 100644 --- a/drivers/regulator/mt6323-regulator.c +++ b/drivers/regulator/mt6323-regulator.c @@ -1,11 +1,7 @@ -/* - * Copyright (c) 2016 MediaTek Inc. - * Author: Chen Zhong <chen.zhong@mediatek.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. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2016 MediaTek Inc. +// Author: Chen Zhong <chen.zhong@mediatek.com> #include <linux/module.h> #include <linux/of.h> @@ -118,43 +114,43 @@ static const struct regulator_linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), }; -static const u32 ldo_volt_table1[] = { +static const unsigned int ldo_volt_table1[] = { 3300000, 3400000, 3500000, 3600000, }; -static const u32 ldo_volt_table2[] = { +static const unsigned int ldo_volt_table2[] = { 1500000, 1800000, 2500000, 2800000, }; -static const u32 ldo_volt_table3[] = { +static const unsigned int ldo_volt_table3[] = { 1800000, 3300000, }; -static const u32 ldo_volt_table4[] = { +static const unsigned int ldo_volt_table4[] = { 3000000, 3300000, }; -static const u32 ldo_volt_table5[] = { +static const unsigned int ldo_volt_table5[] = { 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table6[] = { +static const unsigned int ldo_volt_table6[] = { 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, }; -static const u32 ldo_volt_table7[] = { +static const unsigned int ldo_volt_table7[] = { 1200000, 1300000, 1500000, 1800000, }; -static const u32 ldo_volt_table8[] = { +static const unsigned int ldo_volt_table8[] = { 1800000, 3000000, }; -static const u32 ldo_volt_table9[] = { +static const unsigned int ldo_volt_table9[] = { 1200000, 1350000, 1500000, 1800000, }; -static const u32 ldo_volt_table10[] = { +static const unsigned int ldo_volt_table10[] = { 1200000, 1300000, 1500000, 1800000, }; diff --git a/drivers/regulator/mt6380-regulator.c b/drivers/regulator/mt6380-regulator.c index 127dd720cbcc..b6aed090b5e0 100644 --- a/drivers/regulator/mt6380-regulator.c +++ b/drivers/regulator/mt6380-regulator.c @@ -1,16 +1,7 @@ -/* - * Copyright (c) 2017 MediaTek Inc. - * Author: Chenglin Xu <chenglin.xu@mediatek.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2017 MediaTek Inc. +// Author: Chenglin Xu <chenglin.xu@mediatek.com> #include <linux/module.h> #include <linux/of.h> @@ -173,19 +164,19 @@ static const struct regulator_linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(1200000, 0, 0x3c, 25000), }; -static const u32 ldo_volt_table1[] = { +static const unsigned int ldo_volt_table1[] = { 1400000, 1350000, 1300000, 1250000, 1200000, 1150000, 1100000, 1050000, }; -static const u32 ldo_volt_table2[] = { +static const unsigned int ldo_volt_table2[] = { 2200000, 3300000, }; -static const u32 ldo_volt_table3[] = { +static const unsigned int ldo_volt_table3[] = { 1240000, 1390000, 1540000, 1840000, }; -static const u32 ldo_volt_table4[] = { +static const unsigned int ldo_volt_table4[] = { 2200000, 3300000, }; diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index c6c6aa85e4e8..fd9ed864a0c1 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -1,16 +1,7 @@ -/* - * Copyright (c) 2014 MediaTek Inc. - * Author: Flora Fu <flora.fu@mediatek.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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2014 MediaTek Inc. +// Author: Flora Fu <flora.fu@mediatek.com> #include <linux/module.h> #include <linux/of.h> @@ -123,35 +114,35 @@ static const struct regulator_linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000), }; -static const u32 ldo_volt_table1[] = { +static const unsigned int ldo_volt_table1[] = { 1500000, 1800000, 2500000, 2800000, }; -static const u32 ldo_volt_table2[] = { +static const unsigned int ldo_volt_table2[] = { 1800000, 3300000, }; -static const u32 ldo_volt_table3[] = { +static const unsigned int ldo_volt_table3[] = { 3000000, 3300000, }; -static const u32 ldo_volt_table4[] = { +static const unsigned int ldo_volt_table4[] = { 1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table5[] = { +static const unsigned int ldo_volt_table5[] = { 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table5_v2[] = { +static const unsigned int ldo_volt_table5_v2[] = { 1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table6[] = { +static const unsigned int ldo_volt_table6[] = { 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, }; -static const u32 ldo_volt_table7[] = { +static const unsigned int ldo_volt_table7[] = { 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, }; diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index ffa5fc3724e4..0ead1164e4d6 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * OF helpers for regulator framework * * Copyright (C) 2011 Texas Instruments, Inc. * Rajendra Nayak <rnayak@ti.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/module.h> @@ -255,7 +251,7 @@ static void of_get_regulation_constraints(struct device_node *np, * @desc: regulator description * * Populates regulator_init_data structure by extracting data from device - * tree node, returns a pointer to the populated struture or NULL if memory + * tree node, returns a pointer to the populated structure or NULL if memory * alloc fails. */ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, @@ -371,8 +367,9 @@ int of_regulator_match(struct device *dev, struct device_node *node, } EXPORT_SYMBOL_GPL(of_regulator_match); -struct device_node *regulator_of_get_init_node(struct device *dev, - const struct regulator_desc *desc) +static struct +device_node *regulator_of_get_init_node(struct device *dev, + const struct regulator_desc *desc) { struct device_node *search, *child; const char *name; @@ -547,7 +544,7 @@ bool of_check_coupling_data(struct regulator_dev *rdev) NULL); if (c_n_phandles != n_phandles) { - dev_err(&rdev->dev, "number of couped reg phandles mismatch\n"); + dev_err(&rdev->dev, "number of coupled reg phandles mismatch\n"); ret = false; goto clean; } diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index c2cc392a27d4..31325912d311 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver for Regulator part of Palmas PMIC Chips * @@ -5,12 +6,6 @@ * * Author: Graeme Gregory <gg@slimlogic.co.uk> * Author: Ian Lartey <ian@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/kernel.h> @@ -382,7 +377,7 @@ static struct palmas_sleep_requestor_info tps65917_sleep_req_info[] = { EXTERNAL_REQUESTOR_TPS65917(LDO5, 2, 4), }; -static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; +static const unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; #define SMPS_CTRL_MODE_OFF 0x00 #define SMPS_CTRL_MODE_ON 0x01 @@ -991,9 +986,6 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, return PTR_ERR(rdev); } - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; - /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; @@ -1101,9 +1093,6 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, return PTR_ERR(rdev); } - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; - /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; @@ -1288,9 +1277,6 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, pdev_name); return PTR_ERR(rdev); } - - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; } return 0; @@ -1395,9 +1381,6 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, pdev_name); return PTR_ERR(rdev); } - - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; } return 0; diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c index 79cb971a69bb..c2469263db95 100644 --- a/drivers/regulator/pcap-regulator.c +++ b/drivers/regulator/pcap-regulator.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * PCAP2 Regulator Driver * * Copyright (c) 2009 Daniel Ribeiro <drwyrm@gmail.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 762e18447cae..f40e3bb303d6 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* NXP PCF50633 PMIC Driver * * (C) 2006-2008 by Openmoko, Inc. @@ -6,12 +7,6 @@ * * Broken down from monstrous PCF50633 driver mainly by * Harald Welte and Andy Green and Werner Almesberger - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/kernel.h> diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c index a9446056435f..3d3415839ba2 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -1,17 +1,7 @@ -/* - * pv88060-regulator.c - Regulator device driver for PV88060 - * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// pv88060-regulator.c - Regulator device driver for PV88060 +// Copyright (C) 2015 Powerventure Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -53,10 +43,6 @@ enum { struct pv88060_regulator { struct regulator_desc desc; - /* Current limiting */ - unsigned n_current_limits; - const int *current_limits; - unsigned int limit_mask; unsigned int conf; /* buck configuration register */ }; @@ -75,7 +61,7 @@ static const struct regmap_config pv88060_regmap_config = { * Entry indexes corresponds to register values. */ -static const int pv88060_buck1_limits[] = { +static const unsigned int pv88060_buck1_limits[] = { 1496000, 2393000, 3291000, 4189000 }; @@ -128,40 +114,6 @@ static int pv88060_buck_set_mode(struct regulator_dev *rdev, PV88060_BUCK_MODE_MASK, val); } -static int pv88060_set_current_limit(struct regulator_dev *rdev, int min, - int max) -{ - struct pv88060_regulator *info = rdev_get_drvdata(rdev); - int i; - - /* search for closest to maximum */ - for (i = info->n_current_limits; i >= 0; i--) { - if (min <= info->current_limits[i] - && max >= info->current_limits[i]) { - return regmap_update_bits(rdev->regmap, - info->conf, - info->limit_mask, - i << PV88060_BUCK_ILIM_SHIFT); - } - } - - return -EINVAL; -} - -static int pv88060_get_current_limit(struct regulator_dev *rdev) -{ - struct pv88060_regulator *info = rdev_get_drvdata(rdev); - unsigned int data; - int ret; - - ret = regmap_read(rdev->regmap, info->conf, &data); - if (ret < 0) - return ret; - - data = (data & info->limit_mask) >> PV88060_BUCK_ILIM_SHIFT; - return info->current_limits[data]; -} - static const struct regulator_ops pv88060_buck_ops = { .get_mode = pv88060_buck_get_mode, .set_mode = pv88060_buck_set_mode, @@ -171,8 +123,8 @@ static const struct regulator_ops pv88060_buck_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = pv88060_set_current_limit, - .get_current_limit = pv88060_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static const struct regulator_ops pv88060_ldo_ops = { @@ -184,6 +136,12 @@ static const struct regulator_ops pv88060_ldo_ops = { .list_voltage = regulator_list_voltage_linear, }; +static const struct regulator_ops pv88060_sw_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + #define PV88060_BUCK(chip, regl_name, min, step, max, limits_array) \ {\ .desc = {\ @@ -201,10 +159,11 @@ static const struct regulator_ops pv88060_ldo_ops = { .enable_mask = PV88060_BUCK_EN, \ .vsel_reg = PV88060_REG_##regl_name##_CONF0,\ .vsel_mask = PV88060_VBUCK_MASK,\ + .curr_table = limits_array,\ + .n_current_limits = ARRAY_SIZE(limits_array),\ + .csel_reg = PV88060_REG_##regl_name##_CONF1,\ + .csel_mask = PV88060_BUCK_ILIM_MASK,\ },\ - .current_limits = limits_array,\ - .n_current_limits = ARRAY_SIZE(limits_array),\ - .limit_mask = PV88060_BUCK_ILIM_MASK, \ .conf = PV88060_REG_##regl_name##_CONF1,\ } @@ -237,9 +196,8 @@ static const struct regulator_ops pv88060_ldo_ops = { .regulators_node = of_match_ptr("regulators"),\ .type = REGULATOR_VOLTAGE,\ .owner = THIS_MODULE,\ - .ops = &pv88060_ldo_ops,\ - .min_uV = max,\ - .uV_step = 0,\ + .ops = &pv88060_sw_ops,\ + .fixed_uV = max,\ .n_voltages = 1,\ .enable_reg = PV88060_REG_##regl_name##_CONF,\ .enable_mask = PV88060_SW_EN,\ @@ -276,9 +234,11 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data) if (reg_val & PV88060_E_VDD_FLT) { for (i = 0; i < PV88060_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -293,9 +253,11 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data) if (reg_val & PV88060_E_OVER_TEMP) { for (i = 0; i < PV88060_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); + regulator_unlock(chip->rdev[i]); } } diff --git a/drivers/regulator/pv88060-regulator.h b/drivers/regulator/pv88060-regulator.h index 02ca9203a172..d333dbf3be94 100644 --- a/drivers/regulator/pv88060-regulator.h +++ b/drivers/regulator/pv88060-regulator.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * pv88060-regulator.h - Regulator definitions for PV88060 * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __PV88060_REGISTERS_H__ diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c index 9a08cb2de501..a444f68af1a8 100644 --- a/drivers/regulator/pv88080-regulator.c +++ b/drivers/regulator/pv88080-regulator.c @@ -1,17 +1,7 @@ -/* - * pv88080-regulator.c - Regulator device driver for PV88080 - * Copyright (C) 2016 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// pv88080-regulator.c - Regulator device driver for PV88080 +// Copyright (C) 2016 Powerventure Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -45,12 +35,7 @@ enum pv88080_types { struct pv88080_regulator { struct regulator_desc desc; - /* Current limiting */ - unsigned int n_current_limits; - const int *current_limits; - unsigned int limit_mask; unsigned int mode_reg; - unsigned int limit_reg; unsigned int conf2; unsigned int conf5; }; @@ -102,11 +87,11 @@ static const struct regmap_config pv88080_regmap_config = { * Entry indexes corresponds to register values. */ -static const int pv88080_buck1_limits[] = { +static const unsigned int pv88080_buck1_limits[] = { 3230000, 5130000, 6960000, 8790000 }; -static const int pv88080_buck23_limits[] = { +static const unsigned int pv88080_buck23_limits[] = { 1496000, 2393000, 3291000, 4189000 }; @@ -272,40 +257,6 @@ static int pv88080_buck_set_mode(struct regulator_dev *rdev, PV88080_BUCK1_MODE_MASK, val); } -static int pv88080_set_current_limit(struct regulator_dev *rdev, int min, - int max) -{ - struct pv88080_regulator *info = rdev_get_drvdata(rdev); - int i; - - /* search for closest to maximum */ - for (i = info->n_current_limits; i >= 0; i--) { - if (min <= info->current_limits[i] - && max >= info->current_limits[i]) { - return regmap_update_bits(rdev->regmap, - info->limit_reg, - info->limit_mask, - i << PV88080_BUCK1_ILIM_SHIFT); - } - } - - return -EINVAL; -} - -static int pv88080_get_current_limit(struct regulator_dev *rdev) -{ - struct pv88080_regulator *info = rdev_get_drvdata(rdev); - unsigned int data; - int ret; - - ret = regmap_read(rdev->regmap, info->limit_reg, &data); - if (ret < 0) - return ret; - - data = (data & info->limit_mask) >> PV88080_BUCK1_ILIM_SHIFT; - return info->current_limits[data]; -} - static const struct regulator_ops pv88080_buck_ops = { .get_mode = pv88080_buck_get_mode, .set_mode = pv88080_buck_set_mode, @@ -315,8 +266,8 @@ static const struct regulator_ops pv88080_buck_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = pv88080_set_current_limit, - .get_current_limit = pv88080_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static const struct regulator_ops pv88080_hvbuck_ops = { @@ -341,9 +292,9 @@ static const struct regulator_ops pv88080_hvbuck_ops = { .min_uV = min, \ .uV_step = step, \ .n_voltages = ((max) - (min))/(step) + 1, \ + .curr_table = limits_array, \ + .n_current_limits = ARRAY_SIZE(limits_array), \ },\ - .current_limits = limits_array, \ - .n_current_limits = ARRAY_SIZE(limits_array), \ } #define PV88080_HVBUCK(chip, regl_name, min, step, max) \ @@ -384,9 +335,11 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data) if (reg_val & PV88080_E_VDD_FLT) { for (i = 0; i < PV88080_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -401,9 +354,11 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data) if (reg_val & PV88080_E_OVER_TEMP) { for (i = 0; i < PV88080_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -521,9 +476,9 @@ static int pv88080_i2c_probe(struct i2c_client *i2c, if (init_data) config.init_data = &init_data[i]; - pv88080_regulator_info[i].limit_reg + pv88080_regulator_info[i].desc.csel_reg = regmap_config->buck_regmap[i].buck_limit_reg; - pv88080_regulator_info[i].limit_mask + pv88080_regulator_info[i].desc.csel_mask = regmap_config->buck_regmap[i].buck_limit_mask; pv88080_regulator_info[i].mode_reg = regmap_config->buck_regmap[i].buck_mode_reg; diff --git a/drivers/regulator/pv88080-regulator.h b/drivers/regulator/pv88080-regulator.h index ae25ff360e3d..7d7f8f11a75a 100644 --- a/drivers/regulator/pv88080-regulator.h +++ b/drivers/regulator/pv88080-regulator.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * pv88080-regulator.h - Regulator definitions for PV88080 * Copyright (C) 2016 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __PV88080_REGISTERS_H__ diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 7a0c15957bd0..b1d0d97ae935 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -1,17 +1,7 @@ -/* - * pv88090-regulator.c - Regulator device driver for PV88090 - * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// pv88090-regulator.c - Regulator device driver for PV88090 +// Copyright (C) 2015 Powerventure Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -42,10 +32,6 @@ enum { struct pv88090_regulator { struct regulator_desc desc; - /* Current limiting */ - unsigned int n_current_limits; - const int *current_limits; - unsigned int limit_mask; unsigned int conf; unsigned int conf2; }; @@ -71,14 +57,14 @@ static const struct regmap_config pv88090_regmap_config = { * Entry indexes corresponds to register values. */ -static const int pv88090_buck1_limits[] = { +static const unsigned int pv88090_buck1_limits[] = { 220000, 440000, 660000, 880000, 1100000, 1320000, 1540000, 1760000, 1980000, 2200000, 2420000, 2640000, 2860000, 3080000, 3300000, 3520000, 3740000, 3960000, 4180000, 4400000, 4620000, 4840000, 5060000, 5280000, 5500000, 5720000, 5940000, 6160000, 6380000, 6600000, 6820000, 7040000 }; -static const int pv88090_buck23_limits[] = { +static const unsigned int pv88090_buck23_limits[] = { 1496000, 2393000, 3291000, 4189000 }; @@ -150,40 +136,6 @@ static int pv88090_buck_set_mode(struct regulator_dev *rdev, PV88090_BUCK1_MODE_MASK, val); } -static int pv88090_set_current_limit(struct regulator_dev *rdev, int min, - int max) -{ - struct pv88090_regulator *info = rdev_get_drvdata(rdev); - int i; - - /* search for closest to maximum */ - for (i = info->n_current_limits; i >= 0; i--) { - if (min <= info->current_limits[i] - && max >= info->current_limits[i]) { - return regmap_update_bits(rdev->regmap, - info->conf, - info->limit_mask, - i << PV88090_BUCK1_ILIM_SHIFT); - } - } - - return -EINVAL; -} - -static int pv88090_get_current_limit(struct regulator_dev *rdev) -{ - struct pv88090_regulator *info = rdev_get_drvdata(rdev); - unsigned int data; - int ret; - - ret = regmap_read(rdev->regmap, info->conf, &data); - if (ret < 0) - return ret; - - data = (data & info->limit_mask) >> PV88090_BUCK1_ILIM_SHIFT; - return info->current_limits[data]; -} - static const struct regulator_ops pv88090_buck_ops = { .get_mode = pv88090_buck_get_mode, .set_mode = pv88090_buck_set_mode, @@ -193,8 +145,8 @@ static const struct regulator_ops pv88090_buck_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = pv88090_set_current_limit, - .get_current_limit = pv88090_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static const struct regulator_ops pv88090_ldo_ops = { @@ -223,10 +175,11 @@ static const struct regulator_ops pv88090_ldo_ops = { .enable_mask = PV88090_##regl_name##_EN, \ .vsel_reg = PV88090_REG_##regl_name##_CONF0, \ .vsel_mask = PV88090_V##regl_name##_MASK, \ + .curr_table = limits_array, \ + .n_current_limits = ARRAY_SIZE(limits_array), \ + .csel_reg = PV88090_REG_##regl_name##_CONF1, \ + .csel_mask = PV88090_##regl_name##_ILIM_MASK, \ },\ - .current_limits = limits_array, \ - .n_current_limits = ARRAY_SIZE(limits_array), \ - .limit_mask = PV88090_##regl_name##_ILIM_MASK, \ .conf = PV88090_REG_##regl_name##_CONF1, \ .conf2 = PV88090_REG_##regl_name##_CONF2, \ } @@ -274,9 +227,11 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data) if (reg_val & PV88090_E_VDD_FLT) { for (i = 0; i < PV88090_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -291,9 +246,11 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data) if (reg_val & PV88090_E_OVER_TEMP) { for (i = 0; i < PV88090_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); + regulator_unlock(chip->rdev[i]); } } diff --git a/drivers/regulator/pv88090-regulator.h b/drivers/regulator/pv88090-regulator.h index 62d9029277f4..f814ee52cff3 100644 --- a/drivers/regulator/pv88090-regulator.h +++ b/drivers/regulator/pv88090-regulator.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * pv88090-regulator.h - Regulator definitions for PV88090 * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __PV88090_REGISTERS_H__ diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index a2fd140eff81..e74e11101fc1 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for PWM Regulators * * Copyright (C) 2014 - STMicroelectronics Inc. * * Author: Lee Jones <lee.jones@linaro.org> - * - * 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/module.h> @@ -40,9 +37,6 @@ struct pwm_regulator_data { /* regulator descriptor */ struct regulator_desc desc; - /* Regulator ops */ - struct regulator_ops ops; - int state; /* Enable GPIO */ @@ -231,7 +225,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, return 0; } -static struct regulator_ops pwm_regulator_voltage_table_ops = { +static const struct regulator_ops pwm_regulator_voltage_table_ops = { .set_voltage_sel = pwm_regulator_set_voltage_sel, .get_voltage_sel = pwm_regulator_get_voltage_sel, .list_voltage = pwm_regulator_list_voltage, @@ -241,7 +235,7 @@ static struct regulator_ops pwm_regulator_voltage_table_ops = { .is_enabled = pwm_regulator_is_enabled, }; -static struct regulator_ops pwm_regulator_voltage_continuous_ops = { +static const struct regulator_ops pwm_regulator_voltage_continuous_ops = { .get_voltage = pwm_regulator_get_voltage, .set_voltage = pwm_regulator_set_voltage, .enable = pwm_regulator_enable, @@ -249,7 +243,7 @@ static struct regulator_ops pwm_regulator_voltage_continuous_ops = { .is_enabled = pwm_regulator_is_enabled, }; -static struct regulator_desc pwm_regulator_desc = { +static const struct regulator_desc pwm_regulator_desc = { .name = "pwm-regulator", .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, @@ -287,9 +281,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev, drvdata->state = -EINVAL; drvdata->duty_cycle_table = duty_cycle_table; - memcpy(&drvdata->ops, &pwm_regulator_voltage_table_ops, - sizeof(drvdata->ops)); - drvdata->desc.ops = &drvdata->ops; + drvdata->desc.ops = &pwm_regulator_voltage_table_ops; drvdata->desc.n_voltages = length / sizeof(*duty_cycle_table); return 0; @@ -301,9 +293,7 @@ static int pwm_regulator_init_continuous(struct platform_device *pdev, u32 dutycycle_range[2] = { 0, 100 }; u32 dutycycle_unit = 100; - memcpy(&drvdata->ops, &pwm_regulator_voltage_continuous_ops, - sizeof(drvdata->ops)); - drvdata->desc.ops = &drvdata->ops; + drvdata->desc.ops = &pwm_regulator_voltage_continuous_ops; drvdata->desc.continuous_voltage_range = true; of_property_read_u32_array(pdev->dev.of_node, diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 88dc0b0f003c..7407cd5a1b74 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014, Sony Mobile Communications AB. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index f5bca77d67c1..3b0828c79e2b 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, Sony Mobile Communications AB. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> @@ -31,6 +23,11 @@ struct qcom_rpm_reg { int is_enabled; int uV; + u32 load; + + unsigned int enabled_updated:1; + unsigned int uv_updated:1; + unsigned int load_updated:1; }; struct rpm_regulator_req { @@ -43,30 +40,59 @@ struct rpm_regulator_req { #define RPM_KEY_UV 0x00007675 /* "uv" */ #define RPM_KEY_MA 0x0000616d /* "ma" */ -static int rpm_reg_write_active(struct qcom_rpm_reg *vreg, - struct rpm_regulator_req *req, - size_t size) +static int rpm_reg_write_active(struct qcom_rpm_reg *vreg) { - return qcom_rpm_smd_write(vreg->rpm, - QCOM_SMD_RPM_ACTIVE_STATE, - vreg->type, - vreg->id, - req, size); + struct rpm_regulator_req req[3]; + int reqlen = 0; + int ret; + + if (vreg->enabled_updated) { + req[reqlen].key = cpu_to_le32(RPM_KEY_SWEN); + req[reqlen].nbytes = cpu_to_le32(sizeof(u32)); + req[reqlen].value = cpu_to_le32(vreg->is_enabled); + reqlen++; + } + + if (vreg->uv_updated && vreg->is_enabled) { + req[reqlen].key = cpu_to_le32(RPM_KEY_UV); + req[reqlen].nbytes = cpu_to_le32(sizeof(u32)); + req[reqlen].value = cpu_to_le32(vreg->uV); + reqlen++; + } + + if (vreg->load_updated && vreg->is_enabled) { + req[reqlen].key = cpu_to_le32(RPM_KEY_MA); + req[reqlen].nbytes = cpu_to_le32(sizeof(u32)); + req[reqlen].value = cpu_to_le32(vreg->load / 1000); + reqlen++; + } + + if (!reqlen) + return 0; + + ret = qcom_rpm_smd_write(vreg->rpm, QCOM_SMD_RPM_ACTIVE_STATE, + vreg->type, vreg->id, + req, sizeof(req[0]) * reqlen); + if (!ret) { + vreg->enabled_updated = 0; + vreg->uv_updated = 0; + vreg->load_updated = 0; + } + + return ret; } static int rpm_reg_enable(struct regulator_dev *rdev) { struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); - struct rpm_regulator_req req; int ret; - req.key = cpu_to_le32(RPM_KEY_SWEN); - req.nbytes = cpu_to_le32(sizeof(u32)); - req.value = cpu_to_le32(1); + vreg->is_enabled = 1; + vreg->enabled_updated = 1; - ret = rpm_reg_write_active(vreg, &req, sizeof(req)); - if (!ret) - vreg->is_enabled = 1; + ret = rpm_reg_write_active(vreg); + if (ret) + vreg->is_enabled = 0; return ret; } @@ -81,16 +107,14 @@ static int rpm_reg_is_enabled(struct regulator_dev *rdev) static int rpm_reg_disable(struct regulator_dev *rdev) { struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); - struct rpm_regulator_req req; int ret; - req.key = cpu_to_le32(RPM_KEY_SWEN); - req.nbytes = cpu_to_le32(sizeof(u32)); - req.value = 0; + vreg->is_enabled = 0; + vreg->enabled_updated = 1; - ret = rpm_reg_write_active(vreg, &req, sizeof(req)); - if (!ret) - vreg->is_enabled = 0; + ret = rpm_reg_write_active(vreg); + if (ret) + vreg->is_enabled = 1; return ret; } @@ -108,16 +132,15 @@ static int rpm_reg_set_voltage(struct regulator_dev *rdev, unsigned *selector) { struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); - struct rpm_regulator_req req; - int ret = 0; + int ret; + int old_uV = vreg->uV; - req.key = cpu_to_le32(RPM_KEY_UV); - req.nbytes = cpu_to_le32(sizeof(u32)); - req.value = cpu_to_le32(min_uV); + vreg->uV = min_uV; + vreg->uv_updated = 1; - ret = rpm_reg_write_active(vreg, &req, sizeof(req)); - if (!ret) - vreg->uV = min_uV; + ret = rpm_reg_write_active(vreg); + if (ret) + vreg->uV = old_uV; return ret; } @@ -125,13 +148,16 @@ static int rpm_reg_set_voltage(struct regulator_dev *rdev, static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA) { struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); - struct rpm_regulator_req req; + u32 old_load = vreg->load; + int ret; - req.key = cpu_to_le32(RPM_KEY_MA); - req.nbytes = cpu_to_le32(sizeof(u32)); - req.value = cpu_to_le32(load_uA / 1000); + vreg->load = load_uA; + vreg->load_updated = 1; + ret = rpm_reg_write_active(vreg); + if (ret) + vreg->load = old_load; - return rpm_reg_write_active(vreg, &req, sizeof(req)); + return ret; } static const struct regulator_ops rpm_smps_ldo_ops = { diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 53a61fb65642..6dfc9e176360 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 2ec51af43673..62641b08b88a 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for RICOH RC5T583 power management chip. * @@ -6,20 +7,6 @@ * * based on code * Copyright (C) 2011 RICOH COMPANY,LTD - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * */ #include <linux/module.h> @@ -47,18 +34,13 @@ struct rc5t583_regulator_info { struct regulator_desc desc; }; -struct rc5t583_regulator { - struct rc5t583_regulator_info *reg_info; - struct regulator_dev *rdev; -}; - static int rc5t583_regulator_enable_time(struct regulator_dev *rdev) { - struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); + struct rc5t583_regulator_info *reg_info = rdev_get_drvdata(rdev); int vsel = regulator_get_voltage_sel_regmap(rdev); int curr_uV = regulator_list_voltage_linear(rdev, vsel); - return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us); + return DIV_ROUND_UP(curr_uV, reg_info->enable_uv_per_us); } static const struct regulator_ops rc5t583_ops = { @@ -120,8 +102,6 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); struct regulator_config config = { }; - struct rc5t583_regulator *reg = NULL; - struct rc5t583_regulator *regs; struct regulator_dev *rdev; struct rc5t583_regulator_info *ri; int ret; @@ -132,18 +112,8 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) return -ENODEV; } - regs = devm_kcalloc(&pdev->dev, - RC5T583_REGULATOR_MAX, - sizeof(struct rc5t583_regulator), - GFP_KERNEL); - if (!regs) - return -ENOMEM; - - for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { - reg = ®s[id]; ri = &rc5t583_reg_info[id]; - reg->reg_info = ri; if (ri->deepsleep_id == RC5T583_DS_NONE) goto skip_ext_pwr_config; @@ -163,7 +133,7 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) skip_ext_pwr_config: config.dev = &pdev->dev; config.init_data = pdata->reg_init_data[id]; - config.driver_data = reg; + config.driver_data = ri; config.regmap = rc5t583->regmap; rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); @@ -172,9 +142,7 @@ skip_ext_pwr_config: ri->desc.name); return PTR_ERR(rdev); } - reg->rdev = rdev; } - platform_set_drvdata(pdev, regs); return 0; } diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 213b68743cc8..061ebc4b3477 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -1,5 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* - * Regulator driver for Rockchip RK808/RK818 + * Regulator driver for Rockchip RK805/RK808/RK818 * * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd * @@ -9,15 +10,6 @@ * Copyright (C) 2016 PHYTEC Messtechnik GmbH * * Author: Wadim Egorov <w.egorov@phytec.de> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/delay.h> @@ -363,28 +355,28 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev) rdev->desc->enable_mask); } -static struct regulator_ops rk805_reg_ops = { - .list_voltage = regulator_list_voltage_linear, - .map_voltage = regulator_map_voltage_linear, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .set_suspend_voltage = rk808_set_suspend_voltage, - .set_suspend_enable = rk805_set_suspend_enable, - .set_suspend_disable = rk805_set_suspend_disable, +static const struct regulator_ops rk805_reg_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_suspend_voltage = rk808_set_suspend_voltage, + .set_suspend_enable = rk805_set_suspend_enable, + .set_suspend_disable = rk805_set_suspend_disable, }; -static struct regulator_ops rk805_switch_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .set_suspend_enable = rk805_set_suspend_enable, - .set_suspend_disable = rk805_set_suspend_disable, +static const struct regulator_ops rk805_switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_suspend_enable = rk805_set_suspend_enable, + .set_suspend_disable = rk805_set_suspend_disable, }; -static struct regulator_ops rk808_buck1_2_ops = { +static const struct regulator_ops rk808_buck1_2_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = rk808_buck1_2_get_voltage_sel_regmap, @@ -399,7 +391,7 @@ static struct regulator_ops rk808_buck1_2_ops = { .set_suspend_disable = rk808_set_suspend_disable, }; -static struct regulator_ops rk808_reg_ops = { +static const struct regulator_ops rk808_reg_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -412,7 +404,7 @@ static struct regulator_ops rk808_reg_ops = { .set_suspend_disable = rk808_set_suspend_disable, }; -static struct regulator_ops rk808_reg_ops_ranges = { +static const struct regulator_ops rk808_reg_ops_ranges = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -425,7 +417,7 @@ static struct regulator_ops rk808_reg_ops_ranges = { .set_suspend_disable = rk808_set_suspend_disable, }; -static struct regulator_ops rk808_switch_ops = { +static const struct regulator_ops rk808_switch_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -433,6 +425,12 @@ static struct regulator_ops rk808_switch_ops = { .set_suspend_disable = rk808_set_suspend_disable, }; +static const struct regulator_linear_range rk805_buck_1_2_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(712500, 0, 59, 12500), + REGULATOR_LINEAR_RANGE(1800000, 60, 62, 200000), + REGULATOR_LINEAR_RANGE(2300000, 63, 63, 0), +}; + static const struct regulator_desc rk805_reg[] = { { .name = "DCDC_REG1", @@ -440,11 +438,11 @@ static const struct regulator_desc rk805_reg[] = { .of_match = of_match_ptr("DCDC_REG1"), .regulators_node = of_match_ptr("regulators"), .id = RK805_ID_DCDC1, - .ops = &rk805_reg_ops, + .ops = &rk808_reg_ops_ranges, .type = REGULATOR_VOLTAGE, - .min_uV = 712500, - .uV_step = 12500, .n_voltages = 64, + .linear_ranges = rk805_buck_1_2_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges), .vsel_reg = RK805_BUCK1_ON_VSEL_REG, .vsel_mask = RK818_BUCK_VSEL_MASK, .enable_reg = RK805_DCDC_EN_REG, @@ -456,11 +454,11 @@ static const struct regulator_desc rk805_reg[] = { .of_match = of_match_ptr("DCDC_REG2"), .regulators_node = of_match_ptr("regulators"), .id = RK805_ID_DCDC2, - .ops = &rk805_reg_ops, + .ops = &rk808_reg_ops_ranges, .type = REGULATOR_VOLTAGE, - .min_uV = 712500, - .uV_step = 12500, .n_voltages = 64, + .linear_ranges = rk805_buck_1_2_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges), .vsel_reg = RK805_BUCK2_ON_VSEL_REG, .vsel_mask = RK818_BUCK_VSEL_MASK, .enable_reg = RK805_DCDC_EN_REG, @@ -796,7 +794,7 @@ static struct platform_driver rk808_regulator_driver = { module_platform_driver(rk808_regulator_driver); -MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs"); +MODULE_DESCRIPTION("regulator driver for the RK805/RK808/RK818 series PMICs"); MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c index 790a4a73ea2c..eb807a059479 100644 --- a/drivers/regulator/rn5t618-regulator.c +++ b/drivers/regulator/rn5t618-regulator.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for Ricoh RN5T618 PMIC * * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/mfd/rn5t618.h> @@ -46,7 +40,7 @@ static const struct regulator_ops rn5t618_reg_ops = { .vsel_mask = (vmask), \ } -static struct regulator_desc rn5t567_regulators[] = { +static const struct regulator_desc rn5t567_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), @@ -63,7 +57,7 @@ static struct regulator_desc rn5t567_regulators[] = { REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), }; -static struct regulator_desc rn5t618_regulators[] = { +static const struct regulator_desc rn5t618_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), @@ -79,7 +73,7 @@ static struct regulator_desc rn5t618_regulators[] = { REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), }; -static struct regulator_desc rc5t619_regulators[] = { +static const struct regulator_desc rc5t619_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), @@ -107,7 +101,7 @@ static int rn5t618_regulator_probe(struct platform_device *pdev) struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct regulator_dev *rdev; - struct regulator_desc *regulators; + const struct regulator_desc *regulators; int i; int num_regulators = 0; diff --git a/drivers/regulator/rt5033-regulator.c b/drivers/regulator/rt5033-regulator.c index 96d2c18e051a..0e7311629165 100644 --- a/drivers/regulator/rt5033-regulator.c +++ b/drivers/regulator/rt5033-regulator.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for the Richtek RT5033 * * Copyright (C) 2014 Samsung Electronics, Co., Ltd. * Author: Beomho Seo <beomho.seo@samsung.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 bythe Free Software Foundation. */ #include <linux/module.h> @@ -16,14 +13,14 @@ #include <linux/mfd/rt5033-private.h> #include <linux/regulator/of_regulator.h> -static struct regulator_ops rt5033_safe_ldo_ops = { +static const struct regulator_ops rt5033_safe_ldo_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .list_voltage = regulator_list_voltage_linear, }; -static struct regulator_ops rt5033_buck_ops = { +static const struct regulator_ops rt5033_buck_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 095d25f3d2ea..51f7e8b74d8c 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -17,10 +17,7 @@ #include <linux/mfd/samsung/core.h> #include <linux/mfd/samsung/s2mpa01.h> -#define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators) - struct s2mpa01_info { - struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX]; int ramp_delay24; int ramp_delay3; int ramp_delay5; @@ -232,6 +229,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_ldo(num, step) { \ .name = "LDO"#num, \ + .of_match = of_match_ptr("LDO"#num), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_LDO##num, \ .ops = &s2mpa01_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -247,6 +246,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_buck1_4(num) { \ .name = "BUCK"#num, \ + .of_match = of_match_ptr("BUCK"#num), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_BUCK##num, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -263,6 +264,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_buck5 { \ .name = "BUCK5", \ + .of_match = of_match_ptr("BUCK5"), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_BUCK5, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -279,6 +282,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_buck6_10(num, min, step) { \ .name = "BUCK"#num, \ + .of_match = of_match_ptr("BUCK"#num), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_BUCK##num, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -298,13 +303,13 @@ static const struct regulator_desc regulators[] = { regulator_desc_ldo(2, STEP_50_MV), regulator_desc_ldo(3, STEP_50_MV), regulator_desc_ldo(4, STEP_50_MV), - regulator_desc_ldo(5, STEP_50_MV), + regulator_desc_ldo(5, STEP_25_MV), regulator_desc_ldo(6, STEP_25_MV), regulator_desc_ldo(7, STEP_50_MV), regulator_desc_ldo(8, STEP_50_MV), regulator_desc_ldo(9, STEP_50_MV), regulator_desc_ldo(10, STEP_50_MV), - regulator_desc_ldo(11, STEP_25_MV), + regulator_desc_ldo(11, STEP_50_MV), regulator_desc_ldo(12, STEP_50_MV), regulator_desc_ldo(13, STEP_50_MV), regulator_desc_ldo(14, STEP_50_MV), @@ -315,11 +320,11 @@ static const struct regulator_desc regulators[] = { regulator_desc_ldo(19, STEP_50_MV), regulator_desc_ldo(20, STEP_50_MV), regulator_desc_ldo(21, STEP_50_MV), - regulator_desc_ldo(22, STEP_25_MV), - regulator_desc_ldo(23, STEP_25_MV), + regulator_desc_ldo(22, STEP_50_MV), + regulator_desc_ldo(23, STEP_50_MV), regulator_desc_ldo(24, STEP_50_MV), regulator_desc_ldo(25, STEP_50_MV), - regulator_desc_ldo(26, STEP_50_MV), + regulator_desc_ldo(26, STEP_25_MV), regulator_desc_buck1_4(1), regulator_desc_buck1_4(2), regulator_desc_buck1_4(3), @@ -336,9 +341,7 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); - struct device_node *reg_np = NULL; struct regulator_config config = { }; - struct of_regulator_match *rdata; struct s2mpa01_info *s2mpa01; int i; @@ -346,39 +349,15 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev) if (!s2mpa01) return -ENOMEM; - rdata = s2mpa01->rdata; - for (i = 0; i < S2MPA01_REGULATOR_CNT; i++) - rdata[i].name = regulators[i].name; - - if (iodev->dev->of_node) { - reg_np = of_get_child_by_name(iodev->dev->of_node, - "regulators"); - if (!reg_np) { - dev_err(&pdev->dev, - "could not find regulators sub-node\n"); - return -EINVAL; - } - - of_regulator_match(&pdev->dev, reg_np, rdata, - S2MPA01_REGULATOR_MAX); - of_node_put(reg_np); - } - - platform_set_drvdata(pdev, s2mpa01); - - config.dev = &pdev->dev; + config.dev = iodev->dev; config.regmap = iodev->regmap_pmic; config.driver_data = s2mpa01; for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) { struct regulator_dev *rdev; + if (pdata) config.init_data = pdata->regulators[i].initdata; - else - config.init_data = rdata[i].init_data; - - if (reg_np) - config.of_node = rdata[i].of_node; rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index ee4a23ab0663..134c62db36c5 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -362,7 +362,7 @@ static const struct regulator_desc s2mps11_regulators[] = { regulator_desc_s2mps11_ldo(32, STEP_50_MV), regulator_desc_s2mps11_ldo(33, STEP_50_MV), regulator_desc_s2mps11_ldo(34, STEP_50_MV), - regulator_desc_s2mps11_ldo(35, STEP_50_MV), + regulator_desc_s2mps11_ldo(35, STEP_25_MV), regulator_desc_s2mps11_ldo(36, STEP_50_MV), regulator_desc_s2mps11_ldo(37, STEP_50_MV), regulator_desc_s2mps11_ldo(38, STEP_50_MV), @@ -372,8 +372,8 @@ static const struct regulator_desc s2mps11_regulators[] = { regulator_desc_s2mps11_buck1_4(4), regulator_desc_s2mps11_buck5, regulator_desc_s2mps11_buck67810(6, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps11_buck67810(7, MIN_600_MV, STEP_6_25_MV), - regulator_desc_s2mps11_buck67810(8, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck67810(7, MIN_600_MV, STEP_12_5_MV), + regulator_desc_s2mps11_buck67810(8, MIN_600_MV, STEP_12_5_MV), regulator_desc_s2mps11_buck9, regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV), }; diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index b581f01f3395..bb9d1a083299 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -115,7 +115,7 @@ static const struct sec_voltage_desc *reg_voltage_map[] = { [S5M8767_BUCK9] = &buck_voltage_val3, }; -static unsigned int s5m8767_opmode_reg[][4] = { +static const unsigned int s5m8767_opmode_reg[][4] = { /* {OFF, ON, LOWPOWER, SUSPEND} */ /* LDO1 ... LDO28 */ {0x0, 0x3, 0x2, 0x1}, /* LDO1 */ @@ -339,13 +339,9 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int new_sel) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); - const struct sec_voltage_desc *desc; - int reg_id = rdev_get_id(rdev); - - desc = reg_voltage_map[reg_id]; if ((old_sel < new_sel) && s5m8767->ramp_delay) - return DIV_ROUND_UP(desc->step * (new_sel - old_sel), + return DIV_ROUND_UP(rdev->desc->uV_step * (new_sel - old_sel), s5m8767->ramp_delay * 1000); return 0; } diff --git a/drivers/regulator/sc2731-regulator.c b/drivers/regulator/sc2731-regulator.c index eb2bdf060b7b..0f21f95c8981 100644 --- a/drivers/regulator/sc2731-regulator.c +++ b/drivers/regulator/sc2731-regulator.c @@ -146,7 +146,7 @@ static const struct regulator_ops sc2731_regu_linear_ops = { .vsel_mask = vmask, \ } -static struct regulator_desc regulators[] = { +static const struct regulator_desc regulators[] = { SC2731_REGU_LINEAR(BUCK_CPU0, SC2731_POWER_PD_SW, SC2731_DCDC_CPU0_PD_MASK, SC2731_DCDC_CPU0_VOL, SC2731_DCDC_CPU0_VOL_MASK, 3125, 400000, 1996875), diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c index 647860611916..177dede82a61 100644 --- a/drivers/regulator/sky81452-regulator.c +++ b/drivers/regulator/sky81452-regulator.c @@ -1,21 +1,9 @@ -/* - * sky81452-regulator.c SKY81452 regulator driver - * - * Copyright 2014 Skyworks Solutions Inc. - * Author : Gyungoh Yoo <jack.yoo@skyworksinc.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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// sky81452-regulator.c SKY81452 regulator driver +// +// Copyright 2014 Skyworks Solutions Inc. +// Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> #include <linux/module.h> #include <linux/kernel.h> @@ -34,7 +22,7 @@ #define SKY81452_LEN 0x40 #define SKY81452_LOUT 0x1F -static struct regulator_ops sky81452_reg_ops = { +static const struct regulator_ops sky81452_reg_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c new file mode 100644 index 000000000000..e0e627b0106e --- /dev/null +++ b/drivers/regulator/stm32-pwr.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) STMicroelectronics 2019 +// Authors: Gabriel Fernandez <gabriel.fernandez@st.com> +// Pascal Paillet <p.paillet@st.com>. + +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/of_regulator.h> + +/* + * Registers description + */ +#define REG_PWR_CR3 0x0C + +#define USB_3_3_EN BIT(24) +#define USB_3_3_RDY BIT(26) +#define REG_1_8_EN BIT(28) +#define REG_1_8_RDY BIT(29) +#define REG_1_1_EN BIT(30) +#define REG_1_1_RDY BIT(31) + +/* list of supported regulators */ +enum { + PWR_REG11, + PWR_REG18, + PWR_USB33, + STM32PWR_REG_NUM_REGS +}; + +static u32 ready_mask_table[STM32PWR_REG_NUM_REGS] = { + [PWR_REG11] = REG_1_1_RDY, + [PWR_REG18] = REG_1_8_RDY, + [PWR_USB33] = USB_3_3_RDY, +}; + +struct stm32_pwr_reg { + void __iomem *base; + u32 ready_mask; +}; + +static int stm32_pwr_reg_is_ready(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + + return (val & priv->ready_mask); +} + +static int stm32_pwr_reg_is_enabled(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + + return (val & rdev->desc->enable_mask); +} + +static int stm32_pwr_reg_enable(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + int ret; + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + val |= rdev->desc->enable_mask; + writel_relaxed(val, priv->base + REG_PWR_CR3); + + /* use an arbitrary timeout of 20ms */ + ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, val, + 100, 20 * 1000); + if (ret) + dev_err(&rdev->dev, "regulator enable timed out!\n"); + + return ret; +} + +static int stm32_pwr_reg_disable(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + int ret; + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + val &= ~rdev->desc->enable_mask; + writel_relaxed(val, priv->base + REG_PWR_CR3); + + /* use an arbitrary timeout of 20ms */ + ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val, + 100, 20 * 1000); + if (ret) + dev_err(&rdev->dev, "regulator disable timed out!\n"); + + return ret; +} + +static const struct regulator_ops stm32_pwr_reg_ops = { + .enable = stm32_pwr_reg_enable, + .disable = stm32_pwr_reg_disable, + .is_enabled = stm32_pwr_reg_is_enabled, +}; + +#define PWR_REG(_id, _name, _volt, _en, _supply) \ + [_id] = { \ + .id = _id, \ + .name = _name, \ + .of_match = of_match_ptr(_name), \ + .n_voltages = 1, \ + .type = REGULATOR_VOLTAGE, \ + .fixed_uV = _volt, \ + .ops = &stm32_pwr_reg_ops, \ + .enable_mask = _en, \ + .owner = THIS_MODULE, \ + .supply_name = _supply, \ + } \ + +static const struct regulator_desc stm32_pwr_desc[] = { + PWR_REG(PWR_REG11, "reg11", 1100000, REG_1_1_EN, "vdd"), + PWR_REG(PWR_REG18, "reg18", 1800000, REG_1_8_EN, "vdd"), + PWR_REG(PWR_USB33, "usb33", 3300000, USB_3_3_EN, "vdd_3v3_usbfs"), +}; + +static int stm32_pwr_regulator_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct stm32_pwr_reg *priv; + void __iomem *base; + struct regulator_dev *rdev; + struct regulator_config config = { }; + int i, ret = 0; + + base = of_iomap(np, 0); + if (!base) { + dev_err(&pdev->dev, "Unable to map IO memory\n"); + return -ENOMEM; + } + + config.dev = &pdev->dev; + + for (i = 0; i < STM32PWR_REG_NUM_REGS; i++) { + priv = devm_kzalloc(&pdev->dev, sizeof(struct stm32_pwr_reg), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->base = base; + priv->ready_mask = ready_mask_table[i]; + config.driver_data = priv; + + rdev = devm_regulator_register(&pdev->dev, + &stm32_pwr_desc[i], + &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(&pdev->dev, + "Failed to register regulator: %d\n", ret); + break; + } + } + return ret; +} + +static const struct of_device_id stm32_pwr_of_match[] = { + { .compatible = "st,stm32mp1,pwr-reg", }, + {}, +}; +MODULE_DEVICE_TABLE(of, stm32_pwr_of_match); + +static struct platform_driver stm32_pwr_driver = { + .probe = stm32_pwr_regulator_probe, + .driver = { + .name = "stm32-pwr-regulator", + .of_match_table = of_match_ptr(stm32_pwr_of_match), + }, +}; +module_platform_driver(stm32_pwr_driver); + +MODULE_DESCRIPTION("STM32MP1 PWR voltage regulator driver"); +MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c index e0a9c445ed67..8919a5130bec 100644 --- a/drivers/regulator/stm32-vrefbuf.c +++ b/drivers/regulator/stm32-vrefbuf.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) STMicroelectronics 2017 * * Author: Fabrice Gasnier <fabrice.gasnier@st.com> - * - * License terms: GNU General Public License (GPL), version 2 */ #include <linux/bitfield.h> @@ -15,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/of_regulator.h> +#include <linux/pm_runtime.h> /* STM32 VREFBUF registers */ #define STM32_VREFBUF_CSR 0x00 @@ -25,9 +25,12 @@ #define STM32_HIZ BIT(1) #define STM32_ENVR BIT(0) +#define STM32_VREFBUF_AUTO_SUSPEND_DELAY_MS 10 + struct stm32_vrefbuf { void __iomem *base; struct clk *clk; + struct device *dev; }; static const unsigned int stm32_vrefbuf_voltages[] = { @@ -38,9 +41,16 @@ static const unsigned int stm32_vrefbuf_voltages[] = { static int stm32_vrefbuf_enable(struct regulator_dev *rdev) { struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); - u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); + u32 val; int ret; + ret = pm_runtime_get_sync(priv->dev); + if (ret < 0) { + pm_runtime_put_noidle(priv->dev); + return ret; + } + + val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = (val & ~STM32_HIZ) | STM32_ENVR; writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); @@ -59,45 +69,95 @@ static int stm32_vrefbuf_enable(struct regulator_dev *rdev) writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); } + pm_runtime_mark_last_busy(priv->dev); + pm_runtime_put_autosuspend(priv->dev); + return ret; } static int stm32_vrefbuf_disable(struct regulator_dev *rdev) { struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); - u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); + u32 val; + int ret; + + ret = pm_runtime_get_sync(priv->dev); + if (ret < 0) { + pm_runtime_put_noidle(priv->dev); + return ret; + } + val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = (val & ~STM32_ENVR) | STM32_HIZ; writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); + pm_runtime_mark_last_busy(priv->dev); + pm_runtime_put_autosuspend(priv->dev); + return 0; } static int stm32_vrefbuf_is_enabled(struct regulator_dev *rdev) { struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); + int ret; - return readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR; + ret = pm_runtime_get_sync(priv->dev); + if (ret < 0) { + pm_runtime_put_noidle(priv->dev); + return ret; + } + + ret = readl_relaxed(priv->base + STM32_VREFBUF_CSR) & STM32_ENVR; + + pm_runtime_mark_last_busy(priv->dev); + pm_runtime_put_autosuspend(priv->dev); + + return ret; } static int stm32_vrefbuf_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) { struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); - u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); + u32 val; + int ret; + + ret = pm_runtime_get_sync(priv->dev); + if (ret < 0) { + pm_runtime_put_noidle(priv->dev); + return ret; + } + val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); val = (val & ~STM32_VRS) | FIELD_PREP(STM32_VRS, sel); writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); + pm_runtime_mark_last_busy(priv->dev); + pm_runtime_put_autosuspend(priv->dev); + return 0; } static int stm32_vrefbuf_get_voltage_sel(struct regulator_dev *rdev) { struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); - u32 val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); + u32 val; + int ret; - return FIELD_GET(STM32_VRS, val); + ret = pm_runtime_get_sync(priv->dev); + if (ret < 0) { + pm_runtime_put_noidle(priv->dev); + return ret; + } + + val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); + ret = FIELD_GET(STM32_VRS, val); + + pm_runtime_mark_last_busy(priv->dev); + pm_runtime_put_autosuspend(priv->dev); + + return ret; } static const struct regulator_ops stm32_vrefbuf_volt_ops = { @@ -130,6 +190,7 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev) priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); @@ -140,10 +201,17 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev) if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, + STM32_VREFBUF_AUTO_SUSPEND_DELAY_MS); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = clk_prepare_enable(priv->clk); if (ret) { dev_err(&pdev->dev, "clk prepare failed with error %d\n", ret); - return ret; + goto err_pm_stop; } config.dev = &pdev->dev; @@ -161,10 +229,17 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, rdev); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + return 0; err_clk_dis: clk_disable_unprepare(priv->clk); +err_pm_stop: + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); return ret; } @@ -174,10 +249,40 @@ static int stm32_vrefbuf_remove(struct platform_device *pdev) struct regulator_dev *rdev = platform_get_drvdata(pdev); struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); + pm_runtime_get_sync(&pdev->dev); regulator_unregister(rdev); clk_disable_unprepare(priv->clk); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + + return 0; +}; + +static int __maybe_unused stm32_vrefbuf_runtime_suspend(struct device *dev) +{ + struct regulator_dev *rdev = dev_get_drvdata(dev); + struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); + + clk_disable_unprepare(priv->clk); return 0; +} + +static int __maybe_unused stm32_vrefbuf_runtime_resume(struct device *dev) +{ + struct regulator_dev *rdev = dev_get_drvdata(dev); + struct stm32_vrefbuf *priv = rdev_get_drvdata(rdev); + + return clk_prepare_enable(priv->clk); +} + +static const struct dev_pm_ops stm32_vrefbuf_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(stm32_vrefbuf_runtime_suspend, + stm32_vrefbuf_runtime_resume, + NULL) }; static const struct of_device_id stm32_vrefbuf_of_match[] = { @@ -192,6 +297,7 @@ static struct platform_driver stm32_vrefbuf_driver = { .driver = { .name = "stm32-vrefbuf", .of_match_table = of_match_ptr(stm32_vrefbuf_of_match), + .pm = &stm32_vrefbuf_pm_ops, }, }; module_platform_driver(stm32_vrefbuf_driver); diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c index 16ba0297f709..f09061473613 100644 --- a/drivers/regulator/stpmic1_regulator.c +++ b/drivers/regulator/stpmic1_regulator.c @@ -12,8 +12,10 @@ #include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> +#include <dt-bindings/mfd/st,stpmic1.h> + /** - * stpmic1 regulator description + * stpmic1 regulator description: this structure is used as driver data * @desc: regulator framework description * @mask_reset_reg: mask reset register address * @mask_reset_mask: mask rank and mask reset register mask @@ -28,28 +30,9 @@ struct stpmic1_regulator_cfg { u8 icc_mask; }; -/** - * stpmic1 regulator data: this structure is used as driver data - * @regul_id: regulator id - * @reg_node: DT node of regulator (unused on non-DT platforms) - * @cfg: stpmic specific regulator description - * @mask_reset: mask_reset bit value - * @irq_curlim: current limit interrupt number - * @regmap: point to parent regmap structure - */ -struct stpmic1_regulator { - unsigned int regul_id; - struct device_node *reg_node; - struct stpmic1_regulator_cfg *cfg; - u8 mask_reset; - int irq_curlim; - struct regmap *regmap; -}; - static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode); static unsigned int stpmic1_get_mode(struct regulator_dev *rdev); static int stpmic1_set_icc(struct regulator_dev *rdev); -static int stpmic1_regulator_parse_dt(void *driver_data); static unsigned int stpmic1_map_mode(unsigned int mode); enum { @@ -72,15 +55,13 @@ enum { /* Enable time worst case is 5000mV/(2250uV/uS) */ #define PMIC_ENABLE_TIME_US 2200 -#define STPMIC1_BUCK_MODE_NORMAL 0 -#define STPMIC1_BUCK_MODE_LP BUCK_HPLP_ENABLE_MASK - -struct regulator_linear_range buck1_ranges[] = { - REGULATOR_LINEAR_RANGE(600000, 0, 30, 25000), - REGULATOR_LINEAR_RANGE(1350000, 31, 63, 0), +static const struct regulator_linear_range buck1_ranges[] = { + REGULATOR_LINEAR_RANGE(725000, 0, 4, 0), + REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000), + REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0), }; -struct regulator_linear_range buck2_ranges[] = { +static const struct regulator_linear_range buck2_ranges[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0), REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0), REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0), @@ -94,7 +75,7 @@ struct regulator_linear_range buck2_ranges[] = { REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0), }; -struct regulator_linear_range buck3_ranges[] = { +static const struct regulator_linear_range buck3_ranges[] = { REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0), REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0), REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0), @@ -102,10 +83,9 @@ struct regulator_linear_range buck3_ranges[] = { REGULATOR_LINEAR_RANGE(1400000, 32, 35, 0), REGULATOR_LINEAR_RANGE(1500000, 36, 55, 100000), REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0), - }; -struct regulator_linear_range buck4_ranges[] = { +static const struct regulator_linear_range buck4_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000), REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0), REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0), @@ -113,24 +93,21 @@ struct regulator_linear_range buck4_ranges[] = { REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0), REGULATOR_LINEAR_RANGE(1500000, 36, 60, 100000), REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0), - }; -struct regulator_linear_range ldo1_ranges[] = { +static const struct regulator_linear_range ldo1_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0), - }; -struct regulator_linear_range ldo2_ranges[] = { +static const struct regulator_linear_range ldo2_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0), - }; -struct regulator_linear_range ldo3_ranges[] = { +static const struct regulator_linear_range ldo3_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0), @@ -138,18 +115,18 @@ struct regulator_linear_range ldo3_ranges[] = { REGULATOR_LINEAR_RANGE(500000, 31, 31, 0), }; -struct regulator_linear_range ldo5_ranges[] = { +static const struct regulator_linear_range ldo5_ranges[] = { REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0), REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000), REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0), }; -struct regulator_linear_range ldo6_ranges[] = { +static const struct regulator_linear_range ldo6_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000), REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0), }; -static struct regulator_ops stpmic1_ldo_ops = { +static const struct regulator_ops stpmic1_ldo_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .is_enabled = regulator_is_enabled_regmap, @@ -157,11 +134,10 @@ static struct regulator_ops stpmic1_ldo_ops = { .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_pull_down = regulator_set_pull_down_regmap, .set_over_current_protection = stpmic1_set_icc, }; -static struct regulator_ops stpmic1_ldo3_ops = { +static const struct regulator_ops stpmic1_ldo3_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_iterate, .is_enabled = regulator_is_enabled_regmap, @@ -169,21 +145,19 @@ static struct regulator_ops stpmic1_ldo3_ops = { .disable = regulator_disable_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .set_pull_down = regulator_set_pull_down_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, .set_over_current_protection = stpmic1_set_icc, }; -static struct regulator_ops stpmic1_ldo4_fixed_regul_ops = { +static const struct regulator_ops stpmic1_ldo4_fixed_regul_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .set_pull_down = regulator_set_pull_down_regmap, .set_over_current_protection = stpmic1_set_icc, }; -static struct regulator_ops stpmic1_buck_ops = { +static const struct regulator_ops stpmic1_buck_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .is_enabled = regulator_is_enabled_regmap, @@ -197,20 +171,27 @@ static struct regulator_ops stpmic1_buck_ops = { .set_over_current_protection = stpmic1_set_icc, }; -static struct regulator_ops stpmic1_vref_ddr_ops = { +static const struct regulator_ops stpmic1_vref_ddr_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .set_pull_down = regulator_set_pull_down_regmap, }; -static struct regulator_ops stpmic1_switch_regul_ops = { +static const struct regulator_ops stpmic1_boost_regul_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .set_over_current_protection = stpmic1_set_icc, }; +static const struct regulator_ops stpmic1_switch_regul_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .set_over_current_protection = stpmic1_set_icc, + .set_active_discharge = regulator_set_active_discharge_regmap, +}; + #define REG_LDO(ids, base) { \ .name = #ids, \ .id = STPMIC1_##ids, \ @@ -227,8 +208,6 @@ static struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ - .pull_down_reg = ids##_PULL_DOWN_REG, \ - .pull_down_mask = ids##_PULL_DOWN_MASK, \ .supply_name = #base, \ } @@ -252,8 +231,6 @@ static struct regulator_ops stpmic1_switch_regul_ops = { .bypass_mask = LDO_BYPASS_MASK, \ .bypass_val_on = LDO_BYPASS_MASK, \ .bypass_val_off = 0, \ - .pull_down_reg = ids##_PULL_DOWN_REG, \ - .pull_down_mask = ids##_PULL_DOWN_MASK, \ .supply_name = #base, \ } @@ -271,8 +248,6 @@ static struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ - .pull_down_reg = ids##_PULL_DOWN_REG, \ - .pull_down_mask = ids##_PULL_DOWN_MASK, \ .supply_name = #base, \ } @@ -312,12 +287,47 @@ static struct regulator_ops stpmic1_switch_regul_ops = { .enable_val = 1, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ - .pull_down_reg = ids##_PULL_DOWN_REG, \ - .pull_down_mask = ids##_PULL_DOWN_MASK, \ .supply_name = #base, \ } -#define REG_SWITCH(ids, base, reg, mask, val) { \ +#define REG_BOOST(ids, base) { \ + .name = #ids, \ + .id = STPMIC1_##ids, \ + .n_voltages = 1, \ + .ops = &stpmic1_boost_regul_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 0, \ + .fixed_uV = 5000000, \ + .enable_reg = BST_SW_CR, \ + .enable_mask = BOOST_ENABLED, \ + .enable_val = BOOST_ENABLED, \ + .disable_val = 0, \ + .enable_time = PMIC_ENABLE_TIME_US, \ + .supply_name = #base, \ +} + +#define REG_VBUS_OTG(ids, base) { \ + .name = #ids, \ + .id = STPMIC1_##ids, \ + .n_voltages = 1, \ + .ops = &stpmic1_switch_regul_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 0, \ + .fixed_uV = 5000000, \ + .enable_reg = BST_SW_CR, \ + .enable_mask = USBSW_OTG_SWITCH_ENABLED, \ + .enable_val = USBSW_OTG_SWITCH_ENABLED, \ + .disable_val = 0, \ + .enable_time = PMIC_ENABLE_TIME_US, \ + .supply_name = #base, \ + .active_discharge_reg = BST_SW_CR, \ + .active_discharge_mask = VBUS_OTG_DISCHARGE, \ + .active_discharge_on = VBUS_OTG_DISCHARGE, \ +} + +#define REG_SW_OUT(ids, base) { \ .name = #ids, \ .id = STPMIC1_##ids, \ .n_voltages = 1, \ @@ -326,15 +336,18 @@ static struct regulator_ops stpmic1_switch_regul_ops = { .owner = THIS_MODULE, \ .min_uV = 0, \ .fixed_uV = 5000000, \ - .enable_reg = (reg), \ - .enable_mask = (mask), \ - .enable_val = (val), \ + .enable_reg = BST_SW_CR, \ + .enable_mask = SWIN_SWOUT_ENABLED, \ + .enable_val = SWIN_SWOUT_ENABLED, \ .disable_val = 0, \ .enable_time = PMIC_ENABLE_TIME_US, \ .supply_name = #base, \ + .active_discharge_reg = BST_SW_CR, \ + .active_discharge_mask = SW_OUT_DISCHARGE, \ + .active_discharge_on = SW_OUT_DISCHARGE, \ } -struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = { +static const struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = { [STPMIC1_BUCK1] = { .desc = REG_BUCK(BUCK1, buck1), .icc_reg = BUCKS_ICCTO_CR, @@ -411,23 +424,17 @@ struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = { .mask_reset_mask = BIT(6), }, [STPMIC1_BOOST] = { - .desc = REG_SWITCH(BOOST, boost, BST_SW_CR, - BOOST_ENABLED, - BOOST_ENABLED), + .desc = REG_BOOST(BOOST, boost), .icc_reg = BUCKS_ICCTO_CR, .icc_mask = BIT(6), }, [STPMIC1_VBUS_OTG] = { - .desc = REG_SWITCH(VBUS_OTG, pwr_sw1, BST_SW_CR, - USBSW_OTG_SWITCH_ENABLED, - USBSW_OTG_SWITCH_ENABLED), + .desc = REG_VBUS_OTG(VBUS_OTG, pwr_sw1), .icc_reg = BUCKS_ICCTO_CR, .icc_mask = BIT(4), }, [STPMIC1_SW_OUT] = { - .desc = REG_SWITCH(SW_OUT, pwr_sw2, BST_SW_CR, - SWIN_SWOUT_ENABLED, - SWIN_SWOUT_ENABLED), + .desc = REG_SW_OUT(SW_OUT, pwr_sw2), .icc_reg = BUCKS_ICCTO_CR, .icc_mask = BIT(5), }, @@ -448,8 +455,9 @@ static unsigned int stpmic1_map_mode(unsigned int mode) static unsigned int stpmic1_get_mode(struct regulator_dev *rdev) { int value; + struct regmap *regmap = rdev_get_regmap(rdev); - regmap_read(rdev->regmap, rdev->desc->enable_reg, &value); + regmap_read(regmap, rdev->desc->enable_reg, &value); if (value & STPMIC1_BUCK_MODE_LP) return REGULATOR_MODE_STANDBY; @@ -460,6 +468,7 @@ static unsigned int stpmic1_get_mode(struct regulator_dev *rdev) static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode) { int value; + struct regmap *regmap = rdev_get_regmap(rdev); switch (mode) { case REGULATOR_MODE_NORMAL: @@ -472,17 +481,18 @@ static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode) return -EINVAL; } - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + return regmap_update_bits(regmap, rdev->desc->enable_reg, STPMIC1_BUCK_MODE_LP, value); } static int stpmic1_set_icc(struct regulator_dev *rdev) { - struct stpmic1_regulator *regul = rdev_get_drvdata(rdev); + struct stpmic1_regulator_cfg *cfg = rdev_get_drvdata(rdev); + struct regmap *regmap = rdev_get_regmap(rdev); /* enable switch off in case of over current */ - return regmap_update_bits(regul->regmap, regul->cfg->icc_reg, - regul->cfg->icc_mask, regul->cfg->icc_mask); + return regmap_update_bits(regmap, cfg->icc_reg, cfg->icc_mask, + cfg->icc_mask); } static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data) @@ -501,46 +511,13 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int stpmic1_regulator_init(struct platform_device *pdev, - struct regulator_dev *rdev) -{ - struct stpmic1_regulator *regul = rdev_get_drvdata(rdev); - int ret = 0; - - /* set mask reset */ - if (regul->mask_reset && regul->cfg->mask_reset_reg != 0) { - ret = regmap_update_bits(regul->regmap, - regul->cfg->mask_reset_reg, - regul->cfg->mask_reset_mask, - regul->cfg->mask_reset_mask); - if (ret) { - dev_err(&pdev->dev, "set mask reset failed\n"); - return ret; - } - } - - /* setup an irq handler for over-current detection */ - if (regul->irq_curlim > 0) { - ret = devm_request_threaded_irq(&pdev->dev, - regul->irq_curlim, NULL, - stpmic1_curlim_irq_handler, - IRQF_ONESHOT | IRQF_SHARED, - pdev->name, rdev); - if (ret) { - dev_err(&pdev->dev, "Request IRQ failed\n"); - return ret; - } - } - return 0; -} - #define MATCH(_name, _id) \ [STPMIC1_##_id] = { \ .name = #_name, \ .desc = &stpmic1_regulator_cfgs[STPMIC1_##_id].desc, \ } -static struct of_regulator_match stpmic1_regulators_matches[] = { +static struct of_regulator_match stpmic1_matches[] = { MATCH(buck1, BUCK1), MATCH(buck2, BUCK2), MATCH(buck3, BUCK3), @@ -557,94 +534,75 @@ static struct of_regulator_match stpmic1_regulators_matches[] = { MATCH(pwr_sw2, SW_OUT), }; -static int stpmic1_regulator_parse_dt(void *driver_data) -{ - struct stpmic1_regulator *regul = - (struct stpmic1_regulator *)driver_data; - - if (!regul) - return -EINVAL; - - if (of_get_property(regul->reg_node, "st,mask-reset", NULL)) - regul->mask_reset = 1; - - regul->irq_curlim = of_irq_get(regul->reg_node, 0); - - return 0; -} - -static struct -regulator_dev *stpmic1_regulator_register(struct platform_device *pdev, int id, - struct regulator_init_data *init_data, - struct stpmic1_regulator *regul) +static int stpmic1_regulator_register(struct platform_device *pdev, int id, + struct of_regulator_match *match, + const struct stpmic1_regulator_cfg *cfg) { struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent); struct regulator_dev *rdev; struct regulator_config config = {}; + int ret = 0; + int irq; config.dev = &pdev->dev; - config.init_data = init_data; - config.of_node = stpmic1_regulators_matches[id].of_node; + config.init_data = match->init_data; + config.of_node = match->of_node; config.regmap = pmic_dev->regmap; - config.driver_data = regul; - - regul->regul_id = id; - regul->reg_node = config.of_node; - regul->cfg = &stpmic1_regulator_cfgs[id]; - regul->regmap = pmic_dev->regmap; + config.driver_data = (void *)cfg; - rdev = devm_regulator_register(&pdev->dev, ®ul->cfg->desc, &config); + rdev = devm_regulator_register(&pdev->dev, &cfg->desc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s regulator\n", - regul->cfg->desc.name); + cfg->desc.name); + return PTR_ERR(rdev); + } + + /* set mask reset */ + if (of_get_property(config.of_node, "st,mask-reset", NULL) && + cfg->mask_reset_reg != 0) { + ret = regmap_update_bits(pmic_dev->regmap, + cfg->mask_reset_reg, + cfg->mask_reset_mask, + cfg->mask_reset_mask); + if (ret) { + dev_err(&pdev->dev, "set mask reset failed\n"); + return ret; + } } - return rdev; + /* setup an irq handler for over-current detection */ + irq = of_irq_get(config.of_node, 0); + if (irq > 0) { + ret = devm_request_threaded_irq(&pdev->dev, + irq, NULL, + stpmic1_curlim_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + pdev->name, rdev); + if (ret) { + dev_err(&pdev->dev, "Request IRQ failed\n"); + return ret; + } + } + return 0; } static int stpmic1_regulator_probe(struct platform_device *pdev) { - struct regulator_dev *rdev; - struct stpmic1_regulator *regul; - struct regulator_init_data *init_data; - struct device_node *np; int i, ret; - np = pdev->dev.of_node; - - ret = of_regulator_match(&pdev->dev, np, - stpmic1_regulators_matches, - ARRAY_SIZE(stpmic1_regulators_matches)); + ret = of_regulator_match(&pdev->dev, pdev->dev.of_node, stpmic1_matches, + ARRAY_SIZE(stpmic1_matches)); if (ret < 0) { dev_err(&pdev->dev, "Error in PMIC regulator device tree node"); return ret; } - regul = devm_kzalloc(&pdev->dev, ARRAY_SIZE(stpmic1_regulator_cfgs) * - sizeof(struct stpmic1_regulator), - GFP_KERNEL); - if (!regul) - return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) { - /* Parse DT & find regulators to register */ - init_data = stpmic1_regulators_matches[i].init_data; - if (init_data) - init_data->regulator_init = &stpmic1_regulator_parse_dt; - - rdev = stpmic1_regulator_register(pdev, i, init_data, regul); - if (IS_ERR(rdev)) - return PTR_ERR(rdev); - - ret = stpmic1_regulator_init(pdev, rdev); - if (ret) { - dev_err(&pdev->dev, - "failed to initialize regulator %d\n", ret); + ret = stpmic1_regulator_register(pdev, i, &stpmic1_matches[i], + &stpmic1_regulator_cfgs[i]); + if (ret < 0) return ret; - } - - regul++; } dev_dbg(&pdev->dev, "stpmic1_regulator driver probed\n"); diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c index 342f5da79975..6dc2316daad3 100644 --- a/drivers/regulator/stw481x-vmmc.c +++ b/drivers/regulator/stw481x-vmmc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for STw4810/STw4811 VMMC regulator. * @@ -5,8 +6,6 @@ * Written on behalf of Linaro for ST-Ericsson * * Author: Linus Walleij <linus.walleij@linaro.org> - * - * License terms: GNU General Public License (GPL) version 2 */ #include <linux/err.h> diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c index 65fbd1f0b612..42e03b2c10a0 100644 --- a/drivers/regulator/sy8106a-regulator.c +++ b/drivers/regulator/sy8106a-regulator.c @@ -22,12 +22,6 @@ */ #define SY8106A_GO_BIT BIT(7) -struct sy8106a { - struct regulator_dev *rdev; - struct regmap *regmap; - u32 fixed_voltage; -}; - static const struct regmap_config sy8106a_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -70,36 +64,32 @@ static const struct regulator_desc sy8106a_reg = { static int sy8106a_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct sy8106a *chip; struct device *dev = &i2c->dev; - struct regulator_dev *rdev = NULL; + struct regulator_dev *rdev; struct regulator_config config = { }; + struct regmap *regmap; unsigned int reg, vsel; + u32 fixed_voltage; int error; - chip = devm_kzalloc(&i2c->dev, sizeof(struct sy8106a), GFP_KERNEL); - if (!chip) - return -ENOMEM; - error = of_property_read_u32(dev->of_node, "silergy,fixed-microvolt", - &chip->fixed_voltage); + &fixed_voltage); if (error) return error; - if (chip->fixed_voltage < SY8106A_MIN_MV * 1000 || - chip->fixed_voltage > SY8106A_MAX_MV * 1000) + if (fixed_voltage < SY8106A_MIN_MV * 1000 || + fixed_voltage > SY8106A_MAX_MV * 1000) return -EINVAL; - chip->regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config); - if (IS_ERR(chip->regmap)) { - error = PTR_ERR(chip->regmap); + regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config); + if (IS_ERR(regmap)) { + error = PTR_ERR(regmap); dev_err(dev, "Failed to allocate register map: %d\n", error); return error; } config.dev = &i2c->dev; - config.regmap = chip->regmap; - config.driver_data = chip; + config.regmap = regmap; config.of_node = dev->of_node; config.init_data = of_get_regulator_init_data(dev, dev->of_node, @@ -109,15 +99,15 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c, return -ENOMEM; /* Ensure GO_BIT is enabled when probing */ - error = regmap_read(chip->regmap, SY8106A_REG_VOUT1_SEL, ®); + error = regmap_read(regmap, SY8106A_REG_VOUT1_SEL, ®); if (error) return error; if (!(reg & SY8106A_GO_BIT)) { - vsel = (chip->fixed_voltage / 1000 - SY8106A_MIN_MV) / + vsel = (fixed_voltage / 1000 - SY8106A_MIN_MV) / SY8106A_STEP_MV; - error = regmap_write(chip->regmap, SY8106A_REG_VOUT1_SEL, + error = regmap_write(regmap, SY8106A_REG_VOUT1_SEL, vsel | SY8106A_GO_BIT); if (error) return error; @@ -131,10 +121,6 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c, return error; } - chip->rdev = rdev; - - i2c_set_clientdata(i2c, chip); - return 0; } diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 584ef3dedca6..06059a94f7c6 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Driver for TPS61050/61052 boost converters, typically used for white LEDs * or audio amplifiers. @@ -6,8 +7,6 @@ * Written on behalf of Linaro for ST-Ericsson * * Author: Linus Walleij <linus.walleij@linaro.org> - * - * License terms: GNU General Public License (GPL) version 2 */ #include <linux/module.h> diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c179a3a221af..d2a8f69b2665 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -115,7 +115,6 @@ static struct tps_info tps6507x_pmic_regs[] = { struct tps6507x_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; struct tps6507x_dev *mfd; - struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; struct tps_info *info[TPS6507X_NUM_REGULATOR]; struct mutex io_lock; }; @@ -349,7 +348,7 @@ static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, return tps6507x_pmic_reg_write(tps, reg, data); } -static struct regulator_ops tps6507x_pmic_ops = { +static const struct regulator_ops tps6507x_pmic_ops = { .is_enabled = tps6507x_pmic_is_enabled, .enable = tps6507x_pmic_enable, .disable = tps6507x_pmic_disable, @@ -359,66 +358,20 @@ static struct regulator_ops tps6507x_pmic_ops = { .map_voltage = regulator_map_voltage_ascend, }; -static struct of_regulator_match tps6507x_matches[] = { - { .name = "VDCDC1"}, - { .name = "VDCDC2"}, - { .name = "VDCDC3"}, - { .name = "LDO1"}, - { .name = "LDO2"}, -}; - -static struct tps6507x_board *tps6507x_parse_dt_reg_data( - struct platform_device *pdev, - struct of_regulator_match **tps6507x_reg_matches) +static int tps6507x_pmic_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *config) { - struct tps6507x_board *tps_board; - struct device_node *np = pdev->dev.parent->of_node; - struct device_node *regulators; - struct of_regulator_match *matches; - struct regulator_init_data *reg_data; - int idx = 0, count, ret; - - tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), - GFP_KERNEL); - if (!tps_board) - return NULL; - - regulators = of_get_child_by_name(np, "regulators"); - if (!regulators) { - dev_err(&pdev->dev, "regulator node not found\n"); - return NULL; - } - - count = ARRAY_SIZE(tps6507x_matches); - matches = tps6507x_matches; - - ret = of_regulator_match(&pdev->dev, regulators, matches, count); - of_node_put(regulators); - if (ret < 0) { - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", - ret); - return NULL; - } + struct tps6507x_pmic *tps = config->driver_data; + struct tps_info *info = tps->info[desc->id]; + u32 prop; + int ret; - *tps6507x_reg_matches = matches; - - reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) - * TPS6507X_NUM_REGULATOR), GFP_KERNEL); - if (!reg_data) - return NULL; - - tps_board->tps6507x_pmic_init_data = reg_data; - - for (idx = 0; idx < count; idx++) { - if (!matches[idx].init_data || !matches[idx].of_node) - continue; - - memcpy(®_data[idx], matches[idx].init_data, - sizeof(struct regulator_init_data)); - - } + ret = of_property_read_u32(np, "ti,defdcdc_default", &prop); + if (!ret) + info->defdcdc_default = prop; - return tps_board; + return 0; } static int tps6507x_pmic_probe(struct platform_device *pdev) @@ -426,14 +379,11 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); struct tps_info *info = &tps6507x_pmic_regs[0]; struct regulator_config config = { }; - struct regulator_init_data *init_data; + struct regulator_init_data *init_data = NULL; struct regulator_dev *rdev; struct tps6507x_pmic *tps; struct tps6507x_board *tps_board; - struct of_regulator_match *tps6507x_reg_matches = NULL; int i; - int error; - unsigned int prop; /** * tps_board points to pmic related constants @@ -441,20 +391,8 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) */ tps_board = dev_get_platdata(tps6507x_dev->dev); - if (IS_ENABLED(CONFIG_OF) && !tps_board && - tps6507x_dev->dev->of_node) - tps_board = tps6507x_parse_dt_reg_data(pdev, - &tps6507x_reg_matches); - if (!tps_board) - return -EINVAL; - - /** - * init_data points to array of regulator_init structures - * coming from the board-evm file. - */ - init_data = tps_board->tps6507x_pmic_init_data; - if (!init_data) - return -EINVAL; + if (tps_board) + init_data = tps_board->tps6507x_pmic_init_data; tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL); if (!tps) @@ -465,16 +403,19 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) /* common for all regulators */ tps->mfd = tps6507x_dev; - for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { + for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++) { /* Register the regulators */ tps->info[i] = info; - if (init_data->driver_data) { + if (init_data && init_data[i].driver_data) { struct tps6507x_reg_platform_data *data = - init_data->driver_data; - tps->info[i]->defdcdc_default = data->defdcdc_default; + init_data[i].driver_data; + info->defdcdc_default = data->defdcdc_default; } tps->desc[i].name = info->name; + tps->desc[i].of_match = of_match_ptr(info->name); + tps->desc[i].regulators_node = of_match_ptr("regulators"); + tps->desc[i].of_parse_cb = tps6507x_pmic_of_parse_cb; tps->desc[i].id = i; tps->desc[i].n_voltages = info->table_len; tps->desc[i].volt_table = info->table; @@ -486,17 +427,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) config.init_data = init_data; config.driver_data = tps; - if (tps6507x_reg_matches) { - error = of_property_read_u32( - tps6507x_reg_matches[i].of_node, - "ti,defdcdc_default", &prop); - - if (!error) - tps->info[i]->defdcdc_default = prop; - - config.of_node = tps6507x_reg_matches[i].of_node; - } - rdev = devm_regulator_register(&pdev->dev, &tps->desc[i], &config); if (IS_ERR(rdev)) { @@ -505,9 +435,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) pdev->name); return PTR_ERR(rdev); } - - /* Save regulator for cleanup */ - tps->rdev[i] = rdev; } tps6507x_dev->pmic = tps; diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index 45e96e154690..5a5e9b5bf4be 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -90,8 +90,8 @@ static const struct regulator_linear_range tps65086_buck345_25mv_ranges[] = { static const struct regulator_linear_range tps65086_ldoa1_ranges[] = { REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000), - REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xA, 100000), - REGULATOR_LINEAR_RANGE(2700000, 0xB, 0xD, 150000), + REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xB, 100000), + REGULATOR_LINEAR_RANGE(2850000, 0xC, 0xD, 150000), REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0), }; diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 0614551796a1..ca39b3d55123 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for tps65090 power management chip. * * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/> */ #include <linux/module.h> diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c index 73978dd440f7..6e22f5ebba2e 100644 --- a/drivers/regulator/tps65132-regulator.c +++ b/drivers/regulator/tps65132-regulator.c @@ -55,10 +55,7 @@ struct tps65132_reg_pdata { struct tps65132_regulator { struct device *dev; - struct regmap *rmap; - struct regulator_desc *rdesc[TPS65132_MAX_REGULATORS]; struct tps65132_reg_pdata reg_pdata[TPS65132_MAX_REGULATORS]; - struct regulator_dev *rdev[TPS65132_MAX_REGULATORS]; }; static int tps65132_regulator_enable(struct regulator_dev *rdev) @@ -120,7 +117,7 @@ static int tps65132_regulator_is_enabled(struct regulator_dev *rdev) return 1; } -static struct regulator_ops tps65132_regulator_ops = { +static const struct regulator_ops tps65132_regulator_ops = { .enable = tps65132_regulator_enable, .disable = tps65132_regulator_disable, .is_enabled = tps65132_regulator_is_enabled, @@ -196,7 +193,7 @@ static int tps65132_of_parse_cb(struct device_node *np, .owner = THIS_MODULE, \ } -static struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = { +static const struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = { TPS65132_REGULATOR_DESC(VPOS, outp), TPS65132_REGULATOR_DESC(VNEG, outn), }; @@ -225,6 +222,8 @@ static int tps65132_probe(struct i2c_client *client, { struct device *dev = &client->dev; struct tps65132_regulator *tps; + struct regulator_dev *rdev; + struct regmap *rmap; struct regulator_config config = { }; int id; int ret; @@ -233,9 +232,9 @@ static int tps65132_probe(struct i2c_client *client, if (!tps) return -ENOMEM; - tps->rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config); - if (IS_ERR(tps->rmap)) { - ret = PTR_ERR(tps->rmap); + rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config); + if (IS_ERR(rmap)) { + ret = PTR_ERR(rmap); dev_err(dev, "regmap init failed: %d\n", ret); return ret; } @@ -244,18 +243,16 @@ static int tps65132_probe(struct i2c_client *client, tps->dev = dev; for (id = 0; id < TPS65132_MAX_REGULATORS; ++id) { - tps->rdesc[id] = &tps_regs_desc[id]; - - config.regmap = tps->rmap; + config.regmap = rmap; config.dev = dev; config.driver_data = tps; - tps->rdev[id] = devm_regulator_register(dev, - tps->rdesc[id], &config); - if (IS_ERR(tps->rdev[id])) { - ret = PTR_ERR(tps->rdev[id]); + rdev = devm_regulator_register(dev, &tps_regs_desc[id], + &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); dev_err(dev, "regulator %s register failed: %d\n", - tps->rdesc[id]->name, ret); + tps_regs_desc[id].name, ret); return ret; } } diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index d84fab616abf..67ba78da77ec 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -58,10 +58,9 @@ static const unsigned int LDO1_VSEL_table[] = { static const struct regulator_linear_range tps65217_uv1_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 24, 25000), - REGULATOR_LINEAR_RANGE(1550000, 25, 30, 50000), - REGULATOR_LINEAR_RANGE(1850000, 31, 52, 50000), + REGULATOR_LINEAR_RANGE(1550000, 25, 52, 50000), REGULATOR_LINEAR_RANGE(3000000, 53, 55, 100000), - REGULATOR_LINEAR_RANGE(3300000, 56, 62, 0), + REGULATOR_LINEAR_RANGE(3300000, 56, 63, 0), }; static const struct regulator_linear_range tps65217_uv2_ranges[] = { @@ -150,7 +149,7 @@ static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev) } /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ -static struct regulator_ops tps65217_pmic_ops = { +static const struct regulator_ops tps65217_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, @@ -163,7 +162,7 @@ static struct regulator_ops tps65217_pmic_ops = { }; /* Operations permitted on LDO1 */ -static struct regulator_ops tps65217_pmic_ldo1_ops = { +static const struct regulator_ops tps65217_pmic_ldo1_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 6209beee1018..b72035610013 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -29,7 +29,8 @@ #include <linux/mfd/tps65218.h> #define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \ - _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \ + _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm, \ + _ct, _ncl) \ { \ .name = _name, \ .of_match = _of, \ @@ -42,6 +43,8 @@ .vsel_mask = _vm, \ .csel_reg = _cr, \ .csel_mask = _cm, \ + .curr_table = _ct, \ + .n_current_limits = _ncl, \ .enable_reg = _er, \ .enable_mask = _em, \ .volt_table = NULL, \ @@ -162,7 +165,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) } /* Operations permitted on DCDC1, DCDC2 */ -static struct regulator_ops tps65218_dcdc12_ops = { +static const struct regulator_ops tps65218_dcdc12_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, @@ -176,7 +179,7 @@ static struct regulator_ops tps65218_dcdc12_ops = { }; /* Operations permitted on DCDC3, DCDC4 and LDO1 */ -static struct regulator_ops tps65218_ldo1_dcdc34_ops = { +static const struct regulator_ops tps65218_ldo1_dcdc34_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, @@ -188,7 +191,7 @@ static struct regulator_ops tps65218_ldo1_dcdc34_ops = { .set_suspend_disable = tps65218_pmic_set_suspend_disable, }; -static const int ls3_currents[] = { 100, 200, 500, 1000 }; +static const unsigned int ls3_currents[] = { 100000, 200000, 500000, 1000000 }; static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, int lim_uA) @@ -204,7 +207,8 @@ static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, return -EINVAL; return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, - index << 2, TPS65218_PROTECT_L1); + index << __builtin_ctz(dev->desc->csel_mask), + TPS65218_PROTECT_L1); } static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, @@ -214,7 +218,7 @@ static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, unsigned int num_currents = ARRAY_SIZE(ls3_currents); struct tps65218 *tps = rdev_get_drvdata(dev); - while (index < num_currents && ls3_currents[index] < max_uA) + while (index < num_currents && ls3_currents[index] <= max_uA) index++; index--; @@ -223,35 +227,21 @@ static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, return -EINVAL; return tps65218_set_bits(tps, dev->desc->csel_reg, dev->desc->csel_mask, - index << 2, TPS65218_PROTECT_L1); -} - -static int tps65218_pmic_get_current_limit(struct regulator_dev *dev) -{ - int retval; - unsigned int index; - struct tps65218 *tps = rdev_get_drvdata(dev); - - retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index); - if (retval < 0) - return retval; - - index = (index & dev->desc->csel_mask) >> 2; - - return ls3_currents[index]; + index << __builtin_ctz(dev->desc->csel_mask), + TPS65218_PROTECT_L1); } -static struct regulator_ops tps65218_ls3_ops = { +static const struct regulator_ops tps65218_ls23_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, .set_input_current_limit = tps65218_pmic_set_input_current_lim, .set_current_limit = tps65218_pmic_set_current_limit, - .get_current_limit = tps65218_pmic_get_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, }; /* Operations permitted on DCDC5, DCDC6 */ -static struct regulator_ops tps65218_dcdc56_pmic_ops = { +static const struct regulator_ops tps65218_dcdc56_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, @@ -266,48 +256,57 @@ static const struct regulator_desc regulators[] = { TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, 2, 4000, 0, TPS65218_REG_SEQ3, - TPS65218_SEQ3_DC1_SEQ_MASK), + TPS65218_SEQ3_DC1_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2, REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, 2, 4000, 0, TPS65218_REG_SEQ3, - TPS65218_SEQ3_DC2_SEQ_MASK), + TPS65218_SEQ3_DC2_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, - 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK), + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK, + NULL, 0), TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, - 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK), + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK, + NULL, 0), TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5, REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5, - TPS65218_SEQ5_DC5_SEQ_MASK), + TPS65218_SEQ5_DC5_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6, REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5, - TPS65218_SEQ5_DC6_SEQ_MASK), + TPS65218_SEQ5_DC6_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, 2, 0, 0, TPS65218_REG_SEQ6, - TPS65218_SEQ6_LDO1_SEQ_MASK), + TPS65218_SEQ6_LDO1_SEQ_MASK, NULL, 0), + TPS65218_REGULATOR("LS2", "regulator-ls2", TPS65218_LS_2, + REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, + TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS2_EN, + TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS2ILIM_MASK, + NULL, 0, 0, 0, 0, 0, ls3_currents, + ARRAY_SIZE(ls3_currents)), TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3, - REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0, + REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK, - NULL, 0, 0, 0, 0, 0), + NULL, 0, 0, 0, 0, 0, ls3_currents, + ARRAY_SIZE(ls3_currents)), }; static int tps65218_regulator_probe(struct platform_device *pdev) diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 67cac2682f50..740aeccdfb1f 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -137,7 +137,6 @@ struct tps6524x { struct spi_device *spi; struct mutex lock; struct regulator_desc desc[N_REGULATORS]; - struct regulator_dev *rdev[N_REGULATORS]; }; static int __read_reg(struct tps6524x *hw, int reg) @@ -565,7 +564,7 @@ static int is_supply_enabled(struct regulator_dev *rdev) return read_field(hw, &info->enable); } -static struct regulator_ops regulator_ops = { +static const struct regulator_ops regulator_ops = { .is_enabled = is_supply_enabled, .enable = enable_supply, .disable = disable_supply, @@ -584,6 +583,7 @@ static int pmic_probe(struct spi_device *spi) const struct supply_info *info = supply_info; struct regulator_init_data *init_data; struct regulator_config config = { }; + struct regulator_dev *rdev; int i; init_data = dev_get_platdata(dev); @@ -616,10 +616,9 @@ static int pmic_probe(struct spi_device *spi) config.init_data = init_data; config.driver_data = hw; - hw->rdev[i] = devm_regulator_register(dev, &hw->desc[i], - &config); - if (IS_ERR(hw->rdev[i])) - return PTR_ERR(hw->rdev[i]); + rdev = devm_regulator_register(dev, &hw->desc[i], &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); } return 0; diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index ba3dae7b2d2d..09e994e1f9a9 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Regulator driver for TI TPS6586x * @@ -7,10 +8,6 @@ * Based on da903x * Copyright (C) 2006-2008 Marvell International Ltd. * Copyright (C) 2008 Compulab Ltd. - * - * 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/kernel.h> diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 5ebb6ee73f07..4eb5b19d2344 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * tps65910.c -- TI tps65910 * @@ -5,12 +6,6 @@ * * Author: Graeme Gregory <gg@slimlogic.co.uk> * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/kernel.h> diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index 1001147404c3..85a6a8ca8c1b 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -1,27 +1,13 @@ -/* - * tps80031-regulator.c -- TI TPS80031 regulator driver. - * - * Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power - * Management with Power Path and Battery Charger. - * - * Copyright (c) 2012, NVIDIA Corporation. - * - * Author: Laxman Dewangan <ldewangan@nvidia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, - * whether express or implied; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ +// SPDX-License-Identifier: GPL-2.0 +// +// tps80031-regulator.c -- TI TPS80031 regulator driver. +// +// Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power +// Management with Power Path and Battery Charger. +// +// Copyright (c) 2012, NVIDIA Corporation. +// +// Author: Laxman Dewangan <ldewangan@nvidia.com> #include <linux/delay.h> #include <linux/err.h> @@ -85,7 +71,6 @@ struct tps80031_regulator_info { struct tps80031_regulator { struct device *dev; - struct regulator_dev *rdev; struct tps80031_regulator_info *rinfo; u8 device_flags; @@ -155,7 +140,7 @@ static int tps80031_reg_disable(struct regulator_dev *rdev) } /* DCDC voltages for the selector of 58 to 63 */ -static int tps80031_dcdc_voltages[4][5] = { +static const int tps80031_dcdc_voltages[4][5] = { { 1350, 1500, 1800, 1900, 2100}, { 1350, 1500, 1800, 1900, 2100}, { 2084, 2315, 2778, 2932, 3241}, @@ -378,7 +363,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev) return ret; } -static struct regulator_ops tps80031_dcdc_ops = { +static const struct regulator_ops tps80031_dcdc_ops = { .list_voltage = tps80031_dcdc_list_voltage, .set_voltage_sel = tps80031_dcdc_set_voltage_sel, .get_voltage_sel = tps80031_dcdc_get_voltage_sel, @@ -387,7 +372,7 @@ static struct regulator_ops tps80031_dcdc_ops = { .is_enabled = tps80031_reg_is_enabled, }; -static struct regulator_ops tps80031_ldo_ops = { +static const struct regulator_ops tps80031_ldo_ops = { .list_voltage = tps80031_ldo_list_voltage, .map_voltage = tps80031_ldo_map_voltage, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -397,18 +382,18 @@ static struct regulator_ops tps80031_ldo_ops = { .is_enabled = tps80031_reg_is_enabled, }; -static struct regulator_ops tps80031_vbus_sw_ops = { +static const struct regulator_ops tps80031_vbus_sw_ops = { .list_voltage = regulator_list_voltage_linear, .enable = tps80031_vbus_enable, .disable = tps80031_vbus_disable, .is_enabled = tps80031_vbus_is_enabled, }; -static struct regulator_ops tps80031_vbus_hw_ops = { +static const struct regulator_ops tps80031_vbus_hw_ops = { .list_voltage = regulator_list_voltage_linear, }; -static struct regulator_ops tps80031_ext_reg_ops = { +static const struct regulator_ops tps80031_ext_reg_ops = { .list_voltage = regulator_list_voltage_linear, .enable = tps80031_reg_enable, .disable = tps80031_reg_disable, @@ -736,7 +721,6 @@ static int tps80031_regulator_probe(struct platform_device *pdev) ri->rinfo->desc.name); return PTR_ERR(rdev); } - ri->rdev = rdev; } platform_set_drvdata(pdev, pmic); diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 884c7505ed91..6fa15b2d6fb3 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * twl-regulator.c -- support regulators in twl4030/twl6030 family chips * * Copyright (C) 2008 David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/module.h> @@ -392,7 +388,7 @@ static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev) return vsel; } -static struct regulator_ops twl4030ldo_ops = { +static const struct regulator_ops twl4030ldo_ops = { .list_voltage = twl4030ldo_list_voltage, .set_voltage_sel = twl4030ldo_set_voltage_sel, @@ -430,14 +426,14 @@ static int twl4030smps_get_voltage(struct regulator_dev *rdev) return vsel * 12500 + 600000; } -static struct regulator_ops twl4030smps_ops = { +static const struct regulator_ops twl4030smps_ops = { .set_voltage = twl4030smps_set_voltage, .get_voltage = twl4030smps_get_voltage, }; /*----------------------------------------------------------------------*/ -static struct regulator_ops twl4030fixed_ops = { +static const struct regulator_ops twl4030fixed_ops = { .list_voltage = regulator_list_voltage_linear, .enable = twl4030reg_enable, @@ -576,14 +572,9 @@ static int twlreg_probe(struct platform_device *pdev) struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; - const struct of_device_id *match; struct regulator_config config = { }; - match = of_match_device(twl_of_match, &pdev->dev); - if (!match) - return -ENODEV; - - template = match->data; + template = of_device_get_match_data(&pdev->dev); if (!template) return -ENODEV; diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c index 219cbd910dbf..5fe208b381eb 100644 --- a/drivers/regulator/twl6030-regulator.c +++ b/drivers/regulator/twl6030-regulator.c @@ -1,13 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Split TWL6030 logic from twl-regulator.c: * Copyright (C) 2008 David Brownell * * Copyright (C) 2016 Nicolae Rosia <nicolae.rosia@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/module.h> @@ -31,9 +27,6 @@ struct twlreg_info { /* twl resource ID, for resource control state machine */ u8 id; - /* chip constraints on regulator behavior */ - u16 min_mV; - u8 flags; /* used by regulator core */ @@ -247,32 +240,11 @@ static int twl6030coresmps_get_voltage(struct regulator_dev *rdev) return -ENODEV; } -static struct regulator_ops twl6030coresmps_ops = { +static const struct regulator_ops twl6030coresmps_ops = { .set_voltage = twl6030coresmps_set_voltage, .get_voltage = twl6030coresmps_get_voltage, }; -static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned sel) -{ - struct twlreg_info *info = rdev_get_drvdata(rdev); - - switch (sel) { - case 0: - return 0; - case 1 ... 24: - /* Linear mapping from 00000001 to 00011000: - * Absolute voltage value = 1.0 V + 0.1 V × (sel – 00000001) - */ - return (info->min_mV + 100 * (sel - 1)) * 1000; - case 25 ... 30: - return -EINVAL; - case 31: - return 2750000; - default: - return -EINVAL; - } -} - static int twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { @@ -290,8 +262,8 @@ static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev) return vsel; } -static struct regulator_ops twl6030ldo_ops = { - .list_voltage = twl6030ldo_list_voltage, +static const struct regulator_ops twl6030ldo_ops = { + .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = twl6030ldo_set_voltage_sel, .get_voltage_sel = twl6030ldo_get_voltage_sel, @@ -305,7 +277,7 @@ static struct regulator_ops twl6030ldo_ops = { .get_status = twl6030reg_get_status, }; -static struct regulator_ops twl6030fixed_ops = { +static const struct regulator_ops twl6030fixed_ops = { .list_voltage = regulator_list_voltage_linear, .enable = twl6030reg_enable, @@ -496,7 +468,7 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev) return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS); } -static struct regulator_ops twlsmps_ops = { +static const struct regulator_ops twlsmps_ops = { .list_voltage = twl6030smps_list_voltage, .map_voltage = twl6030smps_map_voltage, @@ -513,6 +485,11 @@ static struct regulator_ops twlsmps_ops = { }; /*----------------------------------------------------------------------*/ +static const struct regulator_linear_range twl6030ldo_linear_range[] = { + REGULATOR_LINEAR_RANGE(0, 0, 0, 0), + REGULATOR_LINEAR_RANGE(1000000, 1, 24, 100000), + REGULATOR_LINEAR_RANGE(2750000, 31, 31, 0), +}; #define TWL6030_ADJUSTABLE_SMPS(label) \ static const struct twlreg_info TWL6030_INFO_##label = { \ @@ -525,28 +502,30 @@ static const struct twlreg_info TWL6030_INFO_##label = { \ }, \ } -#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts) \ +#define TWL6030_ADJUSTABLE_LDO(label, offset) \ static const struct twlreg_info TWL6030_INFO_##label = { \ .base = offset, \ - .min_mV = min_mVolts, \ .desc = { \ .name = #label, \ .id = TWL6030_REG_##label, \ .n_voltages = 32, \ + .linear_ranges = twl6030ldo_linear_range, \ + .n_linear_ranges = ARRAY_SIZE(twl6030ldo_linear_range), \ .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ } -#define TWL6032_ADJUSTABLE_LDO(label, offset, min_mVolts) \ +#define TWL6032_ADJUSTABLE_LDO(label, offset) \ static const struct twlreg_info TWL6032_INFO_##label = { \ .base = offset, \ - .min_mV = min_mVolts, \ .desc = { \ .name = #label, \ .id = TWL6032_REG_##label, \ .n_voltages = 32, \ + .linear_ranges = twl6030ldo_linear_range, \ + .n_linear_ranges = ARRAY_SIZE(twl6030ldo_linear_range), \ .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ @@ -557,7 +536,6 @@ static const struct twlreg_info TWL6032_INFO_##label = { \ static const struct twlreg_info TWLFIXED_INFO_##label = { \ .base = offset, \ .id = 0, \ - .min_mV = mVolts, \ .desc = { \ .name = #label, \ .id = TWL6030##_REG_##label, \ @@ -574,7 +552,6 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \ static const struct twlreg_info TWLSMPS_INFO_##label = { \ .base = offset, \ - .min_mV = 600, \ .desc = { \ .name = #label, \ .id = TWL6032_REG_##label, \ @@ -592,22 +569,22 @@ static const struct twlreg_info TWLSMPS_INFO_##label = { \ TWL6030_ADJUSTABLE_SMPS(VDD1); TWL6030_ADJUSTABLE_SMPS(VDD2); TWL6030_ADJUSTABLE_SMPS(VDD3); -TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000); -TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000); -TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000); -TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000); -TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000); -TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000); +TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54); +TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58); +TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c); +TWL6030_ADJUSTABLE_LDO(VMMC, 0x68); +TWL6030_ADJUSTABLE_LDO(VPP, 0x6c); +TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74); /* 6025 are renamed compared to 6030 versions */ -TWL6032_ADJUSTABLE_LDO(LDO2, 0x54, 1000); -TWL6032_ADJUSTABLE_LDO(LDO4, 0x58, 1000); -TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c, 1000); -TWL6032_ADJUSTABLE_LDO(LDO5, 0x68, 1000); -TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c, 1000); -TWL6032_ADJUSTABLE_LDO(LDO7, 0x74, 1000); -TWL6032_ADJUSTABLE_LDO(LDO6, 0x60, 1000); -TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64, 1000); -TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000); +TWL6032_ADJUSTABLE_LDO(LDO2, 0x54); +TWL6032_ADJUSTABLE_LDO(LDO4, 0x58); +TWL6032_ADJUSTABLE_LDO(LDO3, 0x5c); +TWL6032_ADJUSTABLE_LDO(LDO5, 0x68); +TWL6032_ADJUSTABLE_LDO(LDO1, 0x6c); +TWL6032_ADJUSTABLE_LDO(LDO7, 0x74); +TWL6032_ADJUSTABLE_LDO(LDO6, 0x60); +TWL6032_ADJUSTABLE_LDO(LDOLN, 0x64); +TWL6032_ADJUSTABLE_LDO(LDOUSB, 0x70); TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0); TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0); TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); @@ -687,14 +664,9 @@ static int twlreg_probe(struct platform_device *pdev) struct regulator_init_data *initdata; struct regulation_constraints *c; struct regulator_dev *rdev; - const struct of_device_id *match; struct regulator_config config = { }; - match = of_match_device(twl_of_match, &pdev->dev); - if (!match) - return -ENODEV; - - template = match->data; + template = of_device_get_match_data(&pdev->dev); if (!template) return -ENODEV; diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c index abf22acbd13e..9026d5a3e964 100644 --- a/drivers/regulator/uniphier-regulator.c +++ b/drivers/regulator/uniphier-regulator.c @@ -32,7 +32,7 @@ struct uniphier_regulator_priv { const struct uniphier_regulator_soc_data *data; }; -static struct regulator_ops uniphier_regulator_ops = { +static const struct regulator_ops uniphier_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -87,8 +87,10 @@ static int uniphier_regulator_probe(struct platform_device *pdev) } regmap = devm_regmap_init_mmio(dev, base, priv->data->regconf); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto out_rst_assert; + } config.dev = dev; config.driver_data = priv; diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c index 765acc11c9c8..8e3b5a67cfd8 100644 --- a/drivers/regulator/userspace-consumer.c +++ b/drivers/regulator/userspace-consumer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * userspace-consumer.c * @@ -8,12 +9,6 @@ * Based of virtual consumer driver: * Copyright 2008 Wolfson Microelectronics PLC. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * */ #include <linux/err.h> diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c index 78de002037c7..9a9ee8188109 100644 --- a/drivers/regulator/vctrl-regulator.c +++ b/drivers/regulator/vctrl-regulator.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Driver for voltage controller regulators * * Copyright (C) 2017 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/delay.h> @@ -334,10 +326,8 @@ static int vctrl_init_vtable(struct platform_device *pdev) ctrl_uV = regulator_list_voltage(ctrl_reg, i); if (ctrl_uV < vrange_ctrl->min_uV || - ctrl_uV > vrange_ctrl->max_uV) { + ctrl_uV > vrange_ctrl->max_uV) rdesc->n_voltages--; - continue; - } } if (rdesc->n_voltages == 0) { diff --git a/drivers/regulator/vexpress-regulator.c b/drivers/regulator/vexpress-regulator.c index c810cbbd463f..1235f46e633e 100644 --- a/drivers/regulator/vexpress-regulator.c +++ b/drivers/regulator/vexpress-regulator.c @@ -1,15 +1,6 @@ -/* - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Copyright (C) 2012 ARM Limited - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2012 ARM Limited #define DRVNAME "vexpress-regulator" #define pr_fmt(fmt) DRVNAME ": " fmt @@ -23,17 +14,10 @@ #include <linux/regulator/of_regulator.h> #include <linux/vexpress.h> -struct vexpress_regulator { - struct regulator_desc desc; - struct regulator_dev *regdev; - struct regmap *regmap; -}; - static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) { - struct vexpress_regulator *reg = rdev_get_drvdata(regdev); - u32 uV; - int err = regmap_read(reg->regmap, 0, &uV); + unsigned int uV; + int err = regmap_read(regdev->regmap, 0, &uV); return err ? err : uV; } @@ -41,60 +25,58 @@ static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) static int vexpress_regulator_set_voltage(struct regulator_dev *regdev, int min_uV, int max_uV, unsigned *selector) { - struct vexpress_regulator *reg = rdev_get_drvdata(regdev); - - return regmap_write(reg->regmap, 0, min_uV); + return regmap_write(regdev->regmap, 0, min_uV); } -static struct regulator_ops vexpress_regulator_ops_ro = { +static const struct regulator_ops vexpress_regulator_ops_ro = { .get_voltage = vexpress_regulator_get_voltage, }; -static struct regulator_ops vexpress_regulator_ops = { +static const struct regulator_ops vexpress_regulator_ops = { .get_voltage = vexpress_regulator_get_voltage, .set_voltage = vexpress_regulator_set_voltage, }; static int vexpress_regulator_probe(struct platform_device *pdev) { - struct vexpress_regulator *reg; + struct regulator_desc *desc; struct regulator_init_data *init_data; struct regulator_config config = { }; + struct regulator_dev *rdev; + struct regmap *regmap; - reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); - if (!reg) + desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL); + if (!desc) return -ENOMEM; - reg->regmap = devm_regmap_init_vexpress_config(&pdev->dev); - if (IS_ERR(reg->regmap)) - return PTR_ERR(reg->regmap); + regmap = devm_regmap_init_vexpress_config(&pdev->dev); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); - reg->desc.name = dev_name(&pdev->dev); - reg->desc.type = REGULATOR_VOLTAGE; - reg->desc.owner = THIS_MODULE; - reg->desc.continuous_voltage_range = true; + desc->name = dev_name(&pdev->dev); + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; + desc->continuous_voltage_range = true; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, - ®->desc); + desc); if (!init_data) return -EINVAL; init_data->constraints.apply_uV = 0; if (init_data->constraints.min_uV && init_data->constraints.max_uV) - reg->desc.ops = &vexpress_regulator_ops; + desc->ops = &vexpress_regulator_ops; else - reg->desc.ops = &vexpress_regulator_ops_ro; + desc->ops = &vexpress_regulator_ops_ro; + config.regmap = regmap; config.dev = &pdev->dev; config.init_data = init_data; - config.driver_data = reg; config.of_node = pdev->dev.of_node; - reg->regdev = devm_regulator_register(&pdev->dev, ®->desc, &config); - if (IS_ERR(reg->regdev)) - return PTR_ERR(reg->regdev); - - platform_set_drvdata(pdev, reg); + rdev = devm_regulator_register(&pdev->dev, desc, &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); return 0; } diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index a6f1c7a9914f..52c5a0e0acd8 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * reg-virtual-consumer.c * * Copyright 2008 Wolfson Microelectronics PLC. * * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. */ #include <linux/err.h> diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 5a5bc4bb08d2..b422eef97b77 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -1,15 +1,10 @@ -/* - * wm831x-dcdc.c -- DC-DC buck convertor driver for the WM831x series - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm831x-dcdc.c -- DC-DC buck converter driver for the WM831x series +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -183,9 +178,11 @@ static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data) { struct wm831x_dcdc *dcdc = data; + regulator_lock(dcdc->regulator); regulator_notifier_call_chain(dcdc->regulator, REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(dcdc->regulator); return IRQ_HANDLED; } @@ -194,9 +191,11 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data) { struct wm831x_dcdc *dcdc = data; + regulator_lock(dcdc->regulator); regulator_notifier_call_chain(dcdc->regulator, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(dcdc->regulator); return IRQ_HANDLED; } @@ -205,33 +204,10 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data) * BUCKV specifics */ -static int wm831x_buckv_list_voltage(struct regulator_dev *rdev, - unsigned selector) -{ - if (selector <= 0x8) - return 600000; - if (selector <= WM831X_BUCKV_MAX_SELECTOR) - return 600000 + ((selector - 0x8) * 12500); - return -EINVAL; -} - -static int wm831x_buckv_map_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - u16 vsel; - - if (min_uV < 600000) - vsel = 0; - else if (min_uV <= 1800000) - vsel = DIV_ROUND_UP(min_uV - 600000, 12500) + 8; - else - return -EINVAL; - - if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV) - return -EINVAL; - - return vsel; -} +static const struct regulator_linear_range wm831x_buckv_ranges[] = { + REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0), + REGULATOR_LINEAR_RANGE(600000, 0x8, 0x68, 12500), +}; static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) { @@ -309,7 +285,7 @@ static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; int vsel; - vsel = wm831x_buckv_map_voltage(rdev, uV, uV); + vsel = regulator_map_voltage_linear_range(rdev, uV, uV); if (vsel < 0) return vsel; @@ -327,52 +303,18 @@ static int wm831x_buckv_get_voltage_sel(struct regulator_dev *rdev) } /* Current limit options */ -static u16 wm831x_dcdc_ilim[] = { - 125, 250, 375, 500, 625, 750, 875, 1000 +static const unsigned int wm831x_dcdc_ilim[] = { + 125000, 250000, 375000, 500000, 625000, 750000, 875000, 1000000 }; -static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; - u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2; - int i; - - for (i = ARRAY_SIZE(wm831x_dcdc_ilim) - 1; i >= 0; i--) { - if ((min_uA <= wm831x_dcdc_ilim[i]) && - (wm831x_dcdc_ilim[i] <= max_uA)) - return wm831x_set_bits(wm831x, reg, - WM831X_DC1_HC_THR_MASK, - i << WM831X_DC1_HC_THR_SHIFT); - } - - return -EINVAL; -} - -static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) -{ - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; - u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2; - int val; - - val = wm831x_reg_read(wm831x, reg); - if (val < 0) - return val; - - val = (val & WM831X_DC1_HC_THR_MASK) >> WM831X_DC1_HC_THR_SHIFT; - return wm831x_dcdc_ilim[val]; -} - static const struct regulator_ops wm831x_buckv_ops = { .set_voltage_sel = wm831x_buckv_set_voltage_sel, .get_voltage_sel = wm831x_buckv_get_voltage_sel, - .list_voltage = wm831x_buckv_list_voltage, - .map_voltage = wm831x_buckv_map_voltage, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, .set_suspend_voltage = wm831x_buckv_set_suspend_voltage, - .set_current_limit = wm831x_buckv_set_current_limit, - .get_current_limit = wm831x_buckv_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, @@ -492,10 +434,16 @@ static int wm831x_buckv_probe(struct platform_device *pdev) dcdc->desc.id = id; dcdc->desc.type = REGULATOR_VOLTAGE; dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1; + dcdc->desc.linear_ranges = wm831x_buckv_ranges; + dcdc->desc.n_linear_ranges = ARRAY_SIZE(wm831x_buckv_ranges); dcdc->desc.ops = &wm831x_buckv_ops; dcdc->desc.owner = THIS_MODULE; dcdc->desc.enable_reg = WM831X_DCDC_ENABLE; dcdc->desc.enable_mask = 1 << id; + dcdc->desc.csel_reg = dcdc->base + WM831X_DCDC_CONTROL_2; + dcdc->desc.csel_mask = WM831X_DC1_HC_THR_MASK; + dcdc->desc.n_current_limits = ARRAY_SIZE(wm831x_dcdc_ilim); + dcdc->desc.curr_table = wm831x_dcdc_ilim; ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); if (ret < 0) { diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 6dd891d7eee3..ff3d2bf50410 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -1,15 +1,10 @@ -/* - * wm831x-isink.c -- Current sink driver for the WM831x series - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm831x-isink.c -- Current sink driver for the WM831x series +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -92,57 +87,23 @@ static int wm831x_isink_is_enabled(struct regulator_dev *rdev) return 0; } -static int wm831x_isink_set_current(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct wm831x_isink *isink = rdev_get_drvdata(rdev); - struct wm831x *wm831x = isink->wm831x; - int ret, i; - - for (i = 0; i < ARRAY_SIZE(wm831x_isinkv_values); i++) { - int val = wm831x_isinkv_values[i]; - if (min_uA <= val && val <= max_uA) { - ret = wm831x_set_bits(wm831x, isink->reg, - WM831X_CS1_ISEL_MASK, i); - return ret; - } - } - - return -EINVAL; -} - -static int wm831x_isink_get_current(struct regulator_dev *rdev) -{ - struct wm831x_isink *isink = rdev_get_drvdata(rdev); - struct wm831x *wm831x = isink->wm831x; - int ret; - - ret = wm831x_reg_read(wm831x, isink->reg); - if (ret < 0) - return ret; - - ret &= WM831X_CS1_ISEL_MASK; - if (ret > WM831X_ISINK_MAX_ISEL) - ret = WM831X_ISINK_MAX_ISEL; - - return wm831x_isinkv_values[ret]; -} - static const struct regulator_ops wm831x_isink_ops = { .is_enabled = wm831x_isink_is_enabled, .enable = wm831x_isink_enable, .disable = wm831x_isink_disable, - .set_current_limit = wm831x_isink_set_current, - .get_current_limit = wm831x_isink_get_current, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static irqreturn_t wm831x_isink_irq(int irq, void *data) { struct wm831x_isink *isink = data; + regulator_lock(isink->regulator); regulator_notifier_call_chain(isink->regulator, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(isink->regulator); return IRQ_HANDLED; } @@ -187,10 +148,15 @@ static int wm831x_isink_probe(struct platform_device *pdev) isink->desc.ops = &wm831x_isink_ops; isink->desc.type = REGULATOR_CURRENT; isink->desc.owner = THIS_MODULE; + isink->desc.curr_table = wm831x_isinkv_values, + isink->desc.n_current_limits = ARRAY_SIZE(wm831x_isinkv_values), + isink->desc.csel_reg = isink->reg, + isink->desc.csel_mask = WM831X_CS1_ISEL_MASK, config.dev = pdev->dev.parent; config.init_data = pdata->isink[id]; config.driver_data = isink; + config.regmap = wm831x->regmap; isink->regulator = devm_regulator_register(&pdev->dev, &isink->desc, &config); diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index e4a6f888484e..56754686c982 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -1,15 +1,10 @@ -/* - * wm831x-ldo.c -- LDO driver for the WM831x series - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm831x-ldo.c -- LDO driver for the WM831x series +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -51,9 +46,11 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data) { struct wm831x_ldo *ldo = data; + regulator_lock(ldo->regulator); regulator_notifier_call_chain(ldo->regulator, REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(ldo->regulator); return IRQ_HANDLED; } diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index a1c7dfee5c37..56d6168a888d 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1,16 +1,11 @@ -/* - * wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC +// +// Copyright 2007, 2008 Wolfson Microelectronics PLC. +// +// Author: Liam Girdwood +// linux@wolfsonmicro.com #include <linux/module.h> #include <linux/moduleparam.h> @@ -28,7 +23,7 @@ #define WM8350_DCDC_MAX_VSEL 0x66 /* Microamps */ -static const int isink_cur[] = { +static const unsigned int isink_cur[] = { 4, 5, 6, @@ -95,73 +90,6 @@ static const int isink_cur[] = { 223191 }; -static int get_isink_val(int min_uA, int max_uA, u16 *setting) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(isink_cur); i++) { - if (min_uA <= isink_cur[i] && max_uA >= isink_cur[i]) { - *setting = i; - return 0; - } - } - return -EINVAL; -} - -static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA, - int max_uA) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - u16 val, setting; - int ret; - - ret = get_isink_val(min_uA, max_uA, &setting); - if (ret != 0) - return ret; - - switch (isink) { - case WM8350_ISINK_A: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - ~WM8350_CS1_ISEL_MASK; - wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_A, - val | setting); - break; - case WM8350_ISINK_B: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - ~WM8350_CS1_ISEL_MASK; - wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_B, - val | setting); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int wm8350_isink_get_current(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - u16 val; - - switch (isink) { - case WM8350_ISINK_A: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - WM8350_CS1_ISEL_MASK; - break; - case WM8350_ISINK_B: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - WM8350_CS1_ISEL_MASK; - break; - default: - return 0; - } - - return isink_cur[val]; -} - /* turn on ISINK followed by DCDC */ static int wm8350_isink_enable(struct regulator_dev *rdev) { @@ -982,8 +910,8 @@ static const struct regulator_ops wm8350_ldo_ops = { }; static const struct regulator_ops wm8350_isink_ops = { - .set_current_limit = wm8350_isink_set_current, - .get_current_limit = wm8350_isink_get_current, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .enable = wm8350_isink_enable, .disable = wm8350_isink_disable, .is_enabled = wm8350_isink_is_enabled, @@ -1138,6 +1066,10 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_CS1, .type = REGULATOR_CURRENT, .owner = THIS_MODULE, + .curr_table = isink_cur, + .n_current_limits = ARRAY_SIZE(isink_cur), + .csel_reg = WM8350_CURRENT_SINK_DRIVER_A, + .csel_mask = WM8350_CS1_ISEL_MASK, }, { .name = "ISINKB", @@ -1146,6 +1078,10 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_CS2, .type = REGULATOR_CURRENT, .owner = THIS_MODULE, + .curr_table = isink_cur, + .n_current_limits = ARRAY_SIZE(isink_cur), + .csel_reg = WM8350_CURRENT_SINK_DRIVER_B, + .csel_mask = WM8350_CS2_ISEL_MASK, }, }; diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index fb1837657b64..6f331b51e479 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -1,16 +1,10 @@ -/* - * Regulator support for WM8400 - * - * Copyright 2008 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator support for WM8400 +// +// Copyright 2008 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/bug.h> #include <linux/err.h> @@ -36,13 +30,12 @@ static const struct regulator_ops wm8400_ldo_ops = { static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) { - struct wm8400 *wm8400 = rdev_get_drvdata(dev); + struct regmap *rmap = rdev_get_regmap(dev); int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; u16 data[2]; int ret; - ret = wm8400_block_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 2, - data); + ret = regmap_bulk_read(rmap, WM8400_DCDC1_CONTROL_1 + offset, data, 2); if (ret != 0) return 0; @@ -63,36 +56,36 @@ static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode) { - struct wm8400 *wm8400 = rdev_get_drvdata(dev); + struct regmap *rmap = rdev_get_regmap(dev); int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; int ret; switch (mode) { case REGULATOR_MODE_FAST: /* Datasheet: active with force PWM */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, + ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset, WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM); if (ret != 0) return ret; - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset, WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, WM8400_DC1_ACTIVE); case REGULATOR_MODE_NORMAL: /* Datasheet: active */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, + ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset, WM8400_DC1_FRC_PWM, 0); if (ret != 0) return ret; - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset, WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, WM8400_DC1_ACTIVE); case REGULATOR_MODE_IDLE: /* Datasheet: standby */ - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset, WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0); default: return -EINVAL; @@ -195,7 +188,7 @@ static struct regulator_desc regulators[] = { .id = WM8400_DCDC2, .ops = &wm8400_dcdc_ops, .enable_reg = WM8400_DCDC2_CONTROL_1, - .enable_mask = WM8400_DC1_ENA_MASK, + .enable_mask = WM8400_DC2_ENA_MASK, .n_voltages = WM8400_DC2_VSEL_MASK + 1, .vsel_reg = WM8400_DCDC2_CONTROL_1, .vsel_mask = WM8400_DC2_VSEL_MASK, diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 38928cdcb6e6..cadea0344486 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -1,15 +1,10 @@ -/* - * wm8994-regulator.c -- Regulator driver for the WM8994 - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm8994-regulator.c -- Regulator driver for the WM8994 +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> |