From d16db38c2a66060ee25c6b86ee7b6d66d40fc8e0 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 3 Jul 2023 20:15:54 +0200 Subject: dt-bindings: regulator: Describe Qualcomm REFGEN regulator Modern Qualcomm SoCs have a REFGEN (reference voltage generator) regulator, providing reference voltage to on-chip IP, like PHYs. It's controlled through MMIO and we can toggle it or read its state back. Describe it. Signed-off-by: Konrad Dybcio Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20230628-topic-refgen-v3-1-9fbf0e605d23@linaro.org Signed-off-by: Mark Brown --- .../regulator/qcom,sdm845-refgen-regulator.yaml | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml new file mode 100644 index 000000000000..f02f97d4fdd2 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/qcom,sdm845-refgen-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. REFGEN Regulator + +maintainers: + - Konrad Dybcio + +description: + The REFGEN (reference voltage generator) regulator provides reference + voltage for on-chip IPs (like PHYs) on some Qualcomm SoCs. + +allOf: + - $ref: regulator.yaml# + +properties: + compatible: + oneOf: + - items: + - enum: + - qcom,sc7180-refgen-regulator + - qcom,sc8180x-refgen-regulator + - qcom,sm8150-refgen-regulator + - const: qcom,sdm845-refgen-regulator + + - items: + - enum: + - qcom,sc7280-refgen-regulator + - qcom,sc8280xp-refgen-regulator + - qcom,sm6350-refgen-regulator + - qcom,sm6375-refgen-regulator + - qcom,sm8350-refgen-regulator + - const: qcom,sm8250-refgen-regulator + + - enum: + - qcom,sdm845-refgen-regulator + - qcom,sm8250-refgen-regulator + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + regulator@162f000 { + compatible = "qcom,sm8250-refgen-regulator"; + reg = <0x0162f000 0x84>; + }; +... -- cgit v1.2.3-70-g09d2 From 7cbfbe23796086fdb72b681e2c182b02acd36a04 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 3 Jul 2023 20:15:55 +0200 Subject: regulator: Introduce Qualcomm REFGEN regulator driver Modern Qualcomm SoCs have a REFGEN (reference voltage generator) regulator, providing reference voltage to on-chip IP, like PHYs. Add a driver to support toggling that regulator. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20230628-topic-refgen-v3-2-9fbf0e605d23@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 11 +++ drivers/regulator/Makefile | 1 + drivers/regulator/qcom-refgen-regulator.c | 154 ++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 drivers/regulator/qcom-refgen-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 823f8e6e4801..18a05b09406f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -989,6 +989,17 @@ config REGULATOR_PWM This driver supports PWM controlled voltage regulators. PWM duty cycle can increase or decrease the voltage. +config REGULATOR_QCOM_REFGEN + tristate "Qualcomm REFGEN regulator driver" + depends on HAS_IOMEM + depends on REGMAP + help + This driver supports the MMIO-mapped reference voltage regulator, + used internally by some PHYs on many Qualcomm SoCs. + + Say M here if you want to include support for this regulator as + a module. The module will be named "qcom-refgen-regulator". + config REGULATOR_QCOM_RPM tristate "Qualcomm RPM regulator driver" depends on MFD_QCOM_RPM diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 15e0d614ff66..4f4589877e81 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o +obj-$(CONFIG_REGULATOR_QCOM_REFGEN) += qcom-refgen-regulator.o obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c new file mode 100644 index 000000000000..656fe330d38f --- /dev/null +++ b/drivers/regulator/qcom-refgen-regulator.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2017, 2019-2020, The Linux Foundation. All rights reserved. +// Copyright (c) 2023, Linaro Limited + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REFGEN_REG_BIAS_EN 0x08 +#define REFGEN_BIAS_EN_MASK GENMASK(2, 0) + #define REFGEN_BIAS_EN_ENABLE 0x7 + #define REFGEN_BIAS_EN_DISABLE 0x6 + +#define REFGEN_REG_BG_CTRL 0x14 +#define REFGEN_BG_CTRL_MASK GENMASK(2, 1) + #define REFGEN_BG_CTRL_ENABLE 0x3 + #define REFGEN_BG_CTRL_DISABLE 0x2 + +#define REFGEN_REG_PWRDWN_CTRL5 0x80 +#define REFGEN_PWRDWN_CTRL5_MASK BIT(0) + #define REFGEN_PWRDWN_CTRL5_ENABLE 0x1 + +static int qcom_sdm845_refgen_enable(struct regulator_dev *rdev) +{ + regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK, + FIELD_PREP(REFGEN_BG_CTRL_MASK, REFGEN_BG_CTRL_ENABLE)); + + regmap_write(rdev->regmap, REFGEN_REG_BIAS_EN, + FIELD_PREP(REFGEN_BIAS_EN_MASK, REFGEN_BIAS_EN_ENABLE)); + + return 0; +} + +static int qcom_sdm845_refgen_disable(struct regulator_dev *rdev) +{ + regmap_write(rdev->regmap, REFGEN_REG_BIAS_EN, + FIELD_PREP(REFGEN_BIAS_EN_MASK, REFGEN_BIAS_EN_DISABLE)); + + regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK, + FIELD_PREP(REFGEN_BG_CTRL_MASK, REFGEN_BG_CTRL_DISABLE)); + + return 0; +} + +static int qcom_sdm845_refgen_is_enabled(struct regulator_dev *rdev) +{ + u32 val; + + regmap_read(rdev->regmap, REFGEN_REG_BG_CTRL, &val); + if (FIELD_GET(REFGEN_BG_CTRL_MASK, val) != REFGEN_BG_CTRL_ENABLE) + return 0; + + regmap_read(rdev->regmap, REFGEN_REG_BIAS_EN, &val); + if (FIELD_GET(REFGEN_BIAS_EN_MASK, val) != REFGEN_BIAS_EN_ENABLE) + return 0; + + return 1; +} + +static struct regulator_desc sdm845_refgen_desc = { + .enable_time = 5, + .name = "refgen", + .owner = THIS_MODULE, + .type = REGULATOR_VOLTAGE, + .ops = &(const struct regulator_ops) { + .enable = qcom_sdm845_refgen_enable, + .disable = qcom_sdm845_refgen_disable, + .is_enabled = qcom_sdm845_refgen_is_enabled, + }, +}; + +static struct regulator_desc sm8250_refgen_desc = { + .enable_reg = REFGEN_REG_PWRDWN_CTRL5, + .enable_mask = REFGEN_PWRDWN_CTRL5_MASK, + .enable_val = REFGEN_PWRDWN_CTRL5_ENABLE, + .disable_val = 0, + .enable_time = 5, + .name = "refgen", + .owner = THIS_MODULE, + .type = REGULATOR_VOLTAGE, + .ops = &(const struct regulator_ops) { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + }, +}; + +static const struct regmap_config qcom_refgen_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +static int qcom_refgen_probe(struct platform_device *pdev) +{ + struct regulator_init_data *init_data; + struct regulator_config config = {}; + const struct regulator_desc *rdesc; + struct device *dev = &pdev->dev; + struct regulator_dev *rdev; + struct regmap *regmap; + void __iomem *base; + + rdesc = of_device_get_match_data(dev); + if (!rdesc) + return -ENODATA; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap = devm_regmap_init_mmio(dev, base, &qcom_refgen_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc); + if (!init_data) + return -ENOMEM; + + config.dev = dev; + config.init_data = init_data; + config.of_node = dev->of_node; + config.regmap = regmap; + + rdev = devm_regulator_register(dev, rdesc, &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + + return 0; +} + +static const struct of_device_id qcom_refgen_match_table[] = { + { .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_refgen_desc }, + { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc }, + { } +}; + +static struct platform_driver qcom_refgen_driver = { + .probe = qcom_refgen_probe, + .driver = { + .name = "qcom-refgen-regulator", + .of_match_table = qcom_refgen_match_table, + }, +}; +module_platform_driver(qcom_refgen_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Qualcomm REFGEN regulator driver"); -- cgit v1.2.3-70-g09d2 From 8978af5ef662541bc0a5a7722ad6942cd19daed0 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Thu, 29 Jun 2023 22:29:55 +0800 Subject: regulator: dt-bindings: rt5739: Add compatible for rt5733 Add compatible string for rt5733. Signed-off-by: ChiYuan Huang Acked-by: Rob Herring Link: https://lore.kernel.org/r/1688048996-25606-2-git-send-email-cy_huang@richtek.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml index 358297dd3fb7..e95e046e9ed6 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rt5739.yaml @@ -21,6 +21,7 @@ allOf: properties: compatible: enum: + - richtek,rt5733 - richtek,rt5739 reg: -- cgit v1.2.3-70-g09d2 From 6f5e285839845729858b8f6ca7cf3dd35e1f9a29 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Thu, 29 Jun 2023 22:29:56 +0800 Subject: regulator: rt5739: Add DID check and compatible for rt5733 Add compatible and use DID to check rt5733. The only difference bwtween rt5733 and rt5739 is the output range and voltage step. These two chips can be distinguished from the DIE id. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1688048996-25606-3-git-send-email-cy_huang@richtek.com Signed-off-by: Mark Brown --- drivers/regulator/rt5739.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/rt5739.c b/drivers/regulator/rt5739.c index 0ce6a1666752..91412c905ce6 100644 --- a/drivers/regulator/rt5739.c +++ b/drivers/regulator/rt5739.c @@ -31,10 +31,17 @@ #define RT5739_MODEVSEL1_MASK BIT(1) #define RT5739_MODEVSEL0_MASK BIT(0) #define RT5739_VID_MASK GENMASK(7, 5) +#define RT5739_DID_MASK GENMASK(3, 0) #define RT5739_ACTD_MASK BIT(7) #define RT5739_ENVSEL1_MASK BIT(1) #define RT5739_ENVSEL0_MASK BIT(0) +#define RT5733_CHIPDIE_ID 0x1 +#define RT5733_VOLT_MINUV 270000 +#define RT5733_VOLT_MAXUV 1401250 +#define RT5733_VOLT_STPUV 6250 +#define RT5733_N_VOLTS 182 + #define RT5739_VOLT_MINUV 300000 #define RT5739_VOLT_MAXUV 1300000 #define RT5739_VOLT_STPUV 5000 @@ -93,8 +100,11 @@ static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV) const struct regulator_desc *desc = rdev->desc; struct regmap *regmap = rdev_get_regmap(rdev); unsigned int reg, vsel; + int max_uV; + + max_uV = desc->min_uV + desc->uV_step * (desc->n_voltages - 1); - if (uV < RT5739_VOLT_MINUV || uV > RT5739_VOLT_MAXUV) + if (uV < desc->min_uV || uV > max_uV) return -EINVAL; if (desc->vsel_reg == RT5739_REG_NSEL0) @@ -102,7 +112,7 @@ static int rt5739_set_suspend_voltage(struct regulator_dev *rdev, int uV) else reg = RT5739_REG_NSEL0; - vsel = (uV - RT5739_VOLT_MINUV) / RT5739_VOLT_STPUV; + vsel = (uV - desc->min_uV) / desc->uV_step; return regmap_write(regmap, reg, vsel); } @@ -189,15 +199,12 @@ static unsigned int rt5739_of_map_mode(unsigned int mode) } static void rt5739_init_regulator_desc(struct regulator_desc *desc, - bool vsel_active_high) + bool vsel_active_high, u8 did) { /* Fixed */ desc->name = "rt5739-regulator"; desc->owner = THIS_MODULE; desc->ops = &rt5739_regulator_ops; - desc->n_voltages = RT5739_N_VOLTS; - desc->min_uV = RT5739_VOLT_MINUV; - desc->uV_step = RT5739_VOLT_STPUV; desc->vsel_mask = RT5739_VSEL_MASK; desc->enable_reg = RT5739_REG_CNTL2; desc->active_discharge_reg = RT5739_REG_CNTL1; @@ -213,6 +220,20 @@ static void rt5739_init_regulator_desc(struct regulator_desc *desc, desc->vsel_reg = RT5739_REG_NSEL0; desc->enable_mask = RT5739_ENVSEL0_MASK; } + + /* Assigned by CHIPDIE ID */ + switch (did) { + case RT5733_CHIPDIE_ID: + desc->n_voltages = RT5733_N_VOLTS; + desc->min_uV = RT5733_VOLT_MINUV; + desc->uV_step = RT5733_VOLT_STPUV; + break; + default: + desc->n_voltages = RT5739_N_VOLTS; + desc->min_uV = RT5739_VOLT_MINUV; + desc->uV_step = RT5739_VOLT_STPUV; + break; + } } static const struct regmap_config rt5739_regmap_config = { @@ -258,7 +279,7 @@ static int rt5739_probe(struct i2c_client *i2c) vsel_acth = device_property_read_bool(dev, "richtek,vsel-active-high"); - rt5739_init_regulator_desc(desc, vsel_acth); + rt5739_init_regulator_desc(desc, vsel_acth, vid & RT5739_DID_MASK); cfg.dev = dev; cfg.of_node = dev_of_node(dev); @@ -271,6 +292,7 @@ static int rt5739_probe(struct i2c_client *i2c) } static const struct of_device_id rt5739_device_table[] = { + { .compatible = "richtek,rt5733" }, { .compatible = "richtek,rt5739" }, { /* sentinel */ } }; -- cgit v1.2.3-70-g09d2 From 42a95739c5bc4d7a6e93a43117e9283598ba2287 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 29 Jun 2023 11:42:00 +0100 Subject: regulator: raa215300: Change the scope of the variables {clkin_name, xin_name} Change the scope of the variables {clkin_name, xin_name} from global->local to fix the below warning. drivers/regulator/raa215300.c:42:12: sparse: sparse: symbol 'xin_name' was not declared. Should it be static? Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202306250552.Fan9WTiN-lkp@intel.com/ Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230629104200.102663-1-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- drivers/regulator/raa215300.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c index 24a1c89f5dbc..8e1a4c86b978 100644 --- a/drivers/regulator/raa215300.c +++ b/drivers/regulator/raa215300.c @@ -38,8 +38,6 @@ #define RAA215300_REG_BLOCK_EN_RTC_EN BIT(6) #define RAA215300_RTC_DEFAULT_ADDR 0x6f -const char *clkin_name = "clkin"; -const char *xin_name = "xin"; static struct clk *clk; static const struct regmap_config raa215300_regmap_config = { @@ -71,8 +69,10 @@ static int raa215300_clk_present(struct i2c_client *client, const char *name) static int raa215300_i2c_probe(struct i2c_client *client) { struct device *dev = &client->dev; - const char *clk_name = xin_name; + const char *clkin_name = "clkin"; unsigned int pmic_version, val; + const char *xin_name = "xin"; + const char *clk_name = NULL; struct regmap *regmap; int ret; @@ -114,15 +114,17 @@ static int raa215300_i2c_probe(struct i2c_client *client) ret = raa215300_clk_present(client, xin_name); if (ret < 0) { return ret; - } else if (!ret) { + } else if (ret) { + clk_name = xin_name; + } else { ret = raa215300_clk_present(client, clkin_name); if (ret < 0) return ret; - - clk_name = clkin_name; + if (ret) + clk_name = clkin_name; } - if (ret) { + if (clk_name) { char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0"; struct device_node *np = client->dev.of_node; u32 addr = RAA215300_RTC_DEFAULT_ADDR; -- cgit v1.2.3-70-g09d2 From 741da3f60479acc0de3d79501c4819e49fa28639 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 26 Jun 2023 11:15:44 +0200 Subject: regulator: raa215300: Switch back to use struct i2c_driver::probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct i2c_driver::probe_new is about to go away. Switch the driver to use the probe callback with the same prototype. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230626091544.557403-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/raa215300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c index 8e1a4c86b978..848a03a2fbd4 100644 --- a/drivers/regulator/raa215300.c +++ b/drivers/regulator/raa215300.c @@ -182,7 +182,7 @@ static struct i2c_driver raa215300_i2c_driver = { .name = "raa215300", .of_match_table = raa215300_dt_match, }, - .probe_new = raa215300_i2c_probe, + .probe = raa215300_i2c_probe, }; module_i2c_driver(raa215300_i2c_driver); -- cgit v1.2.3-70-g09d2 From 497897cb200d03b89524e6b4dfb71c77af324766 Mon Sep 17 00:00:00 2001 From: Christoph Niedermaier Date: Thu, 13 Jul 2023 11:03:28 +0200 Subject: regulator: da9062: Make the use of IRQ optional This patch makes the use of IRQ optional to make the DA9061/62 usable for designs that don't have the IRQ pin connected, because the regulator is usable without IRQ. Signed-off-by: Christoph Niedermaier Reviewed-by: Adam Ward Reviewed-by: Marek Vasut Link: https://lore.kernel.org/r/20230713090328.3879-1-cniedermaier@dh-electronics.com Signed-off-by: Mark Brown --- drivers/regulator/da9062-regulator.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index c28b061eef02..1d354db0c1bd 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -924,7 +924,7 @@ static int da9062_regulator_probe(struct platform_device *pdev) struct da9062_regulator *regl; struct regulator_config config = { }; const struct da9062_regulator_info *rinfo; - int irq, n, ret; + int n, ret; int max_regulators; switch (chip->chip_type) { @@ -1012,12 +1012,11 @@ static int da9062_regulator_probe(struct platform_device *pdev) } /* LDOs overcurrent event support */ - irq = platform_get_irq_byname(pdev, "LDO_LIM"); - if (irq < 0) - return irq; - regulators->irq_ldo_lim = irq; + regulators->irq_ldo_lim = platform_get_irq_byname_optional(pdev, "LDO_LIM"); + if (regulators->irq_ldo_lim < 0) + return 0; - ret = devm_request_threaded_irq(&pdev->dev, irq, + ret = devm_request_threaded_irq(&pdev->dev, regulators->irq_ldo_lim, NULL, da9062_ldo_lim_event, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "LDO_LIM", regulators); -- cgit v1.2.3-70-g09d2 From 045a44d4c9b32578aacf0811063e5bb741c7c32c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 14 Jul 2023 11:49:28 -0600 Subject: regulator: Explicitly include correct DT includes The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20230714174930.4063320-1-robh@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/act8945a-regulator.c | 2 +- drivers/regulator/atc260x-regulator.c | 3 ++- drivers/regulator/axp20x-regulator.c | 1 - drivers/regulator/cpcap-regulator.c | 2 +- drivers/regulator/fan53555.c | 2 +- drivers/regulator/fixed.c | 1 - drivers/regulator/ltc3589.c | 1 - drivers/regulator/max77826-regulator.c | 1 - drivers/regulator/mp5416.c | 2 +- drivers/regulator/mp886x.c | 2 +- drivers/regulator/mpq7920.c | 1 - drivers/regulator/mt6315-regulator.c | 2 +- drivers/regulator/mt6359-regulator.c | 3 ++- drivers/regulator/mtk-dvfsrc-regulator.c | 3 +-- drivers/regulator/pbias-regulator.c | 1 - drivers/regulator/pca9450-regulator.c | 1 - drivers/regulator/pwm-regulator.c | 2 +- drivers/regulator/qcom-rpmh-regulator.c | 1 - drivers/regulator/qcom_smd-regulator.c | 1 - drivers/regulator/qcom_usb_vbus-regulator.c | 1 - drivers/regulator/rk808-regulator.c | 3 ++- drivers/regulator/rt5759-regulator.c | 2 +- drivers/regulator/stm32-pwr.c | 3 +-- drivers/regulator/stm32-vrefbuf.c | 2 +- drivers/regulator/sy8824x.c | 2 +- drivers/regulator/sy8827n.c | 2 +- drivers/regulator/tps6286x-regulator.c | 2 +- drivers/regulator/tps6287x-regulator.c | 2 +- drivers/regulator/tps65218-regulator.c | 2 +- drivers/regulator/tps65219-regulator.c | 2 +- drivers/regulator/tps6594-regulator.c | 2 +- drivers/regulator/twl-regulator.c | 1 - drivers/regulator/twl6030-regulator.c | 1 - drivers/regulator/uniphier-regulator.c | 2 +- drivers/regulator/vctrl-regulator.c | 2 +- drivers/regulator/vexpress-regulator.c | 3 ++- 36 files changed, 28 insertions(+), 38 deletions(-) diff --git a/drivers/regulator/act8945a-regulator.c b/drivers/regulator/act8945a-regulator.c index e26264529b74..24cbdd833863 100644 --- a/drivers/regulator/act8945a-regulator.c +++ b/drivers/regulator/act8945a-regulator.c @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/regulator/atc260x-regulator.c b/drivers/regulator/atc260x-regulator.c index 87e237d740bc..09fe51464090 100644 --- a/drivers/regulator/atc260x-regulator.c +++ b/drivers/regulator/atc260x-regulator.c @@ -7,7 +7,8 @@ #include #include -#include +#include +#include #include #include diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 810f90f3e2a1..c657820b0bbb 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index 1fd79fb17303..6958d154442b 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 289c06e09f47..48f312167e53 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 364d1a2683b7..55130efae9b8 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index e9751c206d95..cf931b8c36dc 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/max77826-regulator.c b/drivers/regulator/max77826-regulator.c index 3855f5e686d8..5590cdf615b7 100644 --- a/drivers/regulator/max77826-regulator.c +++ b/drivers/regulator/max77826-regulator.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/mp5416.c b/drivers/regulator/mp5416.c index 3886b252fbe7..d068ac93d373 100644 --- a/drivers/regulator/mp5416.c +++ b/drivers/regulator/mp5416.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index ede1b1e58002..9911be2e6bac 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/mpq7920.c b/drivers/regulator/mpq7920.c index bf677c535edc..4926c229109b 100644 --- a/drivers/regulator/mpq7920.c +++ b/drivers/regulator/mpq7920.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/mt6315-regulator.c b/drivers/regulator/mt6315-regulator.c index 8047081ea2f7..2608a6652d77 100644 --- a/drivers/regulator/mt6315-regulator.c +++ b/drivers/regulator/mt6315-regulator.c @@ -3,7 +3,7 @@ // Copyright (c) 2021 MediaTek Inc. #include -#include +#include #include #include #include diff --git a/drivers/regulator/mt6359-regulator.c b/drivers/regulator/mt6359-regulator.c index 3eb86ec21d08..5cf6448fb05f 100644 --- a/drivers/regulator/mt6359-regulator.c +++ b/drivers/regulator/mt6359-regulator.c @@ -2,12 +2,13 @@ // // Copyright (c) 2021 MediaTek Inc. +#include #include #include #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/mtk-dvfsrc-regulator.c b/drivers/regulator/mtk-dvfsrc-regulator.c index efca67207a5a..f1280d45265d 100644 --- a/drivers/regulator/mtk-dvfsrc-regulator.c +++ b/drivers/regulator/mtk-dvfsrc-regulator.c @@ -6,8 +6,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index 0c9873e9abdc..cd5a0d7e4455 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -25,7 +25,6 @@ #include #include #include -#include struct pbias_reg_info { u32 enable; diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index 91bfb7e026c9..2ab365d2749f 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index b64d99695b84..2aff6db748e2 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -10,11 +10,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index f3b280af0773..ec1b50721ec6 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 18189f35db68..f53ada076252 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index 57ec613f4a0a..cd94ed67621f 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 460525ed006c..867a2cf243f6 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -17,9 +17,10 @@ #include #include #include -#include +#include #include #include +#include #include #include #include diff --git a/drivers/regulator/rt5759-regulator.c b/drivers/regulator/rt5759-regulator.c index 90555a9ef1b0..c2553dcee050 100644 --- a/drivers/regulator/rt5759-regulator.c +++ b/drivers/regulator/rt5759-regulator.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c index 4c60eddad60d..85b0102fb9b1 100644 --- a/drivers/regulator/stm32-pwr.c +++ b/drivers/regulator/stm32-pwr.c @@ -6,8 +6,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c index f5ccc7dd309a..717144cbe0f9 100644 --- a/drivers/regulator/stm32-vrefbuf.c +++ b/drivers/regulator/stm32-vrefbuf.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/sy8824x.c b/drivers/regulator/sy8824x.c index d0703105c439..d49c0cba09fb 100644 --- a/drivers/regulator/sy8824x.c +++ b/drivers/regulator/sy8824x.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c index 433959b43549..f11ff38b36c9 100644 --- a/drivers/regulator/sy8827n.c +++ b/drivers/regulator/sy8827n.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/tps6286x-regulator.c b/drivers/regulator/tps6286x-regulator.c index b1c4b5120745..c06f6d1dc737 100644 --- a/drivers/regulator/tps6286x-regulator.c +++ b/drivers/regulator/tps6286x-regulator.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c index b1c0963586ac..19a4a300a963 100644 --- a/drivers/regulator/tps6287x-regulator.c +++ b/drivers/regulator/tps6287x-regulator.c @@ -8,8 +8,8 @@ #include #include +#include #include -#include #include #include #include diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 13985883e5f0..f44b5767099c 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -8,12 +8,12 @@ */ #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index 8971b507a79a..b4065356392f 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -15,8 +15,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c index d5a574ec6d12..25ef102c8270 100644 --- a/drivers/regulator/tps6594-regulator.c +++ b/drivers/regulator/tps6594-regulator.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 3e724f5345de..5bacfcebf59a 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c index f9c695f9bde8..6eed0f6e0adb 100644 --- a/drivers/regulator/twl6030-regulator.c +++ b/drivers/regulator/twl6030-regulator.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c index 7e2785e10dc6..1d8304b88bd6 100644 --- a/drivers/regulator/uniphier-regulator.c +++ b/drivers/regulator/uniphier-regulator.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c index 85dca90233f6..2796580a3a3c 100644 --- a/drivers/regulator/vctrl-regulator.c +++ b/drivers/regulator/vctrl-regulator.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/regulator/vexpress-regulator.c b/drivers/regulator/vexpress-regulator.c index b545dbc70a4d..6687077e9a97 100644 --- a/drivers/regulator/vexpress-regulator.c +++ b/drivers/regulator/vexpress-regulator.c @@ -8,7 +8,8 @@ #include #include #include -#include +#include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From af71cccadecedad3484c2208e2c4fc8eff927d4a Mon Sep 17 00:00:00 2001 From: Okan Sahin Date: Mon, 17 Jul 2023 08:07:35 +0300 Subject: regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator Support Regulator driver for MAX77857/59 and MAX77831. The MAX77857 is a high-efficiency, high-performance buck-boost converter targeted for systems requiring a wide input voltage range (2.5V to 16V). The MAX77859 is high-Efficiency Buck-Boost Converter for USB-PD/PPS Applications. It has wide input range (2.5V to 22V) The MAX77831 is a high-efficiency, high-performance buck-boost converter targeted for systems requiring wide input voltage range (2.5V to 16V). Signed-off-by: Okan Sahin Link: https://lore.kernel.org/r/20230717050736.10075-3-okan.sahin@analog.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/max77857-regulator.c | 459 +++++++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 drivers/regulator/max77857-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 18a05b09406f..542a7b427994 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -584,6 +584,16 @@ config REGULATOR_MAX77650 Semiconductor. This device has a SIMO with three independent power rails and an LDO. +config REGULATOR_MAX77857 + tristate "ADI MAX77857/MAX77831 regulator support" + depends on I2C + select REGMAP_I2C + help + This driver controls a ADI MAX77857 and MAX77831 regulators. + via I2C bus. MAX77857 and MAX77831 are high efficiency buck-boost + converters with input voltage range (2.5V to 16V). Say Y here to + enable the regulator driver + config REGULATOR_MAX8649 tristate "Maxim 8649 voltage regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 4f4589877e81..77b22bdd2791 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_REGULATOR_MAX77686) += max77686-regulator.o obj-$(CONFIG_REGULATOR_MAX77693) += max77693-regulator.o obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o obj-$(CONFIG_REGULATOR_MAX77826) += max77826-regulator.o +obj-$(CONFIG_REGULATOR_MAX77857) += max77857-regulator.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c new file mode 100644 index 000000000000..c5482ffd606e --- /dev/null +++ b/drivers/regulator/max77857-regulator.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023 Analog Devices, Inc. + * ADI Regulator driver for the MAX77857 + * MAX77859 and MAX77831. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX77857_REG_INT_SRC 0x10 +#define MAX77857_REG_INT_MASK 0x11 +#define MAX77857_REG_CONT1 0x12 +#define MAX77857_REG_CONT2 0x13 +#define MAX77857_REG_CONT3 0x14 + +#define MAX77857_INT_SRC_OCP BIT(0) +#define MAX77857_INT_SRC_THS BIT(1) +#define MAX77857_INT_SRC_HARDSHORT BIT(2) +#define MAX77857_INT_SRC_OVP BIT(3) +#define MAX77857_INT_SRC_POK BIT(4) + +#define MAX77857_ILIM_MASK GENMASK(2, 0) +#define MAX77857_CONT1_FREQ GENMASK(4, 3) +#define MAX77857_CONT3_FPWM BIT(5) + +#define MAX77859_REG_INT_SRC 0x11 +#define MAX77859_REG_CONT1 0x13 +#define MAX77859_REG_CONT2 0x14 +#define MAX77859_REG_CONT3 0x15 +#define MAX77859_REG_CONT5 0x17 +#define MAX77859_CONT2_FPWM BIT(2) +#define MAX77859_CONT2_INTB BIT(3) +#define MAX77859_CONT3_DVS_START BIT(2) +#define MAX77859_VOLTAGE_SEL_MASK GENMASK(9, 0) + +#define MAX77859_CURRENT_MIN 1000000 +#define MAX77859_CURRENT_MAX 5000000 +#define MAX77859_CURRENT_STEP 50000 + +enum max77857_id { + ID_MAX77831 = 1, + ID_MAX77857, + ID_MAX77859, + ID_MAX77859A, +}; + +static bool max77857_volatile_reg(struct device *dev, unsigned int reg) +{ + enum max77857_id id = (enum max77857_id)dev_get_drvdata(dev); + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + return reg == MAX77857_REG_INT_SRC; + case ID_MAX77859: + case ID_MAX77859A: + return reg == MAX77859_REG_INT_SRC; + default: + return true; + } +} + +struct regmap_config max77857_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_MAPLE, + .volatile_reg = max77857_volatile_reg, +}; + +static int max77857_get_status(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val); + if (ret) + return ret; + + if (FIELD_GET(MAX77857_INT_SRC_POK, val)) + return REGULATOR_STATUS_ON; + + return REGULATOR_STATUS_ERROR; +} + +static unsigned int max77857_get_mode(struct regulator_dev *rdev) +{ + enum max77857_id id = (enum max77857_id)rdev_get_drvdata(rdev); + unsigned int regval; + int ret; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + ret = regmap_read(rdev->regmap, MAX77857_REG_CONT3, ®val); + if (ret) + return ret; + + if (FIELD_GET(MAX77857_CONT3_FPWM, regval)) + return REGULATOR_MODE_FAST; + + break; + case ID_MAX77859: + case ID_MAX77859A: + ret = regmap_read(rdev->regmap, MAX77859_REG_CONT2, ®val); + if (ret) + return ret; + + if (FIELD_GET(MAX77859_CONT2_FPWM, regval)) + return REGULATOR_MODE_FAST; + + break; + default: + return -EINVAL; + } + + return REGULATOR_MODE_NORMAL; +} + +static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + enum max77857_id id = (enum max77857_id)rdev_get_drvdata(rdev); + unsigned int reg, val; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + reg = MAX77857_REG_CONT3; + val = MAX77857_CONT3_FPWM; + break; + case ID_MAX77859: + case ID_MAX77859A: + reg = MAX77859_REG_CONT2; + val = MAX77859_CONT2_FPWM; + break; + default: + return -EINVAL; + } + + switch (mode) { + case REGULATOR_MODE_FAST: + return regmap_set_bits(rdev->regmap, reg, val); + case REGULATOR_MODE_NORMAL: + return regmap_clear_bits(rdev->regmap, reg, val); + default: + return -EINVAL; + } +} + +static int max77857_get_error_flags(struct regulator_dev *rdev, + unsigned int *flags) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, MAX77857_REG_INT_SRC, &val); + if (ret) + return ret; + + *flags = 0; + + if (FIELD_GET(MAX77857_INT_SRC_OVP, val)) + *flags |= REGULATOR_ERROR_OVER_VOLTAGE_WARN; + + if (FIELD_GET(MAX77857_INT_SRC_OCP, val) || + FIELD_GET(MAX77857_INT_SRC_HARDSHORT, val)) + *flags |= REGULATOR_ERROR_OVER_CURRENT; + + if (FIELD_GET(MAX77857_INT_SRC_THS, val)) + *flags |= REGULATOR_ERROR_OVER_TEMP; + + if (!FIELD_GET(MAX77857_INT_SRC_POK, val)) + *flags |= REGULATOR_ERROR_FAIL; + + return 0; +} + +static struct linear_range max77859_lin_ranges[] = { + REGULATOR_LINEAR_RANGE(3200000, 0x0A0, 0x320, 20000) +}; + +static const unsigned int max77859_ramp_table[4] = { + 1000, 500, 250, 125 +}; + +static int max77859_set_voltage_sel(struct regulator_dev *rdev, + unsigned int sel) +{ + __be16 reg; + int ret; + + reg = cpu_to_be16(sel); + + ret = regmap_bulk_write(rdev->regmap, MAX77859_REG_CONT3, ®, 2); + if (ret) + return ret; + + /* actually apply new voltage */ + return regmap_set_bits(rdev->regmap, MAX77859_REG_CONT3, + MAX77859_CONT3_DVS_START); +} + +int max77859_get_voltage_sel(struct regulator_dev *rdev) +{ + __be16 reg; + int ret; + + ret = regmap_bulk_read(rdev->regmap, MAX77859_REG_CONT3, ®, 2); + if (ret) + return ret; + + return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg)); +} + +int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) +{ + u32 selector; + + if (max_uA < MAX77859_CURRENT_MIN) + return -EINVAL; + + selector = 0x12 + (max_uA - MAX77859_CURRENT_MIN) / MAX77859_CURRENT_STEP; + + selector = clamp_val(selector, 0x00, 0x7F); + + return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector); +} + +int max77859_get_current_limit(struct regulator_dev *rdev) +{ + u32 selector; + int ret; + + ret = regmap_read(rdev->regmap, MAX77859_REG_CONT5, &selector); + if (ret) + return ret; + + if (selector <= 0x12) + return MAX77859_CURRENT_MIN; + + if (selector >= 0x64) + return MAX77859_CURRENT_MAX; + + return MAX77859_CURRENT_MIN + (selector - 0x12) * MAX77859_CURRENT_STEP; +} + +static const struct regulator_ops max77859_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = max77859_set_voltage_sel, + .get_voltage_sel = max77859_get_voltage_sel, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .get_status = max77857_get_status, + .set_mode = max77857_set_mode, + .get_mode = max77857_get_mode, + .get_error_flags = max77857_get_error_flags, +}; + +static const struct regulator_ops max77859a_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = max77859_set_voltage_sel, + .get_voltage_sel = max77859_get_voltage_sel, + .set_current_limit = max77859_set_current_limit, + .get_current_limit = max77859_get_current_limit, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .get_status = max77857_get_status, + .set_mode = max77857_set_mode, + .get_mode = max77857_get_mode, + .get_error_flags = max77857_get_error_flags, +}; + +static const struct regulator_ops max77857_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .get_status = max77857_get_status, + .set_mode = max77857_set_mode, + .get_mode = max77857_get_mode, + .get_error_flags = max77857_get_error_flags, +}; + +static struct linear_range max77857_lin_ranges[] = { + REGULATOR_LINEAR_RANGE(4485000, 0x3D, 0xCC, 73500) +}; + +static const unsigned int max77857_switch_freq[] = { + 1200000, 1500000, 1800000, 2100000 +}; + +static const unsigned int max77857_ramp_table[2][4] = { + { 1333, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */ + { 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */ +}; + +static struct regulator_desc max77857_regulator_desc = { + .ops = &max77857_regulator_ops, + .name = "max77857", + .linear_ranges = max77857_lin_ranges, + .n_linear_ranges = ARRAY_SIZE(max77857_lin_ranges), + .vsel_mask = 0xFF, + .vsel_reg = MAX77857_REG_CONT2, + .ramp_delay_table = max77857_ramp_table[0], + .n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]), + .ramp_reg = MAX77857_REG_CONT3, + .ramp_mask = GENMASK(1, 0), + .ramp_delay = max77857_ramp_table[0][0], + .owner = THIS_MODULE, +}; + +static void max77857_calc_range(struct device *dev, enum max77857_id id) +{ + struct linear_range *range; + unsigned long vref_step; + u32 rtop = 0; + u32 rbot = 0; + + device_property_read_u32(dev, "adi,rtop-ohms", &rtop); + device_property_read_u32(dev, "adi,rbot-ohms", &rbot); + + if (!rbot || !rtop) + return; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + range = max77857_lin_ranges; + vref_step = 4900UL; + break; + case ID_MAX77859: + case ID_MAX77859A: + range = max77859_lin_ranges; + vref_step = 1250UL; + break; + } + + range->step = DIV_ROUND_CLOSEST(vref_step * (rbot + rtop), rbot); + range->min = range->step * range->min_sel; +} + +static int max77857_probe(struct i2c_client *client) +{ + const struct i2c_device_id *i2c_id; + struct device *dev = &client->dev; + struct regulator_config cfg = { }; + struct regulator_dev *rdev; + struct regmap *regmap; + enum max77857_id id; + u32 switch_freq = 0; + int ret; + + i2c_id = i2c_client_get_device_id(client); + if (!i2c_id) + return -EINVAL; + + id = i2c_id->driver_data; + + dev_set_drvdata(dev, (void *)id); + + if (id == ID_MAX77859 || id == ID_MAX77859A) { + max77857_regulator_desc.ops = &max77859_regulator_ops; + max77857_regulator_desc.linear_ranges = max77859_lin_ranges; + max77857_regulator_desc.ramp_delay_table = max77859_ramp_table; + max77857_regulator_desc.ramp_delay = max77859_ramp_table[0]; + } + + if (id == ID_MAX77859A) + max77857_regulator_desc.ops = &max77859a_regulator_ops; + + max77857_calc_range(dev, id); + + regmap = devm_regmap_init_i2c(client, &max77857_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "cannot initialize regmap\n"); + + device_property_read_u32(dev, "adi,switch-frequency-hz", &switch_freq); + if (switch_freq) { + switch_freq = find_closest(switch_freq, max77857_switch_freq, + ARRAY_SIZE(max77857_switch_freq)); + + if (id == ID_MAX77831 && switch_freq == 3) + switch_freq = 2; + + switch (id) { + case ID_MAX77831: + case ID_MAX77857: + ret = regmap_update_bits(regmap, MAX77857_REG_CONT1, + MAX77857_CONT1_FREQ, switch_freq); + + if (switch_freq >= 2) + break; + + max77857_regulator_desc.ramp_delay_table = max77857_ramp_table[1]; + max77857_regulator_desc.ramp_delay = max77857_ramp_table[1][0]; + break; + case ID_MAX77859: + case ID_MAX77859A: + ret = regmap_update_bits(regmap, MAX77859_REG_CONT1, + MAX77857_CONT1_FREQ, switch_freq); + break; + } + if (ret) + return ret; + } + + cfg.dev = dev; + cfg.driver_data = (void *)id; + cfg.regmap = regmap; + cfg.init_data = of_get_regulator_init_data(dev, dev->of_node, + &max77857_regulator_desc); + if (!cfg.init_data) + return -ENOMEM; + + rdev = devm_regulator_register(dev, &max77857_regulator_desc, &cfg); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "cannot register regulator\n"); + + return 0; +} + +const struct i2c_device_id max77857_id[] = { + { "max77831", ID_MAX77831 }, + { "max77857", ID_MAX77857 }, + { "max77859", ID_MAX77859 }, + { "max77859a", ID_MAX77859A }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max77857_id); + +static const struct of_device_id max77857_of_id[] = { + { .compatible = "adi,max77831", .data = (void *)ID_MAX77831 }, + { .compatible = "adi,max77857", .data = (void *)ID_MAX77857 }, + { .compatible = "adi,max77859", .data = (void *)ID_MAX77859 }, + { .compatible = "adi,max77859a", .data = (void *)ID_MAX77859A }, + { } +}; +MODULE_DEVICE_TABLE(of, max77857_of_id); + +struct i2c_driver max77857_driver = { + .driver = { + .name = "max77857", + .of_match_table = max77857_of_id, + }, + .id_table = max77857_id, + .probe_new = max77857_probe, +}; +module_i2c_driver(max77857_driver); + +MODULE_DESCRIPTION("Analog Devices MAX77857 Buck-Boost Converter Driver"); +MODULE_AUTHOR("Ibrahim Tilki "); +MODULE_AUTHOR("Okan Sahin "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 6d5373e98b37721987c16fd1c0f9500ecbb69f20 Mon Sep 17 00:00:00 2001 From: Okan Sahin Date: Mon, 17 Jul 2023 08:07:34 +0300 Subject: regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator bindings Add ADI MAX77857/59 and MAX77831 Regulator device tree document. Signed-off-by: Okan Sahin Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20230717050736.10075-2-okan.sahin@analog.com Signed-off-by: Mark Brown --- .../bindings/regulator/adi,max77857.yaml | 86 ++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/adi,max77857.yaml diff --git a/Documentation/devicetree/bindings/regulator/adi,max77857.yaml b/Documentation/devicetree/bindings/regulator/adi,max77857.yaml new file mode 100644 index 000000000000..d1fa74aca721 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/adi,max77857.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2022 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/adi,max77857.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices MAX77857 Buck-Boost Converter + +maintainers: + - Ibrahim Tilki + - Okan Sahin + +description: Analog Devices MAX77857 Buck-Boost Converter + +properties: + compatible: + enum: + - adi,max77831 + - adi,max77857 + - adi,max77859 + - adi,max77859a + + reg: + description: I2C address of the device + items: + - enum: [0x66, 0x67, 0x6E, 0x6F] + + interrupts: + maxItems: 1 + + adi,switch-frequency-hz: + description: Switching frequency of the Buck-Boost converter in Hz. + items: + - enum: [1200000, 1500000, 1800000, 2100000] + + adi,rtop-ohms: + description: Top feedback resistor value in ohms for external feedback. + minimum: 150000 + maximum: 330000 + + adi,rbot-ohms: + description: Bottom feedback resistor value in ohms for external feedback. + +dependencies: + adi,rtop-ohms: [ 'adi,rbot-ohms' ] + adi,rbot-ohms: [ 'adi,rtop-ohms' ] + +required: + - compatible + - reg + +allOf: + - $ref: regulator.yaml# + - if: + properties: + compatible: + contains: + enum: + - adi,max77831 + + then: + properties: + adi,switch-frequency-hz: + items: + enum: [1200000, 1500000, 1800000] + +unevaluatedProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@66 { + reg = <0x66>; + compatible = "adi,max77857"; + interrupt-parent = <&gpio>; + interrupts = <26 IRQ_TYPE_EDGE_FALLING>; + + adi,rtop-ohms = <312000>; + adi,rbot-ohms = <12000>; + }; + }; -- cgit v1.2.3-70-g09d2 From 6023fffc3e276d1ab0d1262ea9be3b720325fede Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 18 Jul 2023 08:32:55 +0800 Subject: regulator: Remove duplicated include in mt6359-regulator.c ./drivers/regulator/mt6359-regulator.c: linux/platform_device.h is included more than once. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5901 Signed-off-by: Yang Li Link: https://lore.kernel.org/r/20230718003255.124594-1-yang.lee@linux.alibaba.com Signed-off-by: Mark Brown --- drivers/regulator/mt6359-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/mt6359-regulator.c b/drivers/regulator/mt6359-regulator.c index 5cf6448fb05f..c8a788858824 100644 --- a/drivers/regulator/mt6359-regulator.c +++ b/drivers/regulator/mt6359-regulator.c @@ -2,7 +2,6 @@ // // Copyright (c) 2021 MediaTek Inc. -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 2920e08bef609c8b59f9996fd6852a7b97119d75 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 18 Jul 2023 22:14:53 +0200 Subject: regulator: max77857: Switch back to use struct i2c_driver's .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit b8a1a4cd5a98 ("i2c: Provide a temporary .probe_new() call-back type"), all drivers being converted to .probe_new() and then commit 03c835f498b5 ("i2c: Switch .probe() to not take an id parameter") convert back to (the new) .probe() to be able to eventually drop .probe_new() from struct i2c_driver. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230718201453.3953602-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/max77857-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c index c5482ffd606e..d0fcb080f825 100644 --- a/drivers/regulator/max77857-regulator.c +++ b/drivers/regulator/max77857-regulator.c @@ -449,7 +449,7 @@ struct i2c_driver max77857_driver = { .of_match_table = max77857_of_id, }, .id_table = max77857_id, - .probe_new = max77857_probe, + .probe = max77857_probe, }; module_i2c_driver(max77857_driver); -- cgit v1.2.3-70-g09d2 From 541e75954cadde0355ce7bebed5675625b2943a8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 18 Jul 2023 21:39:31 +0200 Subject: regulator: max77857: mark more functions static A few functions in the new driver are global but only used in this file: drivers/regulator/max77857-regulator.c:209:5: error: no previous prototype for 'max77859_get_voltage_sel' [-Werror=missing-prototypes] drivers/regulator/max77857-regulator.c:221:5: error: no previous prototype for 'max77859_set_current_limit' [-Werror=missing-prototypes] drivers/regulator/max77857-regulator.c:235:5: error: no previous prototype for 'max77859_get_current_limit' [-Werror=missing-prototypes] Mark them static, which produces potentially better code and avoids the warning. Fixes: af71cccadeced ("regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator Support") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230718193938.3593118-1-arnd@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/max77857-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c index d0fcb080f825..58f825d8d2b0 100644 --- a/drivers/regulator/max77857-regulator.c +++ b/drivers/regulator/max77857-regulator.c @@ -206,7 +206,7 @@ static int max77859_set_voltage_sel(struct regulator_dev *rdev, MAX77859_CONT3_DVS_START); } -int max77859_get_voltage_sel(struct regulator_dev *rdev) +static int max77859_get_voltage_sel(struct regulator_dev *rdev) { __be16 reg; int ret; @@ -218,7 +218,7 @@ int max77859_get_voltage_sel(struct regulator_dev *rdev) return FIELD_GET(MAX77859_VOLTAGE_SEL_MASK, __be16_to_cpu(reg)); } -int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) +static int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) { u32 selector; @@ -232,7 +232,7 @@ int max77859_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_u return regmap_write(rdev->regmap, MAX77859_REG_CONT5, selector); } -int max77859_get_current_limit(struct regulator_dev *rdev) +static int max77859_get_current_limit(struct regulator_dev *rdev) { u32 selector; int ret; -- cgit v1.2.3-70-g09d2 From 813ebba3b100997a24984040673d35cb2dc9f418 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 21 Jul 2023 09:33:03 +0200 Subject: regulator: max8893: Drop "_new" from probe callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver was introduced when .probe_new was the right probe callback to use for i2c drivers. Today .probe is the right one (again) and the driver was already switched in commit 964e186547b2 ("regulator: Switch i2c drivers back to use .probe()") but the name continued to include "_new". To prevent code readers wondering about what might be new here, drop that part of the name. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230721073303.112597-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/max8893.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/max8893.c b/drivers/regulator/max8893.c index cb0e72948dd4..30592425e193 100644 --- a/drivers/regulator/max8893.c +++ b/drivers/regulator/max8893.c @@ -125,7 +125,7 @@ static const struct regmap_config max8893_regmap = { .val_bits = 8, }; -static int max8893_probe_new(struct i2c_client *i2c) +static int max8893_probe(struct i2c_client *i2c) { int id, ret; struct regulator_config config = {.dev = &i2c->dev}; @@ -168,7 +168,7 @@ static const struct i2c_device_id max8893_ids[] = { MODULE_DEVICE_TABLE(i2c, max8893_ids); static struct i2c_driver max8893_driver = { - .probe = max8893_probe_new, + .probe = max8893_probe, .driver = { .name = "max8893", .probe_type = PROBE_PREFER_ASYNCHRONOUS, -- cgit v1.2.3-70-g09d2 From 4fdef8553df58953f572f1cb46d357c735c683a9 Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Tue, 11 Jul 2023 13:30:12 +0530 Subject: regulator: dt-bindings: qcom,rpmh: Update PMX65 entry PMX65 does not have vdd-l18-supply separately and its already part of vdd-l2-l18-supply property specified. Updating this PMX65 dt-bindings entry accordingly. Signed-off-by: Rohit Agarwal Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1689062414-3654-2-git-send-email-quic_rohiagar@quicinc.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index b9498504ad79..12a1e0c35ab2 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -424,7 +424,7 @@ allOf: vdd-l11-l13-supply: true patternProperties: "^vdd-l[1347]-supply$": true - "^vdd-l1[0245789]-supply$": true + "^vdd-l1[024579]-supply$": true "^vdd-l2[01]-supply$": true "^vdd-s[1-8]-supply$": true -- cgit v1.2.3-70-g09d2 From 0ef3d931632e3fce51ed5510935238937d644c97 Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Tue, 11 Jul 2023 13:30:13 +0530 Subject: regulator: dt-bindings: qcom,rpmh: Add PMX75 compatible Add PMX75 compatibles for PMIC found in SDX75 platform. Signed-off-by: Rohit Agarwal Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1689062414-3654-3-git-send-email-quic_rohiagar@quicinc.com Signed-off-by: Mark Brown --- .../bindings/regulator/qcom,rpmh-regulator.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index 12a1e0c35ab2..72b533c3761a 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -53,6 +53,7 @@ description: | For PMR735A, smps1 - smps3, ldo1 - ldo7 For PMX55, smps1 - smps7, ldo1 - ldo16 For PMX65, smps1 - smps8, ldo1 - ldo21 + For PMX75, smps1 - smps10, ldo1 - ldo21 properties: compatible: @@ -84,6 +85,7 @@ properties: - qcom,pmr735a-rpmh-regulators - qcom,pmx55-rpmh-regulators - qcom,pmx65-rpmh-regulators + - qcom,pmx75-rpmh-regulators qcom,pmic-id: description: | @@ -428,6 +430,24 @@ allOf: "^vdd-l2[01]-supply$": true "^vdd-s[1-8]-supply$": true + - if: + properties: + compatible: + enum: + - qcom,pmx75-rpmh-regulators + then: + properties: + vdd-l2-l18-supply: true + vdd-l4-l16-supply: true + vdd-l5-l6-supply: true + vdd-l8-l9-supply: true + vdd-l11-l13-supply: true + vdd-l20-l21-supply: true + patternProperties: + "^vdd-l[137]-supply$": true + "^vdd-l1[024579]-supply$": true + "^vdd-s([1-9]|10)-supply$": true + unevaluatedProperties: false examples: -- cgit v1.2.3-70-g09d2 From 0b294ed669ead34a348d17d06b6d4d58712b14e2 Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Tue, 11 Jul 2023 13:30:14 +0530 Subject: regulator: qcom-rpmh: Add regulators support for PMX75 Add support from RPMH regulators found in PMX75 for SDX75 platform. Signed-off-by: Rohit Agarwal Link: https://lore.kernel.org/r/1689062414-3654-4-git-send-email-quic_rohiagar@quicinc.com Signed-off-by: Mark Brown --- drivers/regulator/qcom-rpmh-regulator.c | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index ec1b50721ec6..88ddd6c54d04 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -1272,6 +1272,40 @@ static const struct rpmh_vreg_init_data pmx65_vreg_data[] = { {} }; +static const struct rpmh_vreg_init_data pmx75_vreg_data[] = { + RPMH_VREG("smps1", "smp%s1", &pmic5_ftsmps525_lv, "vdd-s1"), + RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps525_lv, "vdd-s2"), + RPMH_VREG("smps3", "smp%s3", &pmic5_ftsmps525_lv, "vdd-s3"), + RPMH_VREG("smps4", "smp%s4", &pmic5_ftsmps525_mv, "vdd-s4"), + RPMH_VREG("smps5", "smp%s5", &pmic5_ftsmps525_lv, "vdd-s5"), + RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525_lv, "vdd-s6"), + RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525_lv, "vdd-s7"), + RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525_lv, "vdd-s8"), + RPMH_VREG("smps9", "smp%s9", &pmic5_ftsmps525_lv, "vdd-s9"), + RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps525_lv, "vdd-s10"), + RPMH_VREG("ldo1", "ldo%s1", &pmic5_nldo515, "vdd-l1"), + RPMH_VREG("ldo2", "ldo%s2", &pmic5_nldo515, "vdd-l2-18"), + RPMH_VREG("ldo3", "ldo%s3", &pmic5_nldo515, "vdd-l3"), + RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo515, "vdd-l4-l16"), + RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo_lv, "vdd-l5-l6"), + RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo_lv, "vdd-l5-l6"), + RPMH_VREG("ldo7", "ldo%s7", &pmic5_nldo515, "vdd-l7"), + RPMH_VREG("ldo8", "ldo%s8", &pmic5_nldo515, "vdd-l8-l9"), + RPMH_VREG("ldo9", "ldo%s9", &pmic5_nldo515, "vdd-l8-l9"), + RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l10"), + RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l11-l13"), + RPMH_VREG("ldo12", "ldo%s12", &pmic5_nldo515, "vdd-l12"), + RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l11-l13"), + RPMH_VREG("ldo14", "ldo%s14", &pmic5_nldo515, "vdd-l14"), + RPMH_VREG("ldo15", "ldo%s15", &pmic5_nldo515, "vdd-l15"), + RPMH_VREG("ldo16", "ldo%s16", &pmic5_nldo515, "vdd-l4-l16"), + RPMH_VREG("ldo17", "ldo%s17", &pmic5_nldo515, "vdd-l17"), + /* ldo18 not configured */ + RPMH_VREG("ldo19", "ldo%s19", &pmic5_nldo515, "vdd-l19"), + RPMH_VREG("ldo20", "ldo%s20", &pmic5_nldo515, "vdd-l20-l21"), + RPMH_VREG("ldo21", "ldo%s21", &pmic5_nldo515, "vdd-l20-l21"), +}; + static const struct rpmh_vreg_init_data pm7325_vreg_data[] = { RPMH_VREG("smps1", "smp%s1", &pmic5_hfsmps510, "vdd-s1"), RPMH_VREG("smps2", "smp%s2", &pmic5_ftsmps520, "vdd-s2"), @@ -1493,6 +1527,10 @@ static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = { .compatible = "qcom,pmx65-rpmh-regulators", .data = pmx65_vreg_data, }, + { + .compatible = "qcom,pmx75-rpmh-regulators", + .data = pmx75_vreg_data, + }, { .compatible = "qcom,pm7325-rpmh-regulators", .data = pm7325_vreg_data, -- cgit v1.2.3-70-g09d2 From 55c8b8ddc0d95912c7b0d066aaa4bbac146e3c42 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 25 Jul 2023 12:54:21 +0200 Subject: regulator: dt-bindings: mps,mpq7920: drop incorrect ref to regulator.yaml "regulators" node is just grouping regulators, but itself is not describing one regulator, thus reference to regulator.yaml schema is incorrect. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230725105421.99160-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml index f3fcfc8be72f..019c60942efc 100644 --- a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml +++ b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml @@ -21,7 +21,6 @@ properties: regulators: type: object - $ref: regulator.yaml# description: | list of regulators provided by this controller, must be named -- cgit v1.2.3-70-g09d2 From 269cb04b601dd8c35bbee180a9800335b93111fb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 14 Jul 2023 16:14:07 +0800 Subject: regulator: Use bitfield values for range selectors Right now the regulator helpers expect raw register values for the range selectors. This is different from the voltage selectors, which are normalized as bitfield values. This leads to a bit of confusion. Also, raw values are harder to copy from datasheets or match up with them, as datasheets will typically have bitfield values. Make the helpers expect bitfield values, and convert existing users. The field in regulator_desc is renamed to |linear_range_selectors_bitfield|. This is intended to cause drivers added in the same merge window and out-of-tree drivers using the incorrect variable and values to break, preventing incorrect values being used on actual hardware and potentially producing magic smoke. Also include bitops.h explicitly for ffs(), and reorder the header include statements. While at it, also replace module.h with export.h, since the only use is EXPORT_SYMBOL_GPL. Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20230714081408.274567-1-wenst@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/atc260x-regulator.c | 4 ++-- drivers/regulator/bd718x7-regulator.c | 22 +++++++++++----------- drivers/regulator/helpers.c | 15 +++++++++------ drivers/regulator/max77541-regulator.c | 6 +++--- drivers/regulator/max77650-regulator.c | 2 +- drivers/regulator/rohm-regulator.c | 2 +- drivers/regulator/tps6287x-regulator.c | 4 ++-- include/linux/regulator/driver.h | 11 ++++++----- 8 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/regulator/atc260x-regulator.c b/drivers/regulator/atc260x-regulator.c index 09fe51464090..3e9f8fd54fca 100644 --- a/drivers/regulator/atc260x-regulator.c +++ b/drivers/regulator/atc260x-regulator.c @@ -38,7 +38,7 @@ static const struct linear_range atc2609a_ldo_voltage_ranges1[] = { }; static const unsigned int atc260x_ldo_voltage_range_sel[] = { - 0x0, 0x20, + 0x0, 0x1, }; static int atc260x_dcdc_set_voltage_time_sel(struct regulator_dev *rdev, @@ -428,7 +428,7 @@ enum atc2609a_reg_ids { .vsel_mask = GENMASK(4, 1), \ .vsel_range_reg = ATC2609A_PMU_LDO##num##_CTL0, \ .vsel_range_mask = BIT(5), \ - .linear_range_selectors = atc260x_ldo_voltage_range_sel, \ + .linear_range_selectors_bitfield = atc260x_ldo_voltage_range_sel, \ .enable_reg = ATC2609A_PMU_LDO##num##_CTL0, \ .enable_mask = BIT(0), \ .enable_time = 2000, \ diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index b0b9938c20a1..c3fb05dce40c 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -289,7 +289,7 @@ static const struct linear_range bd71837_buck5_volts[] = { * and 0x1 for last 3 ranges. */ static const unsigned int bd71837_buck5_volt_range_sel[] = { - 0x0, 0x0, 0x0, 0x80, 0x80, 0x80 + 0x0, 0x0, 0x0, 0x1, 0x1, 0x1 }; /* @@ -309,7 +309,7 @@ static const struct linear_range bd71847_buck3_volts[] = { }; static const unsigned int bd71847_buck3_volt_range_sel[] = { - 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80 + 0x0, 0x0, 0x0, 0x1, 0x2, 0x2, 0x2 }; static const struct linear_range bd71847_buck4_volts[] = { @@ -317,7 +317,7 @@ static const struct linear_range bd71847_buck4_volts[] = { REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000), }; -static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 }; +static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x1 }; /* * BUCK6 @@ -360,7 +360,7 @@ static const struct linear_range bd718xx_ldo1_volts[] = { REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000), }; -static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 }; +static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x1 }; /* * LDO2 @@ -403,7 +403,7 @@ static const struct linear_range bd71847_ldo5_volts[] = { REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000), }; -static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 }; +static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x1 }; /* * LDO6 @@ -817,7 +817,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK, .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, .vsel_range_mask = BD71847_BUCK3_RANGE_MASK, - .linear_range_selectors = bd71847_buck3_volt_range_sel, + .linear_range_selectors_bitfield = bd71847_buck3_volt_range_sel, .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, .enable_time = BD71847_BUCK3_STARTUP_TIME, @@ -845,7 +845,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { .vsel_mask = BD71847_BUCK4_MASK, .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT, .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, - .linear_range_selectors = bd71847_buck4_volt_range_sel, + .linear_range_selectors_bitfield = bd71847_buck4_volt_range_sel, .enable_mask = BD718XX_BUCK_EN, .enable_time = BD71847_BUCK4_STARTUP_TIME, .owner = THIS_MODULE, @@ -916,7 +916,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { .vsel_mask = BD718XX_LDO1_MASK, .vsel_range_reg = BD718XX_REG_LDO1_VOLT, .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, - .linear_range_selectors = bd718xx_ldo1_volt_range_sel, + .linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel, .enable_reg = BD718XX_REG_LDO1_VOLT, .enable_mask = BD718XX_LDO_EN, .enable_time = BD71847_LDO1_STARTUP_TIME, @@ -1010,7 +1010,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { .vsel_mask = BD71847_LDO5_MASK, .vsel_range_reg = BD718XX_REG_LDO5_VOLT, .vsel_range_mask = BD71847_LDO5_RANGE_MASK, - .linear_range_selectors = bd71847_ldo5_volt_range_sel, + .linear_range_selectors_bitfield = bd71847_ldo5_volt_range_sel, .enable_reg = BD718XX_REG_LDO5_VOLT, .enable_mask = BD718XX_LDO_EN, .enable_time = BD71847_LDO5_STARTUP_TIME, @@ -1232,7 +1232,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { .vsel_mask = BD71837_BUCK5_MASK, .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT, .vsel_range_mask = BD71837_BUCK5_RANGE_MASK, - .linear_range_selectors = bd71837_buck5_volt_range_sel, + .linear_range_selectors_bitfield = bd71837_buck5_volt_range_sel, .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, .enable_time = BD71837_BUCK5_STARTUP_TIME, @@ -1328,7 +1328,7 @@ static struct bd718xx_regulator_data bd71837_regulators[] = { .vsel_mask = BD718XX_LDO1_MASK, .vsel_range_reg = BD718XX_REG_LDO1_VOLT, .vsel_range_mask = BD718XX_LDO1_RANGE_MASK, - .linear_range_selectors = bd718xx_ldo1_volt_range_sel, + .linear_range_selectors_bitfield = bd718xx_ldo1_volt_range_sel, .enable_reg = BD718XX_REG_LDO1_VOLT, .enable_mask = BD718XX_LDO_EN, .enable_time = BD71837_LDO1_STARTUP_TIME, diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c index e6c999ba3fa2..5ad5f3b3a6b5 100644 --- a/drivers/regulator/helpers.c +++ b/drivers/regulator/helpers.c @@ -5,13 +5,14 @@ // Copyright 2007, 2008 Wolfson Microelectronics PLC. // Copyright 2008 SlimLogic Ltd. -#include -#include +#include #include +#include +#include +#include #include #include #include -#include #include "internal.h" @@ -104,13 +105,14 @@ static int regulator_range_selector_to_index(struct regulator_dev *rdev, { int i; - if (!rdev->desc->linear_range_selectors) + if (!rdev->desc->linear_range_selectors_bitfield) return -EINVAL; rval &= rdev->desc->vsel_range_mask; + rval >>= ffs(rdev->desc->vsel_range_mask) - 1; for (i = 0; i < rdev->desc->n_linear_ranges; i++) { - if (rdev->desc->linear_range_selectors[i] == rval) + if (rdev->desc->linear_range_selectors_bitfield[i] == rval) return i; } return -EINVAL; @@ -194,7 +196,8 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev, sel <<= ffs(rdev->desc->vsel_mask) - 1; sel += rdev->desc->linear_ranges[i].min_sel; - range = rdev->desc->linear_range_selectors[i]; + range = rdev->desc->linear_range_selectors_bitfield[i]; + range <<= ffs(rdev->desc->vsel_mask) - 1; if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) { ret = regmap_update_bits(rdev->regmap, diff --git a/drivers/regulator/max77541-regulator.c b/drivers/regulator/max77541-regulator.c index 2976f9cb3e26..e6b3d9147c37 100644 --- a/drivers/regulator/max77541-regulator.c +++ b/drivers/regulator/max77541-regulator.c @@ -44,7 +44,7 @@ static const struct linear_range max77541_buck_ranges[] = { }; static const unsigned int max77541_buck_volt_range_sel[] = { - 0x00, 0x00, 0x40, 0x40, 0x80, 0x80, + 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, }; enum max77541_regulators { @@ -67,7 +67,7 @@ enum max77541_regulators { .vsel_mask = MAX77541_BITS_MX_VOUT, \ .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \ .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \ - .linear_range_selectors = max77541_buck_volt_range_sel, \ + .linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \ .owner = THIS_MODULE, \ } @@ -86,7 +86,7 @@ enum max77541_regulators { .vsel_mask = MAX77541_BITS_MX_VOUT, \ .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \ .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \ - .linear_range_selectors = max77541_buck_volt_range_sel, \ + .linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \ .owner = THIS_MODULE, \ } diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index f6539b945037..94abfbb2bc1e 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -239,7 +239,7 @@ static struct max77650_regulator_desc max77651_SBB1_desc = { .supply_name = "in-sbb1", .id = MAX77650_REGULATOR_ID_SBB1, .ops = &max77651_SBB1_regulator_ops, - .linear_range_selectors = max77651_sbb1_volt_range_sel, + .linear_range_selectors_bitfield = max77651_sbb1_volt_range_sel, .linear_ranges = max77651_sbb1_volt_ranges, .n_linear_ranges = ARRAY_SIZE(max77651_sbb1_volt_ranges), .n_voltages = 58, diff --git a/drivers/regulator/rohm-regulator.c b/drivers/regulator/rohm-regulator.c index f97a9a51ee76..0e2418ed957c 100644 --- a/drivers/regulator/rohm-regulator.c +++ b/drivers/regulator/rohm-regulator.c @@ -36,7 +36,7 @@ static int set_dvs_level(const struct regulator_desc *desc, } for (i = 0; i < desc->n_voltages; i++) { /* NOTE to next hacker - Does not support pickable ranges */ - if (desc->linear_range_selectors) + if (desc->linear_range_selectors_bitfield) return -EINVAL; if (desc->n_linear_ranges) ret = regulator_desc_list_voltage_linear_range(desc, i); diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c index 19a4a300a963..d022184a8e7d 100644 --- a/drivers/regulator/tps6287x-regulator.c +++ b/drivers/regulator/tps6287x-regulator.c @@ -41,7 +41,7 @@ static const struct linear_range tps6287x_voltage_ranges[] = { }; static const unsigned int tps6287x_voltage_range_sel[] = { - 0x0, 0x4, 0x8, 0xC + 0x0, 0x1, 0x2, 0x3 }; static const unsigned int tps6287x_ramp_table[] = { @@ -122,7 +122,7 @@ static struct regulator_desc tps6287x_reg = { .n_voltages = 256, .linear_ranges = tps6287x_voltage_ranges, .n_linear_ranges = ARRAY_SIZE(tps6287x_voltage_ranges), - .linear_range_selectors = tps6287x_voltage_range_sel, + .linear_range_selectors_bitfield = tps6287x_voltage_range_sel, }; static int tps6287x_i2c_probe(struct i2c_client *i2c) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index c6ef7d68eb9a..4b7eceb3828b 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -292,11 +292,12 @@ enum regulator_type { * @ramp_delay: Time to settle down after voltage change (unit: uV/us) * @min_dropout_uV: The minimum dropout voltage this regulator can handle * @linear_ranges: A constant table of possible voltage ranges. - * @linear_range_selectors: A constant table of voltage range selectors. - * If pickable ranges are used each range must - * have corresponding selector here. + * @linear_range_selectors_bitfield: A constant table of voltage range + * selectors as bitfield values. If + * pickable ranges are used each range + * must have corresponding selector here. * @n_linear_ranges: Number of entries in the @linear_ranges (and in - * linear_range_selectors if used) table(s). + * linear_range_selectors_bitfield if used) table(s). * @volt_table: Voltage mapping table (if table based mapping) * @curr_table: Current limit mapping table (if table based mapping) * @@ -384,7 +385,7 @@ struct regulator_desc { int min_dropout_uV; const struct linear_range *linear_ranges; - const unsigned int *linear_range_selectors; + const unsigned int *linear_range_selectors_bitfield; int n_linear_ranges; -- cgit v1.2.3-70-g09d2 From 6b677c1ae8e4096c84fbcbe1b7fd300dab0b381b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 25 Jul 2023 17:47:43 +0200 Subject: regulator: REGULATOR_QCOM_REFGEN should depend on ARCH_QCOM The Qualcomm MMIO-mapped reference voltage regulator is only present on Qualcomm SoCs. Hence add a dependency on ARCH_QCOM, to prevent asking the user about this driver when configuring a kernel without Qualcomm SoC support. Fixes: 7cbfbe23796086fd ("regulator: Introduce Qualcomm REFGEN regulator driver") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/60938ed138c9331ba3d2891fbd3b3d6644d3fbdc.1690300012.git.geert+renesas@glider.be Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 542a7b427994..94f44736473e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1001,6 +1001,7 @@ config REGULATOR_PWM config REGULATOR_QCOM_REFGEN tristate "Qualcomm REFGEN regulator driver" + depends on ARCH_QCOM || COMPILE_TEST depends on HAS_IOMEM depends on REGMAP help -- cgit v1.2.3-70-g09d2 From 9b7e0645ba65e4824436a2f1817843291e744443 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 25 Jul 2023 14:46:27 +0200 Subject: regulator: dt-bindings: dlg,da9121: add buck2 constraints Instead of describing the constraints for some devices (buck2 not present), code it in allOf:if:then section to actually allow validation of this requirement. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230725124629.150113-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/dlg,da9121.yaml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml index dc626517c2ad..43f99bc8fbd4 100644 --- a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml +++ b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml @@ -97,8 +97,6 @@ properties: properties: regulator-name: pattern: "^BUCK([1-2])$" - description: | - BUCK2 present in DA9122, DA9220, DA9131, DA9132 only regulator-initial-mode: enum: [ 0, 1, 2, 3 ] @@ -122,6 +120,23 @@ required: - reg - regulators +allOf: + - if: + properties: + compatible: + not: + contains: + enum: + - dlg,da9122 + - dlg,da9131 + - dlg,da9132 + - dlg,da9220 + then: + properties: + regulators: + properties: + buck2: false + additionalProperties: false examples: -- cgit v1.2.3-70-g09d2 From e5481cc40d00b9f4a3250b2fd4a805e3d000b229 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 25 Jul 2023 14:46:28 +0200 Subject: regulator: dt-bindings: dlg,da9121: allow different names Regulator names, as specified by regulator-name, are board-dependent and should describe the name used on the actual board. Do not enforce generic buck1/2 names. This also fixes dtbs_check warnings like: zynqmp-sm-k26-revA.dtb: pmic@33: regulators:buck1:regulator-name:0: 'da9131_buck1' does not match '^BUCK([1-2])$' Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230725124629.150113-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/dlg,da9121.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml index 43f99bc8fbd4..13b3f75f8e5e 100644 --- a/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml +++ b/Documentation/devicetree/bindings/regulator/dlg,da9121.yaml @@ -95,9 +95,6 @@ properties: Properties for a single BUCK regulator properties: - regulator-name: - pattern: "^BUCK([1-2])$" - regulator-initial-mode: enum: [ 0, 1, 2, 3 ] description: Defined in include/dt-bindings/regulator/dlg,da9121-regulator.h -- cgit v1.2.3-70-g09d2 From 7631a0c5b093fe1bc27b4770021c4aa0d06fb3c5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 25 Jul 2023 14:46:29 +0200 Subject: regulator: dt-bindings: active-semi,act8846: correct supplies Regulator supplies are per-device, not per regulator, so they are expected to be present in device node. Moving them to proper place allows to simplify a lot, because now none of the regulators differ. This also fixes dtbs_check warnings like: rk3368-evb-act8846.dtb: act8846@5a: 'inl1-supply', 'inl2-supply', 'inl3-supply', 'vp1-supply', 'vp2-supply', 'vp3-supply', 'vp4-supply' do not match any of the regexes: 'pinctrl-[0-9]+' Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230725124629.150113-3-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../bindings/regulator/active-semi,act8846.yaml | 74 ++++++---------------- 1 file changed, 18 insertions(+), 56 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/active-semi,act8846.yaml b/Documentation/devicetree/bindings/regulator/active-semi,act8846.yaml index 3725348bb235..02f45b5834d0 100644 --- a/Documentation/devicetree/bindings/regulator/active-semi,act8846.yaml +++ b/Documentation/devicetree/bindings/regulator/active-semi,act8846.yaml @@ -28,75 +28,37 @@ properties: the VSEL pin is assumed to be low. type: boolean - regulators: - type: object - additionalProperties: false + inl1-supply: + description: Handle to the INL1 input supply (REG5-7) - properties: - REG1: - type: object - $ref: /schemas/regulator/regulator.yaml# - unevaluatedProperties: false + inl2-supply: + description: Handle to the INL2 input supply (REG8-9) - properties: - vp1-supply: - description: Handle to the VP1 input supply + inl3-supply: + description: Handle to the INL3 input supply (REG10-12) - REG2: - type: object - $ref: /schemas/regulator/regulator.yaml# - unevaluatedProperties: false + vp1-supply: + description: Handle to the VP1 input supply (REG1) - properties: - vp2-supply: - description: Handle to the VP2 input supply + vp2-supply: + description: Handle to the VP2 input supply (REG2) - REG3: - type: object - $ref: /schemas/regulator/regulator.yaml# - unevaluatedProperties: false + vp3-supply: + description: Handle to the VP3 input supply (REG3) - properties: - vp3-supply: - description: Handle to the VP3 input supply - - REG4: - type: object - $ref: /schemas/regulator/regulator.yaml# - unevaluatedProperties: false + vp4-supply: + description: Handle to the VP4 input supply (REG4) - properties: - vp4-supply: - description: Handle to the VP4 input supply + regulators: + type: object + additionalProperties: false patternProperties: - "^REG[5-7]$": + "^REG([1-9]|1[0-2])$": type: object $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false - properties: - inl1-supply: - description: Handle to the INL1 input supply - - "^REG[8-9]$": - type: object - $ref: /schemas/regulator/regulator.yaml# - unevaluatedProperties: false - - properties: - inl2-supply: - description: Handle to the INL2 input supply - - "^REG1[0-2]$": - type: object - $ref: /schemas/regulator/regulator.yaml# - unevaluatedProperties: false - - properties: - inl3-supply: - description: Handle to the INL3 input supply - additionalProperties: false required: -- cgit v1.2.3-70-g09d2 From 75d9bf03e2fa38242b35e941ce7c7cdabe479961 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 25 Jul 2023 18:40:47 +0200 Subject: regulator: dt-bindings: qcom,rpm: fix pattern for children The "or" (|) in regular expression must be within parentheses, otherwise it is not really an "or" and it matches supplies: qcom-apq8060-dragonboard.dtb: regulators-1: vdd_ncp-supply: [[34]] is not of type 'object' Fixes: fde0e25b71a9 ("dt-bindings: regulators: convert non-smd RPM Regulators bindings to dt-schema") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230725164047.368892-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,rpm-regulator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpm-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpm-regulator.yaml index 8a08698e3484..b4eb4001eb3d 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpm-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpm-regulator.yaml @@ -49,7 +49,7 @@ patternProperties: ".*-supply$": description: Input supply phandle(s) for this node - "^((s|l|lvs)[0-9]*)|(s[1-2][a-b])|(ncp)|(mvs)|(usb-switch)|(hdmi-switch)$": + "^((s|l|lvs)[0-9]*|s[1-2][a-b]|ncp|mvs|usb-switch|hdmi-switch)$": description: List of regulators and its properties $ref: regulator.yaml# unevaluatedProperties: false -- cgit v1.2.3-70-g09d2 From d2d54819779e1ec0d7908ec98220fa54e72adc48 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 26 Jul 2023 09:49:40 +0200 Subject: regulator: dt-bindings: add missing unevaluatedProperties for each regulator Each regulator node, which references common regulator.yaml schema, should disallow additional or unevaluated properties. Otherwise mistakes in properties will go unnoticed. Reported-by: Konrad Dybcio Closes: https://git.codelinaro.org/linaro/qcomlt/kernel/-/commit/1c8aeef8a6e84520b77f0c270d99c8bf692c5933 Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230726074940.121040-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/mps,mp5416.yaml | 2 ++ Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml | 2 ++ Documentation/devicetree/bindings/regulator/pfuze100.yaml | 4 ++++ Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml | 2 ++ .../devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml | 1 + .../devicetree/bindings/regulator/richtek,rt4831-regulator.yaml | 1 + .../devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml | 1 + .../devicetree/bindings/regulator/richtek,rtq6752-regulator.yaml | 1 + Documentation/devicetree/bindings/regulator/st,stm32mp1-pwr-reg.yaml | 2 +- Documentation/devicetree/bindings/regulator/wlf,arizona.yaml | 2 ++ 10 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml b/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml index 2e720d152890..0221397eb51e 100644 --- a/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml +++ b/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml @@ -29,10 +29,12 @@ properties: patternProperties: "^buck[1-4]$": $ref: regulator.yaml# + unevaluatedProperties: false type: object "^ldo[1-4]$": $ref: regulator.yaml# + unevaluatedProperties: false type: object additionalProperties: false diff --git a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml index 019c60942efc..6de5b027f990 100644 --- a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml +++ b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml @@ -38,11 +38,13 @@ properties: ldortc: type: object $ref: regulator.yaml# + unevaluatedProperties: false patternProperties: "^ldo[1-4]$": type: object $ref: regulator.yaml# + unevaluatedProperties: false "^buck[1-4]$": type: object diff --git a/Documentation/devicetree/bindings/regulator/pfuze100.yaml b/Documentation/devicetree/bindings/regulator/pfuze100.yaml index e384e4953f0a..0eda44752cdd 100644 --- a/Documentation/devicetree/bindings/regulator/pfuze100.yaml +++ b/Documentation/devicetree/bindings/regulator/pfuze100.yaml @@ -68,18 +68,22 @@ properties: "^sw([1-4]|[1-4][a-c]|[1-4][a-c][a-c])$": $ref: regulator.yaml# type: object + unevaluatedProperties: false "^vgen[1-6]$": $ref: regulator.yaml# type: object + unevaluatedProperties: false "^vldo[1-4]$": $ref: regulator.yaml# type: object + unevaluatedProperties: false "^(vsnvs|vref|vrefddr|swbst|coin|v33|vccsd)$": $ref: regulator.yaml# type: object + unevaluatedProperties: false additionalProperties: false diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index 72b533c3761a..e758093365bc 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -111,6 +111,7 @@ properties: bob: type: object $ref: regulator.yaml# + unevaluatedProperties: false description: BOB regulator node. dependencies: regulator-allow-set-load: [ regulator-allowed-modes ] @@ -119,6 +120,7 @@ patternProperties: "^(smps|ldo|lvs|bob)[0-9]+$": type: object $ref: regulator.yaml# + unevaluatedProperties: false description: smps/ldo regulator nodes(s). dependencies: regulator-allow-set-load: [ regulator-allowed-modes ] diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml index a8ca8e0b27f8..9ea8ac0786ac 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml @@ -110,6 +110,7 @@ patternProperties: "^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$": description: List of regulators and its properties $ref: regulator.yaml# + unevaluatedProperties: false additionalProperties: false diff --git a/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml index d9c23333e157..cd06e957b9db 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml @@ -29,6 +29,7 @@ patternProperties: "^DSV(LCM|P|N)$": type: object $ref: regulator.yaml# + unevaluatedProperties: false description: Properties for single Display Bias Voltage regulator. diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml index 446ec5127d1f..fec3d396ca50 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml @@ -121,6 +121,7 @@ properties: description: load switch current regulator description. type: object $ref: regulator.yaml# + unevaluatedProperties: false required: - compatible diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq6752-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq6752-regulator.yaml index e6e5a9a7d940..ef62c618de67 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rtq6752-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rtq6752-regulator.yaml @@ -35,6 +35,7 @@ properties: "^(p|n)avdd$": type: object $ref: regulator.yaml# + unevaluatedProperties: false description: | regulator description for pavdd and navdd. diff --git a/Documentation/devicetree/bindings/regulator/st,stm32mp1-pwr-reg.yaml b/Documentation/devicetree/bindings/regulator/st,stm32mp1-pwr-reg.yaml index 7d53cfa2c288..c9586d277f41 100644 --- a/Documentation/devicetree/bindings/regulator/st,stm32mp1-pwr-reg.yaml +++ b/Documentation/devicetree/bindings/regulator/st,stm32mp1-pwr-reg.yaml @@ -25,8 +25,8 @@ properties: patternProperties: "^(reg11|reg18|usb33)$": type: object - $ref: regulator.yaml# + unevaluatedProperties: false required: - compatible diff --git a/Documentation/devicetree/bindings/regulator/wlf,arizona.yaml b/Documentation/devicetree/bindings/regulator/wlf,arizona.yaml index 011819c10988..11e378648b3f 100644 --- a/Documentation/devicetree/bindings/regulator/wlf,arizona.yaml +++ b/Documentation/devicetree/bindings/regulator/wlf,arizona.yaml @@ -29,11 +29,13 @@ properties: Initial data for the LDO1 regulator. $ref: regulator.yaml# type: object + unevaluatedProperties: false micvdd: description: Initial data for the MICVDD regulator. $ref: regulator.yaml# type: object + unevaluatedProperties: false additionalProperties: true -- cgit v1.2.3-70-g09d2 From cfef69cbe3726c095f55769bd0e7c72f32bf5060 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Jul 2023 10:54:34 +0200 Subject: regulator: dt-bindings: dlg,slg51000: Convert to DT schema Convert the bindings for Dialog Semiconductor SLG51000 Voltage Regulator to DT schema. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230727085434.16596-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../bindings/regulator/dlg,slg51000.yaml | 132 +++++++++++++++++++++ .../devicetree/bindings/regulator/slg51000.txt | 88 -------------- MAINTAINERS | 2 +- 3 files changed, 133 insertions(+), 89 deletions(-) create mode 100644 Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml delete mode 100644 Documentation/devicetree/bindings/regulator/slg51000.txt diff --git a/Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml b/Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml new file mode 100644 index 000000000000..bad140418e49 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/dlg,slg51000.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Dialog Semiconductor SLG51000 Voltage Regulator + +maintainers: + - Eric Jeong + - Support Opensource + +properties: + compatible: + const: dlg,slg51000 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + dlg,cs-gpios: + maxItems: 1 + description: + GPIO for chip select + + vin3-supply: + description: + Input supply for ldo3, required if regulator is enabled + + vin4-supply: + description: + Input supply for ldo4, required if regulator is enabled + + vin5-supply: + description: + Input supply for ldo5, required if regulator is enabled + + vin6-supply: + description: + Input supply for ldo6, required if regulator is enabled + + vin7-supply: + description: + Input supply for ldo7, required if regulator is enabled + + regulators: + type: object + additionalProperties: false + + patternProperties: + "^ldo[1-7]$": + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + properties: + enable-gpios: + maxItems: 1 + + required: + - regulator-name + +required: + - compatible + - reg + - regulators + +additionalProperties: false + +examples: + - | + #include + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@75 { + compatible = "dlg,slg51000"; + reg = <0x75>; + dlg,cs-gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>; + vin5-supply = <&vreg_s1f_1p2>; + vin6-supply = <&vreg_s1f_1p2>; + + regulators { + ldo1 { + regulator-name = "slg51000_b_ldo1"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3300000>; + }; + + ldo2 { + regulator-name = "slg51000_b_ldo2"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3300000>; + }; + + ldo3 { + regulator-name = "slg51000_b_ldo3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3750000>; + }; + + ldo4 { + regulator-name = "slg51000_b_ldo4"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3750000>; + }; + + ldo5 { + regulator-name = "slg51000_b_ldo5"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1200000>; + }; + + ldo6 { + regulator-name = "slg51000_b_ldo6"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1200000>; + }; + + ldo7 { + regulator-name = "slg51000_b_ldo7"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3750000>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/slg51000.txt b/Documentation/devicetree/bindings/regulator/slg51000.txt deleted file mode 100644 index aa0733e49b90..000000000000 --- a/Documentation/devicetree/bindings/regulator/slg51000.txt +++ /dev/null @@ -1,88 +0,0 @@ -* Dialog Semiconductor SLG51000 Voltage Regulator - -Required properties: -- compatible : Should be "dlg,slg51000" for SLG51000 -- reg : Specifies the I2C slave address. -- xxx-supply: Input voltage supply regulator for ldo3 to ldo7. - These entries are required if regulators are enabled for a device. - An absence of these properties can cause the regulator registration to fail. - If some of input supply is powered through battery or always-on supply then - also it is required to have these parameters with proper node handle of always - on power supply. - vin3-supply: Input supply for ldo3 - vin4-supply: Input supply for ldo4 - vin5-supply: Input supply for ldo5 - vin6-supply: Input supply for ldo6 - vin7-supply: Input supply for ldo7 - -Optional properties: -- interrupt-parent : Specifies the reference to the interrupt controller. -- interrupts : IRQ line information. -- dlg,cs-gpios : Specify a valid GPIO for chip select - -Sub-nodes: -- regulators : This node defines the settings for the regulators. - The content of the sub-node is defined by the standard binding - for regulators; see regulator.txt. - - The SLG51000 regulators are bound using their names listed below: - ldo1 - ldo2 - ldo3 - ldo4 - ldo5 - ldo6 - ldo7 - -Optional properties for regulators: -- enable-gpios : Specify a valid GPIO for platform control of the regulator. - -Example: - pmic: slg51000@75 { - compatible = "dlg,slg51000"; - reg = <0x75>; - - regulators { - ldo1 { - regulator-name = "ldo1"; - regulator-min-microvolt = <2400000>; - regulator-max-microvolt = <3300000>; - }; - - ldo2 { - regulator-name = "ldo2"; - regulator-min-microvolt = <2400000>; - regulator-max-microvolt = <3300000>; - }; - - ldo3 { - regulator-name = "ldo3"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3750000>; - }; - - ldo4 { - regulator-name = "ldo4"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3750000>; - }; - - ldo5 { - regulator-name = "ldo5"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1200000>; - }; - - ldo6 { - regulator-name = "ldo6"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1200000>; - }; - - ldo7 { - regulator-name = "ldo7"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3750000>; - }; - }; - }; diff --git a/MAINTAINERS b/MAINTAINERS index d516295978a4..7ff9b94ac3ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6010,7 +6010,7 @@ F: Documentation/devicetree/bindings/mfd/da90*.txt F: Documentation/devicetree/bindings/mfd/dlg,da90*.yaml F: Documentation/devicetree/bindings/regulator/da92*.txt F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml -F: Documentation/devicetree/bindings/regulator/slg51000.txt +F: Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml F: Documentation/devicetree/bindings/sound/da[79]*.txt F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt F: Documentation/devicetree/bindings/watchdog/da90??-wdt.txt -- cgit v1.2.3-70-g09d2 From 39b5ba6cb56962d2ac83e4dd89f68538f7861efe Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 1 Aug 2023 21:03:54 +0800 Subject: regulator: max77857: change some variables to static max77857_regmap_config and max77857_driver are only used in max77857-regulator.c now, change them to static. Fixes: af71cccadeced ("regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator Support") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230801130354.552243-1-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/max77857-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c index 58f825d8d2b0..f2141b5be780 100644 --- a/drivers/regulator/max77857-regulator.c +++ b/drivers/regulator/max77857-regulator.c @@ -67,7 +67,7 @@ static bool max77857_volatile_reg(struct device *dev, unsigned int reg) } } -struct regmap_config max77857_regmap_config = { +static struct regmap_config max77857_regmap_config = { .reg_bits = 8, .val_bits = 8, .cache_type = REGCACHE_MAPLE, @@ -443,7 +443,7 @@ static const struct of_device_id max77857_of_id[] = { }; MODULE_DEVICE_TABLE(of, max77857_of_id); -struct i2c_driver max77857_driver = { +static struct i2c_driver max77857_driver = { .driver = { .name = "max77857", .of_match_table = max77857_of_id, -- cgit v1.2.3-70-g09d2 From 22475bcc2083196544fa55b861d76e0e7ee9da11 Mon Sep 17 00:00:00 2001 From: Naresh Solanki Date: Thu, 3 Aug 2023 13:12:25 +0200 Subject: regulator: userspace-consumer: Add regulator event support Add sysfs attribute to track regulator events received from regulator notifier block handler. Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20230803111225.107572-1-Naresh.Solanki@9elements.com Signed-off-by: Mark Brown --- drivers/regulator/userspace-consumer.c | 52 +++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c index 97f075ed68c9..a0b980022993 100644 --- a/drivers/regulator/userspace-consumer.c +++ b/drivers/regulator/userspace-consumer.c @@ -29,6 +29,10 @@ struct userspace_consumer_data { int num_supplies; struct regulator_bulk_data *supplies; + + struct kobject *kobj; + struct notifier_block nb; + unsigned long events; }; static ssize_t name_show(struct device *dev, @@ -89,12 +93,30 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, return count; } +static DEFINE_MUTEX(events_lock); + +static ssize_t events_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct userspace_consumer_data *data = dev_get_drvdata(dev); + unsigned long e; + + mutex_lock(&events_lock); + e = data->events; + data->events = 0; + mutex_unlock(&events_lock); + + return sprintf(buf, "0x%lx\n", e); +} + static DEVICE_ATTR_RO(name); static DEVICE_ATTR_RW(state); +static DEVICE_ATTR_RO(events); static struct attribute *attributes[] = { &dev_attr_name.attr, &dev_attr_state.attr, + &dev_attr_events.attr, NULL, }; @@ -115,12 +137,28 @@ static const struct attribute_group attr_group = { .is_visible = attr_visible, }; +static int regulator_userspace_notify(struct notifier_block *nb, + unsigned long event, + void *ignored) +{ + struct userspace_consumer_data *data = + container_of(nb, struct userspace_consumer_data, nb); + + mutex_lock(&events_lock); + data->events |= event; + mutex_unlock(&events_lock); + + sysfs_notify(data->kobj, NULL, dev_attr_events.attr.name); + + return NOTIFY_OK; +} + static int regulator_userspace_consumer_probe(struct platform_device *pdev) { struct regulator_userspace_consumer_data tmpdata; struct regulator_userspace_consumer_data *pdata; struct userspace_consumer_data *drvdata; - int ret; + int i, ret; pdata = dev_get_platdata(&pdev->dev); if (!pdata) { @@ -153,6 +191,7 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) drvdata->num_supplies = pdata->num_supplies; drvdata->supplies = pdata->supplies; drvdata->no_autoswitch = pdata->no_autoswitch; + drvdata->kobj = &pdev->dev.kobj; mutex_init(&drvdata->lock); @@ -186,6 +225,13 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) } drvdata->enabled = !!ret; + drvdata->nb.notifier_call = regulator_userspace_notify; + for (i = 0; i < drvdata->num_supplies; i++) { + ret = devm_regulator_register_notifier(drvdata->supplies[i].consumer, &drvdata->nb); + if (ret) + goto err_enable; + } + return 0; err_enable: @@ -197,6 +243,10 @@ err_enable: static int regulator_userspace_consumer_remove(struct platform_device *pdev) { struct userspace_consumer_data *data = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < data->num_supplies; i++) + devm_regulator_unregister_notifier(data->supplies[i].consumer, &data->nb); sysfs_remove_group(&pdev->dev.kobj, &attr_group); -- cgit v1.2.3-70-g09d2 From 93083725e1ed86c07ea9846bb573b9340985853f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 3 Aug 2023 19:36:54 +0800 Subject: regulator: max77857: fix build error in max77857-regulator.c When using low verion gcc(7.5) to build the max77857-regulator driver, got the following error: drivers/regulator/max77857-regulator.c:312:16: error: initializer element is not constant .ramp_delay = max77857_ramp_table[0][0], To fix this by introducing a macro RAMAP_DELAY_INIT_VAL to define the value of max77857_ramp_table[0[0]. Fixes: af71cccadece ("regulator: max77857: Add ADI MAX77857/59/MAX77831 Regulator Support") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20230803113654.818640-1-yangyingliang@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/max77857-regulator.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c index f2141b5be780..44a510547318 100644 --- a/drivers/regulator/max77857-regulator.c +++ b/drivers/regulator/max77857-regulator.c @@ -293,8 +293,10 @@ static const unsigned int max77857_switch_freq[] = { 1200000, 1500000, 1800000, 2100000 }; +#define RAMAP_DELAY_INIT_VAL 1333 + static const unsigned int max77857_ramp_table[2][4] = { - { 1333, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */ + { RAMAP_DELAY_INIT_VAL, 667, 333, 227 }, /* when switch freq is 1.8MHz or 2.1MHz */ { 1166, 667, 333, 167 }, /* when switch freq is 1.2MHz or 1.5MHz */ }; @@ -309,7 +311,7 @@ static struct regulator_desc max77857_regulator_desc = { .n_ramp_values = ARRAY_SIZE(max77857_ramp_table[0]), .ramp_reg = MAX77857_REG_CONT3, .ramp_mask = GENMASK(1, 0), - .ramp_delay = max77857_ramp_table[0][0], + .ramp_delay = RAMAP_DELAY_INIT_VAL, .owner = THIS_MODULE, }; -- cgit v1.2.3-70-g09d2 From 4b591ed6971191134e331f02300b4ec4dee188ea Mon Sep 17 00:00:00 2001 From: Alina Yu Date: Mon, 7 Aug 2023 14:28:06 +0800 Subject: regulator: dt-bindings: rtq2208: Add Richtek RTQ2208 SubPMIC Add bindings for Richtek RTQ2208 IC controlled SubPMIC Signed-off-by: Alina Yu Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1691389687-31211-2-git-send-email-alina_yu@richtek.com Signed-off-by: Mark Brown --- .../bindings/regulator/richtek,rtq2208.yaml | 197 +++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml new file mode 100644 index 000000000000..609c06615bdc --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml @@ -0,0 +1,197 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/richtek,rtq2208.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Richtek RTQ2208 SubPMIC Regulator + +maintainers: + - Alina Yu + +description: | + RTQ2208 is a highly integrated power converter that offers functional safety dual + multi-configurable synchronous buck converters and two LDOs. + + Bucks support "regulator-allowed-modes" and "regulator-mode". The former defines the permitted + switching operation in normal mode; the latter defines the operation in suspend to RAM mode. + + No matter the RTQ2208 is configured to normal or suspend to RAM mode, there are two switching + operation modes for all buck rails, automatic power saving mode (Auto mode) and forced continuous + conduction mode (FCCM). + + The definition of modes is in the datasheet which is available in below link + and their meaning is:: + 0 - Auto mode for power saving, which reducing the switching frequency at light load condition + to maintain high frequency. + 1 - FCCM to meet the strict voltage regulation accuracy, which keeping constant switching frequency. + + Datasheet will be available soon at + https://www.richtek.com/assets/Products + +properties: + compatible: + enum: + - richtek,rtq2208 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + richtek,mtp-sel-high: + type: boolean + description: + vout register selection based on this boolean value. + false - Using DVS0 register setting to adjust vout + true - Using DVS1 register setting to adjust vout + + regulators: + type: object + additionalProperties: false + + patternProperties: + "^buck-[a-h]$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + description: + description for buck-[a-h] regulator. + + properties: + regulator-allowed-modes: + description: + two buck modes in different switching accuracy. + 0 - Auto mode + 1 - FCCM + items: + enum: [0, 1] + + "^ldo[1-2]$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + description: + regulator description for ldo[1-2]. + +required: + - compatible + - reg + - regulators + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@10 { + compatible = "richtek,rtq2208"; + reg = <0x10>; + interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>; + richtek,mtp-sel-high; + + regulators { + buck-a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-b { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-c { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-d { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-e { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-f { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-g { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + buck-h { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <2050000>; + regulator-allowed-modes = <0 1>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-mode = <1>; + }; + }; + ldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + ldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; + }; -- cgit v1.2.3-70-g09d2 From 85a11f55621a0c18b22b43ab4219450ac1d19386 Mon Sep 17 00:00:00 2001 From: Alina Yu Date: Mon, 7 Aug 2023 14:28:07 +0800 Subject: regulator: rtq2208: Add Richtek RTQ2208 SubPMIC driver Add support for the RTQ2208 SubPMIC This ic integrates with configurable, synchrnous buck converters and two ldos. Signed-off-by: Alina Yu Link: https://lore.kernel.org/r/1691389687-31211-3-git-send-email-alina_yu@richtek.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 11 + drivers/regulator/Makefile | 1 + drivers/regulator/rtq2208-regulator.c | 583 ++++++++++++++++++++++++++++++++++ 3 files changed, 595 insertions(+) create mode 100644 drivers/regulator/rtq2208-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 94f44736473e..bf4b5b07e09e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1254,6 +1254,17 @@ config REGULATOR_RTQ6752 synchronous boost converters for PAVDD, and one synchronous NAVDD buck-boost. This device is suitable for automotive TFT-LCD panel. +config REGULATOR_RTQ2208 + tristate "Richtek RTQ2208 SubPMIC Regulator" + depends on I2C + select REGMAP_I2C + help + This driver adds support for RTQ2208 SubPMIC regulators. + The RTQ2208 is a multi-phase, programmable power management IC that + integrate with dual multi-configurable, synchronous buck converters + and two ldos. It features wide output voltage range from 0.4V to 2.05V + and the capability to configure the corresponding power stages. + config REGULATOR_S2MPA01 tristate "Samsung S2MPA01 voltage regulator" depends on MFD_SEC_CORE || COMPILE_TEST diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 77b22bdd2791..67468cfcc4f3 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -147,6 +147,7 @@ obj-$(CONFIG_REGULATOR_RT6245) += rt6245-regulator.o obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o obj-$(CONFIG_REGULATOR_RTQ2134) += rtq2134-regulator.o obj-$(CONFIG_REGULATOR_RTQ6752) += rtq6752-regulator.o +obj-$(CONFIG_REGULATOR_RTQ2208) += rtq2208-regulator.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c new file mode 100644 index 000000000000..2463aea4192c --- /dev/null +++ b/drivers/regulator/rtq2208-regulator.c @@ -0,0 +1,583 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register */ +#define RTQ2208_REG_GLOBAL_INT1 0x12 +#define RTQ2208_REG_FLT_RECORDBUCK_CB 0x18 +#define RTQ2208_REG_GLOBAL_INT1_MASK 0x1D +#define RTQ2208_REG_FLT_MASKBUCK_CB 0x1F +#define RTQ2208_REG_BUCK_C_CFG0 0x32 +#define RTQ2208_REG_BUCK_B_CFG0 0x42 +#define RTQ2208_REG_BUCK_A_CFG0 0x52 +#define RTQ2208_REG_BUCK_D_CFG0 0x62 +#define RTQ2208_REG_BUCK_G_CFG0 0x72 +#define RTQ2208_REG_BUCK_F_CFG0 0x82 +#define RTQ2208_REG_BUCK_E_CFG0 0x92 +#define RTQ2208_REG_BUCK_H_CFG0 0xA2 +#define RTQ2208_REG_LDO1_CFG 0xB1 +#define RTQ2208_REG_LDO2_CFG 0xC1 + +/* Mask */ +#define RTQ2208_BUCK_NR_MTP_SEL_MASK GENMASK(7, 0) +#define RTQ2208_BUCK_EN_NR_MTP_SEL0_MASK BIT(0) +#define RTQ2208_BUCK_EN_NR_MTP_SEL1_MASK BIT(1) +#define RTQ2208_BUCK_RSPUP_MASK GENMASK(6, 4) +#define RTQ2208_BUCK_RSPDN_MASK GENMASK(2, 0) +#define RTQ2208_BUCK_NRMODE_MASK BIT(5) +#define RTQ2208_BUCK_STRMODE_MASK BIT(5) +#define RTQ2208_BUCK_EN_STR_MASK BIT(0) +#define RTQ2208_LDO_EN_STR_MASK BIT(7) +#define RTQ2208_EN_DIS_MASK BIT(0) +#define RTQ2208_BUCK_RAMP_SEL_MASK GENMASK(2, 0) +#define RTQ2208_HD_INT_MASK BIT(0) + +/* Size */ +#define RTQ2208_VOUT_MAXNUM 256 +#define RTQ2208_BUCK_NUM_IRQ_REGS 5 +#define RTQ2208_STS_NUM_IRQ_REGS 2 + +/* Value */ +#define RTQ2208_RAMP_VALUE_MIN_uV 500 +#define RTQ2208_RAMP_VALUE_MAX_uV 64000 + +#define RTQ2208_BUCK_MASK(uv_irq, ov_irq) (1 << ((uv_irq) % 8) | 1 << ((ov_irq) % 8)) + +enum { + RTQ2208_BUCK_B = 0, + RTQ2208_BUCK_C, + RTQ2208_BUCK_D, + RTQ2208_BUCK_A, + RTQ2208_BUCK_F, + RTQ2208_BUCK_G, + RTQ2208_BUCK_H, + RTQ2208_BUCK_E, + RTQ2208_LDO2, + RTQ2208_LDO1, + RTQ2208_LDO_MAX, +}; + +enum { + RTQ2208_AUTO_MODE = 0, + RTQ2208_FCCM, +}; + +struct rtq2208_regulator_desc { + struct regulator_desc desc; + unsigned int mtp_sel_reg; + unsigned int mtp_sel_mask; + unsigned int mode_reg; + unsigned int mode_mask; + unsigned int suspend_config_reg; + unsigned int suspend_enable_mask; + unsigned int suspend_mode_mask; +}; + +struct rtq2208_rdev_map { + struct regulator_dev *rdev[RTQ2208_LDO_MAX]; + struct regmap *regmap; + struct device *dev; +}; + +/* set Normal Auto/FCCM mode */ +static int rtq2208_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + const struct rtq2208_regulator_desc *rdesc = + (const struct rtq2208_regulator_desc *)rdev->desc; + unsigned int val, shift; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + val = RTQ2208_AUTO_MODE; + break; + case REGULATOR_MODE_FAST: + val = RTQ2208_FCCM; + break; + default: + return -EINVAL; + } + + shift = ffs(rdesc->mode_mask) - 1; + return regmap_update_bits(rdev->regmap, rdesc->mode_reg, + rdesc->mode_mask, val << shift); +} + +static unsigned int rtq2208_get_mode(struct regulator_dev *rdev) +{ + const struct rtq2208_regulator_desc *rdesc = + (const struct rtq2208_regulator_desc *)rdev->desc; + unsigned int mode_val; + int ret; + + ret = regmap_read(rdev->regmap, rdesc->mode_reg, &mode_val); + if (ret) + return REGULATOR_MODE_INVALID; + + return (mode_val & rdesc->mode_mask) ? REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; +} + +static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) +{ + const struct regulator_desc *desc = rdev->desc; + unsigned int sel = 0, val; + + ramp_delay = max(ramp_delay, RTQ2208_RAMP_VALUE_MIN_uV); + ramp_delay = min(ramp_delay, RTQ2208_RAMP_VALUE_MAX_uV); + + ramp_delay /= RTQ2208_RAMP_VALUE_MIN_uV; + + /* + * fls(ramp_delay) - 1: doing LSB shift, let it starts from 0 + * + * RTQ2208_BUCK_RAMP_SEL_MASK - sel: doing descending order shifting. + * Because the relation of seleltion and value is like that + * + * seletion: value + * 000: 64mv + * 001: 32mv + * ... + * 111: 0.5mv + * + * For example, if I would like to select 64mv, the fls(ramp_delay) - 1 will be 0b111, + * and I need to use 0b111 - sel to do the shifting + */ + + sel = fls(ramp_delay) - 1; + sel = RTQ2208_BUCK_RAMP_SEL_MASK - sel; + + val = FIELD_PREP(RTQ2208_BUCK_RSPUP_MASK, sel) | FIELD_PREP(RTQ2208_BUCK_RSPDN_MASK, sel); + + return regmap_update_bits(rdev->regmap, desc->ramp_reg, + RTQ2208_BUCK_RSPUP_MASK | RTQ2208_BUCK_RSPDN_MASK, val); +} + +static int rtq2208_set_suspend_enable(struct regulator_dev *rdev) +{ + const struct rtq2208_regulator_desc *rdesc = + (const struct rtq2208_regulator_desc *)rdev->desc; + + return regmap_set_bits(rdev->regmap, rdesc->suspend_config_reg, rdesc->suspend_enable_mask); +} + +static int rtq2208_set_suspend_disable(struct regulator_dev *rdev) +{ + const struct rtq2208_regulator_desc *rdesc = + (const struct rtq2208_regulator_desc *)rdev->desc; + + return regmap_update_bits(rdev->regmap, rdesc->suspend_config_reg, rdesc->suspend_enable_mask, 0); +} + +static int rtq2208_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode) +{ + const struct rtq2208_regulator_desc *rdesc = + (const struct rtq2208_regulator_desc *)rdev->desc; + unsigned int val, shift; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + val = RTQ2208_AUTO_MODE; + break; + case REGULATOR_MODE_FAST: + val = RTQ2208_FCCM; + break; + default: + return -EINVAL; + } + + shift = ffs(rdesc->suspend_mode_mask) - 1; + + return regmap_update_bits(rdev->regmap, rdesc->suspend_config_reg, + rdesc->suspend_mode_mask, val << shift); +} + +static const struct regulator_ops rtq2208_regulator_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_mode = rtq2208_set_mode, + .get_mode = rtq2208_get_mode, + .set_ramp_delay = rtq2208_set_ramp_delay, + .set_active_discharge = regulator_set_active_discharge_regmap, + .set_suspend_enable = rtq2208_set_suspend_enable, + .set_suspend_disable = rtq2208_set_suspend_disable, + .set_suspend_mode = rtq2208_set_suspend_mode, +}; + +static const struct regulator_ops rtq2208_regulator_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_active_discharge = regulator_set_active_discharge_regmap, + .set_suspend_enable = rtq2208_set_suspend_enable, + .set_suspend_disable = rtq2208_set_suspend_disable, +}; + +static unsigned int rtq2208_of_map_mode(unsigned int mode) +{ + switch (mode) { + case RTQ2208_AUTO_MODE: + return REGULATOR_MODE_NORMAL; + case RTQ2208_FCCM: + return REGULATOR_MODE_FAST; + default: + return REGULATOR_MODE_INVALID; + } +} + +static int rtq2208_init_irq_mask(struct rtq2208_rdev_map *rdev_map, unsigned int *buck_masks) +{ + unsigned char buck_clr_masks[5] = {0x33, 0x33, 0x33, 0x33, 0x33}, + sts_clr_masks[2] = {0xE7, 0xF7}, sts_masks[2] = {0xE6, 0xF6}; + int ret; + + /* write clear all buck irq once */ + ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB, buck_clr_masks, 5); + if (ret) + return dev_err_probe(rdev_map->dev, ret, "Failed to clr buck irqs\n"); + + /* write clear general irq once */ + ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1, sts_clr_masks, 2); + if (ret) + return dev_err_probe(rdev_map->dev, ret, "Failed to clr general irqs\n"); + + /* unmask buck ov/uv irq */ + ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_MASKBUCK_CB, buck_masks, 5); + if (ret) + return dev_err_probe(rdev_map->dev, ret, "Failed to unmask buck irqs\n"); + + /* unmask needed general irq */ + return regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1_MASK, sts_masks, 2); +} + +static irqreturn_t rtq2208_irq_handler(int irqno, void *devid) +{ + unsigned char buck_flags[RTQ2208_BUCK_NUM_IRQ_REGS], sts_flags[RTQ2208_STS_NUM_IRQ_REGS]; + int ret = 0, i, uv_bit, ov_bit; + struct rtq2208_rdev_map *rdev_map = devid; + struct regulator_dev *rdev; + + if (!rdev_map) + return IRQ_NONE; + + /* read irq event */ + ret = regmap_bulk_read(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB, + buck_flags, ARRAY_SIZE(buck_flags)); + if (ret) + return IRQ_NONE; + + ret = regmap_bulk_read(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1, + sts_flags, ARRAY_SIZE(sts_flags)); + if (ret) + return IRQ_NONE; + + /* clear irq event */ + ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_FLT_RECORDBUCK_CB, + buck_flags, ARRAY_SIZE(buck_flags)); + if (ret) + return IRQ_NONE; + + ret = regmap_bulk_write(rdev_map->regmap, RTQ2208_REG_GLOBAL_INT1, + sts_flags, ARRAY_SIZE(sts_flags)); + if (ret) + return IRQ_NONE; + + for (i = 0; i < RTQ2208_LDO_MAX; i++) { + if (!rdev_map->rdev[i]) + continue; + + rdev = rdev_map->rdev[i]; + /* uv irq */ + uv_bit = (i & 1) ? 4 : 0; + if (buck_flags[i >> 1] & (1 << uv_bit)) + regulator_notifier_call_chain(rdev, + REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + /* ov irq */ + ov_bit = uv_bit + 1; + if (buck_flags[i >> 1] & (1 << ov_bit)) + regulator_notifier_call_chain(rdev, + REGULATOR_EVENT_REGULATION_OUT, NULL); + + /* hd irq */ + if (sts_flags[1] & RTQ2208_HD_INT_MASK) + regulator_notifier_call_chain(rdev, + REGULATOR_EVENT_OVER_TEMP, NULL); + } + + return IRQ_HANDLED; +} + +#define RTQ2208_REGULATOR_INFO(_name, _base) \ +{ \ + .name = #_name, \ + .base = _base, \ +} +#define BUCK_RG_BASE(_id) RTQ2208_REG_BUCK_##_id##_CFG0 +#define BUCK_RG_SHIFT(_base, _shift) (_base + _shift) +#define LDO_RG_BASE(_id) RTQ2208_REG_LDO##_id##_CFG +#define LDO_RG_SHIFT(_base, _shift) (_base + _shift) +#define VSEL_SHIFT(_sel) (_sel ? 3 : 1) +#define MTP_SEL_MASK(_sel) RTQ2208_BUCK_EN_NR_MTP_SEL##_sel##_MASK + +static const struct linear_range rtq2208_vout_range[] = { + REGULATOR_LINEAR_RANGE(400000, 0, 180, 5000), + REGULATOR_LINEAR_RANGE(1310000, 181, 255, 10000), +}; + +static int rtq2208_of_get_fixed_voltage(struct device *dev, + struct of_regulator_match *rtq2208_ldo_match, int n_fixed) +{ + struct device_node *np; + struct of_regulator_match *match; + struct rtq2208_regulator_desc *rdesc; + struct regulator_init_data *init_data; + int ret, i; + + if (!dev->of_node) + return -ENODEV; + + np = of_get_child_by_name(dev->of_node, "regulators"); + if (!np) + np = dev->of_node; + + ret = of_regulator_match(dev, np, rtq2208_ldo_match, n_fixed); + + of_node_put(np); + + if (ret < 0) + return ret; + + for (i = 0; i < n_fixed; i++) { + match = rtq2208_ldo_match + i; + init_data = match->init_data; + rdesc = (struct rtq2208_regulator_desc *)match->driver_data; + + if (!init_data || !rdesc) + continue; + + if (init_data->constraints.min_uV == init_data->constraints.max_uV) + rdesc->desc.fixed_uV = init_data->constraints.min_uV; + } + + return 0; +} + +static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, int mtp_sel, + int idx, struct of_regulator_match *rtq2208_ldo_match, int *ldo_idx) +{ + struct regulator_desc *desc; + static const struct { + char *name; + int base; + } regulator_info[] = { + RTQ2208_REGULATOR_INFO(buck-b, BUCK_RG_BASE(B)), + RTQ2208_REGULATOR_INFO(buck-c, BUCK_RG_BASE(C)), + RTQ2208_REGULATOR_INFO(buck-d, BUCK_RG_BASE(D)), + RTQ2208_REGULATOR_INFO(buck-a, BUCK_RG_BASE(A)), + RTQ2208_REGULATOR_INFO(buck-f, BUCK_RG_BASE(F)), + RTQ2208_REGULATOR_INFO(buck-g, BUCK_RG_BASE(G)), + RTQ2208_REGULATOR_INFO(buck-h, BUCK_RG_BASE(H)), + RTQ2208_REGULATOR_INFO(buck-e, BUCK_RG_BASE(E)), + RTQ2208_REGULATOR_INFO(ldo2, LDO_RG_BASE(2)), + RTQ2208_REGULATOR_INFO(ldo1, LDO_RG_BASE(1)), + }, *curr_info; + + curr_info = regulator_info + idx; + desc = &rdesc->desc; + desc->name = curr_info->name; + desc->of_match = of_match_ptr(curr_info->name); + desc->regulators_node = of_match_ptr("regulators"); + desc->id = idx; + desc->owner = THIS_MODULE; + desc->type = REGULATOR_VOLTAGE; + desc->enable_mask = mtp_sel ? MTP_SEL_MASK(1) : MTP_SEL_MASK(0); + desc->active_discharge_on = RTQ2208_EN_DIS_MASK; + desc->active_discharge_off = 0; + desc->active_discharge_mask = RTQ2208_EN_DIS_MASK; + + rdesc->mode_mask = RTQ2208_BUCK_NRMODE_MASK; + + if (idx >= RTQ2208_BUCK_B && idx <= RTQ2208_BUCK_E) { + /* init buck desc */ + desc->enable_reg = BUCK_RG_SHIFT(curr_info->base, 2); + desc->ops = &rtq2208_regulator_buck_ops; + desc->vsel_reg = curr_info->base + VSEL_SHIFT(mtp_sel); + desc->vsel_mask = RTQ2208_BUCK_NR_MTP_SEL_MASK; + desc->n_voltages = RTQ2208_VOUT_MAXNUM; + desc->linear_ranges = rtq2208_vout_range; + desc->n_linear_ranges = ARRAY_SIZE(rtq2208_vout_range); + desc->ramp_reg = BUCK_RG_SHIFT(curr_info->base, 5); + desc->active_discharge_reg = curr_info->base; + desc->of_map_mode = rtq2208_of_map_mode; + + rdesc->mode_reg = BUCK_RG_SHIFT(curr_info->base, 2); + rdesc->suspend_config_reg = BUCK_RG_SHIFT(curr_info->base, 4); + rdesc->suspend_enable_mask = RTQ2208_BUCK_EN_STR_MASK; + rdesc->suspend_mode_mask = RTQ2208_BUCK_STRMODE_MASK; + } else { + /* init ldo desc */ + desc->enable_reg = curr_info->base; + desc->ops = &rtq2208_regulator_ldo_ops; + desc->n_voltages = 1; + desc->active_discharge_reg = LDO_RG_SHIFT(curr_info->base, 2); + + rtq2208_ldo_match[*ldo_idx].name = desc->name; + rtq2208_ldo_match[*ldo_idx].driver_data = rdesc; + rtq2208_ldo_match[(*ldo_idx)++].desc = desc; + + rdesc->suspend_config_reg = curr_info->base; + rdesc->suspend_enable_mask = RTQ2208_LDO_EN_STR_MASK; + } +} + +static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *regulator_idx_table, + struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev) +{ + struct of_regulator_match rtq2208_ldo_match[2]; + int mtp_sel, ret, i, idx, ldo_idx = 0; + + /* get mtp_sel0 or mtp_sel1 */ + mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high"); + + for (i = 0; i < n_regulator; i++) { + idx = regulator_idx_table[i]; + + rdesc[i] = devm_kcalloc(dev, 1, sizeof(*rdesc[0]), GFP_KERNEL); + if (!rdesc[i]) + return -ENOMEM; + + rtq2208_init_regulator_desc(rdesc[i], mtp_sel, idx, rtq2208_ldo_match, &ldo_idx); + } + + /* init ldo fixed_uV */ + ret = rtq2208_of_get_fixed_voltage(dev, rtq2208_ldo_match, ldo_idx); + if (ret) + return dev_err_probe(dev, ret, "Failed to get ldo fixed_uV\n"); + + return 0; + +} + +/** different slave address corresponds different used bucks + * slave address 0x10: BUCK[BCA FGE] + * slave address 0x20: BUCK[BC FGHE] + * slave address 0x40: BUCK[C G] + */ +static int rtq2208_regulator_check(int slave_addr, int *num, + int *regulator_idx_table, unsigned int *buck_masks) +{ + static bool rtq2208_used_table[3][RTQ2208_LDO_MAX] = { + /* BUCK[BCA FGE], LDO[12] */ + {1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, + /* BUCK[BC FGHE], LDO[12]*/ + {1, 1, 0, 0, 1, 1, 1, 1, 1, 1}, + /* BUCK[C G], LDO[12] */ + {0, 1, 0, 0, 0, 1, 0, 0, 1, 1}, + }; + int i, idx = ffs(slave_addr >> 4) - 1; + u8 mask; + + for (i = 0; i < RTQ2208_LDO_MAX; i++) { + if (!rtq2208_used_table[idx][i]) + continue; + + regulator_idx_table[(*num)++] = i; + + mask = RTQ2208_BUCK_MASK(4 * i, 4 * i + 1); + buck_masks[i >> 1] &= ~mask; + } + + return 0; +} + +static const struct regmap_config rtq2208_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xEF, +}; + +static int rtq2208_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct regmap *regmap; + struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX]; + struct regulator_dev *rdev; + struct regulator_config cfg; + struct rtq2208_rdev_map *rdev_map; + int i, ret = 0, idx, n_regulator = 0; + unsigned int regulator_idx_table[RTQ2208_LDO_MAX], + buck_masks[RTQ2208_BUCK_NUM_IRQ_REGS] = {0x33, 0x33, 0x33, 0x33, 0x33}; + + rdev_map = devm_kzalloc(dev, sizeof(struct rtq2208_rdev_map), GFP_KERNEL); + if (!rdev_map) + return -ENOMEM; + + regmap = devm_regmap_init_i2c(i2c, &rtq2208_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate regmap\n"); + + /* get needed regulator */ + ret = rtq2208_regulator_check(i2c->addr, &n_regulator, regulator_idx_table, buck_masks); + if (ret) + return dev_err_probe(dev, ret, "Failed to check used regulators\n"); + + rdev_map->regmap = regmap; + rdev_map->dev = dev; + + cfg.dev = dev; + + /* init regulator desc */ + ret = rtq2208_parse_regulator_dt_data(n_regulator, regulator_idx_table, rdesc, dev); + if (ret) + return ret; + + for (i = 0; i < n_regulator; i++) { + idx = regulator_idx_table[i]; + + /* register regulator */ + rdev = devm_regulator_register(dev, &rdesc[i]->desc, &cfg); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + + rdev_map->rdev[idx] = rdev; + } + + /* init interrupt mask */ + ret = rtq2208_init_irq_mask(rdev_map, buck_masks); + if (ret) + return ret; + + /* register interrupt */ + return devm_request_threaded_irq(dev, i2c->irq, NULL, rtq2208_irq_handler, + IRQF_ONESHOT, dev_name(dev), rdev_map); +} + +static const struct of_device_id rtq2208_device_tables[] = { + { .compatible = "richtek,rtq2208" }, + {} +}; +MODULE_DEVICE_TABLE(of, rtq2208_device_tables); + +static struct i2c_driver rtq2208_driver = { + .driver = { + .name = "rtq2208", + .of_match_table = rtq2208_device_tables, + }, + .probe_new = rtq2208_probe, +}; +module_i2c_driver(rtq2208_driver); + +MODULE_AUTHOR("Alina Yu "); +MODULE_DESCRIPTION("Richtek RTQ2208 Regulator Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From ed2f4c745fb2bc51bb1b402ff2294587cb0b207a Mon Sep 17 00:00:00 2001 From: Naresh Solanki Date: Tue, 1 Aug 2023 12:24:52 +0200 Subject: regulator: max5970: Rename driver and remove wildcard The previous version of this driver included wildcards in file names and descriptions. This patch renames the driver to only support MAX5970 and MAX5978, which are the only chips that the driver actually supports. Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20230801102453.1798292-1-Naresh.Solanki@9elements.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 6 +- drivers/regulator/Makefile | 2 +- drivers/regulator/max5970-regulator.c | 514 ++++++++++++++++++++++++++++++++++ drivers/regulator/max597x-regulator.c | 514 ---------------------------------- 4 files changed, 518 insertions(+), 518 deletions(-) create mode 100644 drivers/regulator/max5970-regulator.c delete mode 100644 drivers/regulator/max597x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 94f44736473e..a5c9de1cab2b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -546,11 +546,11 @@ config REGULATOR_MAX1586 regulator via I2C bus. The provided regulator is suitable for PXA27x chips to control VCC_CORE and VCC_USIM voltages. -config REGULATOR_MAX597X - tristate "Maxim 597x power switch and monitor" +config REGULATOR_MAX5970 + tristate "Maxim 5970/5978 power switch and monitor" depends on I2C depends on OF - depends on MFD_MAX597X + depends on MFD_MAX5970 help This driver controls a Maxim 5970/5978 switch via I2C bus. The MAX5970/5978 is a smart switch with no output regulation, but diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 77b22bdd2791..453289cdd444 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -67,7 +67,7 @@ obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o -obj-$(CONFIG_REGULATOR_MAX597X) += max597x-regulator.o +obj-$(CONFIG_REGULATOR_MAX5970) += max5970-regulator.o obj-$(CONFIG_REGULATOR_MAX77541) += max77541-regulator.o obj-$(CONFIG_REGULATOR_MAX77620) += max77620-regulator.o obj-$(CONFIG_REGULATOR_MAX77650) += max77650-regulator.o diff --git a/drivers/regulator/max5970-regulator.c b/drivers/regulator/max5970-regulator.c new file mode 100644 index 000000000000..b56a174cde3d --- /dev/null +++ b/drivers/regulator/max5970-regulator.c @@ -0,0 +1,514 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device driver for regulators in MAX5970 and MAX5978 IC + * + * Copyright (c) 2022 9elements GmbH + * + * Author: Patrick Rudolph + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct max5970_regulator { + int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA; + struct regmap *regmap; +}; + +enum max597x_regulator_id { + MAX597X_SW0, + MAX597X_SW1, +}; + +static int max597x_uvp_ovp_check_mode(struct regulator_dev *rdev, int severity) +{ + int ret, reg; + + /* Status1 register contains the soft strap values sampled at POR */ + ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS1, ®); + if (ret) + return ret; + + /* Check soft straps match requested mode */ + if (severity == REGULATOR_SEVERITY_PROT) { + if (STATUS1_PROT(reg) != STATUS1_PROT_SHUTDOWN) + return -EOPNOTSUPP; + + return 0; + } + if (STATUS1_PROT(reg) == STATUS1_PROT_SHUTDOWN) + return -EOPNOTSUPP; + + return 0; +} + +static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity, + bool enable, bool overvoltage) +{ + int off_h, off_l, reg, ret; + struct max5970_regulator *data = rdev_get_drvdata(rdev); + int channel = rdev_get_id(rdev); + + if (overvoltage) { + if (severity == REGULATOR_SEVERITY_WARN) { + off_h = MAX5970_REG_CH_OV_WARN_H(channel); + off_l = MAX5970_REG_CH_OV_WARN_L(channel); + } else { + off_h = MAX5970_REG_CH_OV_CRIT_H(channel); + off_l = MAX5970_REG_CH_OV_CRIT_L(channel); + } + } else { + if (severity == REGULATOR_SEVERITY_WARN) { + off_h = MAX5970_REG_CH_UV_WARN_H(channel); + off_l = MAX5970_REG_CH_UV_WARN_L(channel); + } else { + off_h = MAX5970_REG_CH_UV_CRIT_H(channel); + off_l = MAX5970_REG_CH_UV_CRIT_L(channel); + } + } + + if (enable) + /* reg = ADC_MASK * (lim_uV / 1000000) / (data->mon_rng / 1000000) */ + reg = ADC_MASK * lim_uV / data->mon_rng; + else + reg = 0; + + ret = regmap_write(rdev->regmap, off_h, MAX5970_VAL2REG_H(reg)); + if (ret) + return ret; + + ret = regmap_write(rdev->regmap, off_l, MAX5970_VAL2REG_L(reg)); + if (ret) + return ret; + + return 0; +} + +static int max597x_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity, + bool enable) +{ + int ret; + + /* + * MAX5970 has enable control as a special value in limit reg. Can't + * set limit but keep feature disabled or enable W/O given limit. + */ + if ((lim_uV && !enable) || (!lim_uV && enable)) + return -EINVAL; + + ret = max597x_uvp_ovp_check_mode(rdev, severity); + if (ret) + return ret; + + return max597x_set_vp(rdev, lim_uV, severity, enable, false); +} + +static int max597x_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity, + bool enable) +{ + int ret; + + /* + * MAX5970 has enable control as a special value in limit reg. Can't + * set limit but keep feature disabled or enable W/O given limit. + */ + if ((lim_uV && !enable) || (!lim_uV && enable)) + return -EINVAL; + + ret = max597x_uvp_ovp_check_mode(rdev, severity); + if (ret) + return ret; + + return max597x_set_vp(rdev, lim_uV, severity, enable, true); +} + +static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA, + int severity, bool enable) +{ + int val, reg; + unsigned int vthst, vthfst; + + struct max5970_regulator *data = rdev_get_drvdata(rdev); + int rdev_id = rdev_get_id(rdev); + /* + * MAX5970 doesn't has enable control for ocp. + * If limit is specified but enable is not set then hold the value in + * variable & later use it when ocp needs to be enabled. + */ + if (lim_uA != 0 && lim_uA != data->lim_uA) + data->lim_uA = lim_uA; + + if (severity != REGULATOR_SEVERITY_PROT) + return -EINVAL; + + if (enable) { + + /* Calc Vtrip threshold in uV. */ + vthst = + div_u64(mul_u32_u32(data->shunt_micro_ohms, data->lim_uA), + 1000000); + + /* + * As recommended in datasheed, add 20% margin to avoid + * spurious event & passive component tolerance. + */ + vthst = div_u64(mul_u32_u32(vthst, 120), 100); + + /* Calc fast Vtrip threshold in uV */ + vthfst = vthst * (MAX5970_FAST2SLOW_RATIO / 100); + + if (vthfst > data->irng) { + dev_err(&rdev->dev, "Current limit out of range\n"); + return -EINVAL; + } + /* Fast trip threshold to be programmed */ + val = div_u64(mul_u32_u32(0xFF, vthfst), data->irng); + } else + /* + * Since there is no option to disable ocp, set limit to max + * value + */ + val = 0xFF; + + reg = MAX5970_REG_DAC_FAST(rdev_id); + + return regmap_write(rdev->regmap, reg, val); +} + +static int max597x_get_status(struct regulator_dev *rdev) +{ + int val, ret; + + ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS3, &val); + if (ret) + return ret; + + if (val & MAX5970_STATUS3_ALERT) + return REGULATOR_STATUS_ERROR; + + ret = regulator_is_enabled_regmap(rdev); + if (ret < 0) + return ret; + + if (ret) + return REGULATOR_STATUS_ON; + + return REGULATOR_STATUS_OFF; +} + +static const struct regulator_ops max597x_switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_status = max597x_get_status, + .set_over_voltage_protection = max597x_set_ovp, + .set_under_voltage_protection = max597x_set_uvp, + .set_over_current_protection = max597x_set_ocp, +}; + +static int max597x_dt_parse(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + struct max5970_regulator *data = cfg->driver_data; + int ret = 0; + + ret = + of_property_read_u32(np, "shunt-resistor-micro-ohms", + &data->shunt_micro_ohms); + if (ret < 0) + dev_err(cfg->dev, + "property 'shunt-resistor-micro-ohms' not found, err %d\n", + ret); + return ret; + +} + +#define MAX597X_SWITCH(_ID, _ereg, _chan, _supply) { \ + .name = #_ID, \ + .of_match = of_match_ptr(#_ID), \ + .ops = &max597x_switch_ops, \ + .regulators_node = of_match_ptr("regulators"), \ + .type = REGULATOR_VOLTAGE, \ + .id = MAX597X_##_ID, \ + .owner = THIS_MODULE, \ + .supply_name = _supply, \ + .enable_reg = _ereg, \ + .enable_mask = CHXEN((_chan)), \ + .of_parse_cb = max597x_dt_parse, \ +} + +static const struct regulator_desc regulators[] = { + MAX597X_SWITCH(SW0, MAX5970_REG_CHXEN, 0, "vss1"), + MAX597X_SWITCH(SW1, MAX5970_REG_CHXEN, 1, "vss2"), +}; + +static int max597x_regmap_read_clear(struct regmap *map, unsigned int reg, + unsigned int *val) +{ + int ret; + + ret = regmap_read(map, reg, val); + if (ret) + return ret; + + if (*val) + return regmap_write(map, reg, *val); + + return 0; +} + +static int max597x_irq_handler(int irq, struct regulator_irq_data *rid, + unsigned long *dev_mask) +{ + struct regulator_err_state *stat; + struct max5970_regulator *d = (struct max5970_regulator *)rid->data; + int val, ret, i; + + ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val); + if (ret) + return REGULATOR_FAILED_RETRY; + + *dev_mask = 0; + for (i = 0; i < d->num_switches; i++) { + stat = &rid->states[i]; + stat->notifs = 0; + stat->errors = 0; + } + + for (i = 0; i < d->num_switches; i++) { + stat = &rid->states[i]; + + if (val & UV_STATUS_CRIT(i)) { + *dev_mask |= 1 << i; + stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE; + stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE; + } else if (val & UV_STATUS_WARN(i)) { + *dev_mask |= 1 << i; + stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE_WARN; + stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE_WARN; + } + } + + ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT1, &val); + if (ret) + return REGULATOR_FAILED_RETRY; + + for (i = 0; i < d->num_switches; i++) { + stat = &rid->states[i]; + + if (val & OV_STATUS_CRIT(i)) { + *dev_mask |= 1 << i; + stat->notifs |= REGULATOR_EVENT_REGULATION_OUT; + stat->errors |= REGULATOR_ERROR_REGULATION_OUT; + } else if (val & OV_STATUS_WARN(i)) { + *dev_mask |= 1 << i; + stat->notifs |= REGULATOR_EVENT_OVER_VOLTAGE_WARN; + stat->errors |= REGULATOR_ERROR_OVER_VOLTAGE_WARN; + } + } + + ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT2, &val); + if (ret) + return REGULATOR_FAILED_RETRY; + + for (i = 0; i < d->num_switches; i++) { + stat = &rid->states[i]; + + if (val & OC_STATUS_WARN(i)) { + *dev_mask |= 1 << i; + stat->notifs |= REGULATOR_EVENT_OVER_CURRENT_WARN; + stat->errors |= REGULATOR_ERROR_OVER_CURRENT_WARN; + } + } + + ret = regmap_read(d->regmap, MAX5970_REG_STATUS0, &val); + if (ret) + return REGULATOR_FAILED_RETRY; + + for (i = 0; i < d->num_switches; i++) { + stat = &rid->states[i]; + + if ((val & MAX5970_CB_IFAULTF(i)) + || (val & MAX5970_CB_IFAULTS(i))) { + *dev_mask |= 1 << i; + stat->notifs |= + REGULATOR_EVENT_OVER_CURRENT | + REGULATOR_EVENT_DISABLE; + stat->errors |= + REGULATOR_ERROR_OVER_CURRENT | REGULATOR_ERROR_FAIL; + + /* Clear the sub-IRQ status */ + regulator_disable_regmap(stat->rdev); + } + } + return 0; +} + +static int max597x_adc_range(struct regmap *regmap, const int ch, + u32 *irng, u32 *mon_rng) +{ + unsigned int reg; + int ret; + + /* Decode current ADC range */ + ret = regmap_read(regmap, MAX5970_REG_STATUS2, ®); + if (ret) + return ret; + switch (MAX5970_IRNG(reg, ch)) { + case 0: + *irng = 100000; /* 100 mV */ + break; + case 1: + *irng = 50000; /* 50 mV */ + break; + case 2: + *irng = 25000; /* 25 mV */ + break; + default: + return -EINVAL; + } + + /* Decode current voltage monitor range */ + ret = regmap_read(regmap, MAX5970_REG_MON_RANGE, ®); + if (ret) + return ret; + + *mon_rng = MAX5970_MON_MAX_RANGE_UV >> MAX5970_MON(reg, ch); + + return 0; +} + +static int max597x_setup_irq(struct device *dev, + int irq, + struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES], + int num_switches, struct max5970_regulator *data) +{ + struct regulator_irq_desc max597x_notif = { + .name = "max597x-irq", + .map_event = max597x_irq_handler, + .data = data, + }; + int errs = REGULATOR_ERROR_UNDER_VOLTAGE | + REGULATOR_ERROR_UNDER_VOLTAGE_WARN | + REGULATOR_ERROR_OVER_VOLTAGE_WARN | + REGULATOR_ERROR_REGULATION_OUT | + REGULATOR_ERROR_OVER_CURRENT | + REGULATOR_ERROR_OVER_CURRENT_WARN | REGULATOR_ERROR_FAIL; + void *irq_helper; + + /* Register notifiers - can fail if IRQ is not given */ + irq_helper = devm_regulator_irq_helper(dev, &max597x_notif, + irq, 0, errs, NULL, + &rdevs[0], num_switches); + if (IS_ERR(irq_helper)) { + if (PTR_ERR(irq_helper) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + dev_warn(dev, "IRQ disabled %pe\n", irq_helper); + } + + return 0; +} + +static int max597x_regulator_probe(struct platform_device *pdev) +{ + struct max5970_data *max597x; + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); + struct max5970_regulator *data; + struct i2c_client *i2c = to_i2c_client(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_dev *rdev; + struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES]; + int num_switches; + int ret, i; + + if (!regmap) + return -EPROBE_DEFER; + + max597x = devm_kzalloc(&i2c->dev, sizeof(struct max5970_data), GFP_KERNEL); + if (!max597x) + return -ENOMEM; + + i2c_set_clientdata(i2c, max597x); + + if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978")) + max597x->num_switches = MAX5978_NUM_SWITCHES; + else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970")) + max597x->num_switches = MAX5970_NUM_SWITCHES; + else + return -ENODEV; + + i2c_set_clientdata(i2c, max597x); + num_switches = max597x->num_switches; + + for (i = 0; i < num_switches; i++) { + data = + devm_kzalloc(&i2c->dev, sizeof(struct max5970_regulator), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->num_switches = num_switches; + data->regmap = regmap; + + ret = max597x_adc_range(regmap, i, &max597x->irng[i], &max597x->mon_rng[i]); + if (ret < 0) + return ret; + + data->irng = max597x->irng[i]; + data->mon_rng = max597x->mon_rng[i]; + + config.dev = &i2c->dev; + config.driver_data = (void *)data; + config.regmap = data->regmap; + rdev = devm_regulator_register(&i2c->dev, + ®ulators[i], &config); + if (IS_ERR(rdev)) { + dev_err(&i2c->dev, "failed to register regulator %s\n", + regulators[i].name); + return PTR_ERR(rdev); + } + rdevs[i] = rdev; + max597x->shunt_micro_ohms[i] = data->shunt_micro_ohms; + } + + if (i2c->irq) { + ret = + max597x_setup_irq(&i2c->dev, i2c->irq, rdevs, num_switches, + data); + if (ret) { + dev_err(&i2c->dev, "IRQ setup failed"); + return ret; + } + } + + return ret; +} + +static struct platform_driver max597x_regulator_driver = { + .driver = { + .name = "max5970-regulator", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, + .probe = max597x_regulator_probe, +}; + +module_platform_driver(max597x_regulator_driver); + + +MODULE_AUTHOR("Patrick Rudolph "); +MODULE_DESCRIPTION("MAX5970_hot-swap controller driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/max597x-regulator.c b/drivers/regulator/max597x-regulator.c deleted file mode 100644 index 7873a5267555..000000000000 --- a/drivers/regulator/max597x-regulator.c +++ /dev/null @@ -1,514 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Device driver for regulators in MAX5970 and MAX5978 IC - * - * Copyright (c) 2022 9elements GmbH - * - * Author: Patrick Rudolph - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -struct max597x_regulator { - int num_switches, mon_rng, irng, shunt_micro_ohms, lim_uA; - struct regmap *regmap; -}; - -enum max597x_regulator_id { - MAX597X_SW0, - MAX597X_SW1, -}; - -static int max597x_uvp_ovp_check_mode(struct regulator_dev *rdev, int severity) -{ - int ret, reg; - - /* Status1 register contains the soft strap values sampled at POR */ - ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS1, ®); - if (ret) - return ret; - - /* Check soft straps match requested mode */ - if (severity == REGULATOR_SEVERITY_PROT) { - if (STATUS1_PROT(reg) != STATUS1_PROT_SHUTDOWN) - return -EOPNOTSUPP; - - return 0; - } - if (STATUS1_PROT(reg) == STATUS1_PROT_SHUTDOWN) - return -EOPNOTSUPP; - - return 0; -} - -static int max597x_set_vp(struct regulator_dev *rdev, int lim_uV, int severity, - bool enable, bool overvoltage) -{ - int off_h, off_l, reg, ret; - struct max597x_regulator *data = rdev_get_drvdata(rdev); - int channel = rdev_get_id(rdev); - - if (overvoltage) { - if (severity == REGULATOR_SEVERITY_WARN) { - off_h = MAX5970_REG_CH_OV_WARN_H(channel); - off_l = MAX5970_REG_CH_OV_WARN_L(channel); - } else { - off_h = MAX5970_REG_CH_OV_CRIT_H(channel); - off_l = MAX5970_REG_CH_OV_CRIT_L(channel); - } - } else { - if (severity == REGULATOR_SEVERITY_WARN) { - off_h = MAX5970_REG_CH_UV_WARN_H(channel); - off_l = MAX5970_REG_CH_UV_WARN_L(channel); - } else { - off_h = MAX5970_REG_CH_UV_CRIT_H(channel); - off_l = MAX5970_REG_CH_UV_CRIT_L(channel); - } - } - - if (enable) - /* reg = ADC_MASK * (lim_uV / 1000000) / (data->mon_rng / 1000000) */ - reg = ADC_MASK * lim_uV / data->mon_rng; - else - reg = 0; - - ret = regmap_write(rdev->regmap, off_h, MAX5970_VAL2REG_H(reg)); - if (ret) - return ret; - - ret = regmap_write(rdev->regmap, off_l, MAX5970_VAL2REG_L(reg)); - if (ret) - return ret; - - return 0; -} - -static int max597x_set_uvp(struct regulator_dev *rdev, int lim_uV, int severity, - bool enable) -{ - int ret; - - /* - * MAX5970 has enable control as a special value in limit reg. Can't - * set limit but keep feature disabled or enable W/O given limit. - */ - if ((lim_uV && !enable) || (!lim_uV && enable)) - return -EINVAL; - - ret = max597x_uvp_ovp_check_mode(rdev, severity); - if (ret) - return ret; - - return max597x_set_vp(rdev, lim_uV, severity, enable, false); -} - -static int max597x_set_ovp(struct regulator_dev *rdev, int lim_uV, int severity, - bool enable) -{ - int ret; - - /* - * MAX5970 has enable control as a special value in limit reg. Can't - * set limit but keep feature disabled or enable W/O given limit. - */ - if ((lim_uV && !enable) || (!lim_uV && enable)) - return -EINVAL; - - ret = max597x_uvp_ovp_check_mode(rdev, severity); - if (ret) - return ret; - - return max597x_set_vp(rdev, lim_uV, severity, enable, true); -} - -static int max597x_set_ocp(struct regulator_dev *rdev, int lim_uA, - int severity, bool enable) -{ - int val, reg; - unsigned int vthst, vthfst; - - struct max597x_regulator *data = rdev_get_drvdata(rdev); - int rdev_id = rdev_get_id(rdev); - /* - * MAX5970 doesn't has enable control for ocp. - * If limit is specified but enable is not set then hold the value in - * variable & later use it when ocp needs to be enabled. - */ - if (lim_uA != 0 && lim_uA != data->lim_uA) - data->lim_uA = lim_uA; - - if (severity != REGULATOR_SEVERITY_PROT) - return -EINVAL; - - if (enable) { - - /* Calc Vtrip threshold in uV. */ - vthst = - div_u64(mul_u32_u32(data->shunt_micro_ohms, data->lim_uA), - 1000000); - - /* - * As recommended in datasheed, add 20% margin to avoid - * spurious event & passive component tolerance. - */ - vthst = div_u64(mul_u32_u32(vthst, 120), 100); - - /* Calc fast Vtrip threshold in uV */ - vthfst = vthst * (MAX5970_FAST2SLOW_RATIO / 100); - - if (vthfst > data->irng) { - dev_err(&rdev->dev, "Current limit out of range\n"); - return -EINVAL; - } - /* Fast trip threshold to be programmed */ - val = div_u64(mul_u32_u32(0xFF, vthfst), data->irng); - } else - /* - * Since there is no option to disable ocp, set limit to max - * value - */ - val = 0xFF; - - reg = MAX5970_REG_DAC_FAST(rdev_id); - - return regmap_write(rdev->regmap, reg, val); -} - -static int max597x_get_status(struct regulator_dev *rdev) -{ - int val, ret; - - ret = regmap_read(rdev->regmap, MAX5970_REG_STATUS3, &val); - if (ret) - return ret; - - if (val & MAX5970_STATUS3_ALERT) - return REGULATOR_STATUS_ERROR; - - ret = regulator_is_enabled_regmap(rdev); - if (ret < 0) - return ret; - - if (ret) - return REGULATOR_STATUS_ON; - - return REGULATOR_STATUS_OFF; -} - -static const struct regulator_ops max597x_switch_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .get_status = max597x_get_status, - .set_over_voltage_protection = max597x_set_ovp, - .set_under_voltage_protection = max597x_set_uvp, - .set_over_current_protection = max597x_set_ocp, -}; - -static int max597x_dt_parse(struct device_node *np, - const struct regulator_desc *desc, - struct regulator_config *cfg) -{ - struct max597x_regulator *data = cfg->driver_data; - int ret = 0; - - ret = - of_property_read_u32(np, "shunt-resistor-micro-ohms", - &data->shunt_micro_ohms); - if (ret < 0) - dev_err(cfg->dev, - "property 'shunt-resistor-micro-ohms' not found, err %d\n", - ret); - return ret; - -} - -#define MAX597X_SWITCH(_ID, _ereg, _chan, _supply) { \ - .name = #_ID, \ - .of_match = of_match_ptr(#_ID), \ - .ops = &max597x_switch_ops, \ - .regulators_node = of_match_ptr("regulators"), \ - .type = REGULATOR_VOLTAGE, \ - .id = MAX597X_##_ID, \ - .owner = THIS_MODULE, \ - .supply_name = _supply, \ - .enable_reg = _ereg, \ - .enable_mask = CHXEN((_chan)), \ - .of_parse_cb = max597x_dt_parse, \ -} - -static const struct regulator_desc regulators[] = { - MAX597X_SWITCH(SW0, MAX5970_REG_CHXEN, 0, "vss1"), - MAX597X_SWITCH(SW1, MAX5970_REG_CHXEN, 1, "vss2"), -}; - -static int max597x_regmap_read_clear(struct regmap *map, unsigned int reg, - unsigned int *val) -{ - int ret; - - ret = regmap_read(map, reg, val); - if (ret) - return ret; - - if (*val) - return regmap_write(map, reg, *val); - - return 0; -} - -static int max597x_irq_handler(int irq, struct regulator_irq_data *rid, - unsigned long *dev_mask) -{ - struct regulator_err_state *stat; - struct max597x_regulator *d = (struct max597x_regulator *)rid->data; - int val, ret, i; - - ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT0, &val); - if (ret) - return REGULATOR_FAILED_RETRY; - - *dev_mask = 0; - for (i = 0; i < d->num_switches; i++) { - stat = &rid->states[i]; - stat->notifs = 0; - stat->errors = 0; - } - - for (i = 0; i < d->num_switches; i++) { - stat = &rid->states[i]; - - if (val & UV_STATUS_CRIT(i)) { - *dev_mask |= 1 << i; - stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE; - stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE; - } else if (val & UV_STATUS_WARN(i)) { - *dev_mask |= 1 << i; - stat->notifs |= REGULATOR_EVENT_UNDER_VOLTAGE_WARN; - stat->errors |= REGULATOR_ERROR_UNDER_VOLTAGE_WARN; - } - } - - ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT1, &val); - if (ret) - return REGULATOR_FAILED_RETRY; - - for (i = 0; i < d->num_switches; i++) { - stat = &rid->states[i]; - - if (val & OV_STATUS_CRIT(i)) { - *dev_mask |= 1 << i; - stat->notifs |= REGULATOR_EVENT_REGULATION_OUT; - stat->errors |= REGULATOR_ERROR_REGULATION_OUT; - } else if (val & OV_STATUS_WARN(i)) { - *dev_mask |= 1 << i; - stat->notifs |= REGULATOR_EVENT_OVER_VOLTAGE_WARN; - stat->errors |= REGULATOR_ERROR_OVER_VOLTAGE_WARN; - } - } - - ret = max597x_regmap_read_clear(d->regmap, MAX5970_REG_FAULT2, &val); - if (ret) - return REGULATOR_FAILED_RETRY; - - for (i = 0; i < d->num_switches; i++) { - stat = &rid->states[i]; - - if (val & OC_STATUS_WARN(i)) { - *dev_mask |= 1 << i; - stat->notifs |= REGULATOR_EVENT_OVER_CURRENT_WARN; - stat->errors |= REGULATOR_ERROR_OVER_CURRENT_WARN; - } - } - - ret = regmap_read(d->regmap, MAX5970_REG_STATUS0, &val); - if (ret) - return REGULATOR_FAILED_RETRY; - - for (i = 0; i < d->num_switches; i++) { - stat = &rid->states[i]; - - if ((val & MAX5970_CB_IFAULTF(i)) - || (val & MAX5970_CB_IFAULTS(i))) { - *dev_mask |= 1 << i; - stat->notifs |= - REGULATOR_EVENT_OVER_CURRENT | - REGULATOR_EVENT_DISABLE; - stat->errors |= - REGULATOR_ERROR_OVER_CURRENT | REGULATOR_ERROR_FAIL; - - /* Clear the sub-IRQ status */ - regulator_disable_regmap(stat->rdev); - } - } - return 0; -} - -static int max597x_adc_range(struct regmap *regmap, const int ch, - u32 *irng, u32 *mon_rng) -{ - unsigned int reg; - int ret; - - /* Decode current ADC range */ - ret = regmap_read(regmap, MAX5970_REG_STATUS2, ®); - if (ret) - return ret; - switch (MAX5970_IRNG(reg, ch)) { - case 0: - *irng = 100000; /* 100 mV */ - break; - case 1: - *irng = 50000; /* 50 mV */ - break; - case 2: - *irng = 25000; /* 25 mV */ - break; - default: - return -EINVAL; - } - - /* Decode current voltage monitor range */ - ret = regmap_read(regmap, MAX5970_REG_MON_RANGE, ®); - if (ret) - return ret; - - *mon_rng = MAX5970_MON_MAX_RANGE_UV >> MAX5970_MON(reg, ch); - - return 0; -} - -static int max597x_setup_irq(struct device *dev, - int irq, - struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES], - int num_switches, struct max597x_regulator *data) -{ - struct regulator_irq_desc max597x_notif = { - .name = "max597x-irq", - .map_event = max597x_irq_handler, - .data = data, - }; - int errs = REGULATOR_ERROR_UNDER_VOLTAGE | - REGULATOR_ERROR_UNDER_VOLTAGE_WARN | - REGULATOR_ERROR_OVER_VOLTAGE_WARN | - REGULATOR_ERROR_REGULATION_OUT | - REGULATOR_ERROR_OVER_CURRENT | - REGULATOR_ERROR_OVER_CURRENT_WARN | REGULATOR_ERROR_FAIL; - void *irq_helper; - - /* Register notifiers - can fail if IRQ is not given */ - irq_helper = devm_regulator_irq_helper(dev, &max597x_notif, - irq, 0, errs, NULL, - &rdevs[0], num_switches); - if (IS_ERR(irq_helper)) { - if (PTR_ERR(irq_helper) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_warn(dev, "IRQ disabled %pe\n", irq_helper); - } - - return 0; -} - -static int max597x_regulator_probe(struct platform_device *pdev) -{ - struct max597x_data *max597x; - struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); - struct max597x_regulator *data; - struct i2c_client *i2c = to_i2c_client(pdev->dev.parent); - struct regulator_config config = { }; - struct regulator_dev *rdev; - struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES]; - int num_switches; - int ret, i; - - if (!regmap) - return -EPROBE_DEFER; - - max597x = devm_kzalloc(&i2c->dev, sizeof(struct max597x_data), GFP_KERNEL); - if (!max597x) - return -ENOMEM; - - i2c_set_clientdata(i2c, max597x); - - if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978")) - max597x->num_switches = MAX597x_TYPE_MAX5978; - else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970")) - max597x->num_switches = MAX597x_TYPE_MAX5970; - else - return -ENODEV; - - i2c_set_clientdata(i2c, max597x); - num_switches = max597x->num_switches; - - for (i = 0; i < num_switches; i++) { - data = - devm_kzalloc(&i2c->dev, sizeof(struct max597x_regulator), - GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->num_switches = num_switches; - data->regmap = regmap; - - ret = max597x_adc_range(regmap, i, &max597x->irng[i], &max597x->mon_rng[i]); - if (ret < 0) - return ret; - - data->irng = max597x->irng[i]; - data->mon_rng = max597x->mon_rng[i]; - - config.dev = &i2c->dev; - config.driver_data = (void *)data; - config.regmap = data->regmap; - rdev = devm_regulator_register(&i2c->dev, - ®ulators[i], &config); - if (IS_ERR(rdev)) { - dev_err(&i2c->dev, "failed to register regulator %s\n", - regulators[i].name); - return PTR_ERR(rdev); - } - rdevs[i] = rdev; - max597x->shunt_micro_ohms[i] = data->shunt_micro_ohms; - } - - if (i2c->irq) { - ret = - max597x_setup_irq(&i2c->dev, i2c->irq, rdevs, num_switches, - data); - if (ret) { - dev_err(&i2c->dev, "IRQ setup failed"); - return ret; - } - } - - return ret; -} - -static struct platform_driver max597x_regulator_driver = { - .driver = { - .name = "max597x-regulator", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - }, - .probe = max597x_regulator_probe, -}; - -module_platform_driver(max597x_regulator_driver); - - -MODULE_AUTHOR("Patrick Rudolph "); -MODULE_DESCRIPTION("MAX5970_hot-swap controller driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 200ee464f7a9a4e8d7a51a2083b28cf240e7cb91 Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Mon, 7 Aug 2023 21:41:27 +0800 Subject: regulator: rpi-panel-attiny-regulator: Remove redundant of_match_ptr() The driver depends on CONFIG_OF, so it is not necessary to use of_match_ptr() here, and __maybe_unused can also be removed. Even for drivers that do not depend on CONFIG_OF, it's almost always better to leave out the of_match_ptr(), since the only thing it can possibly do is to save a few bytes of .text if a driver can be used both with and without it. Signed-off-by: Ruan Jinjie Link: https://lore.kernel.org/r/20230807134127.2380390-1-ruanjinjie@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/rpi-panel-attiny-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/rpi-panel-attiny-regulator.c b/drivers/regulator/rpi-panel-attiny-regulator.c index e9719a378a0b..ed046cc998c6 100644 --- a/drivers/regulator/rpi-panel-attiny-regulator.c +++ b/drivers/regulator/rpi-panel-attiny-regulator.c @@ -397,7 +397,7 @@ static struct i2c_driver attiny_regulator_driver = { .driver = { .name = "rpi_touchscreen_attiny", .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(attiny_dt_ids), + .of_match_table = attiny_dt_ids, }, .probe = attiny_i2c_probe, .remove = attiny_i2c_remove, -- cgit v1.2.3-70-g09d2 From 9b966639b0cc742a9c4b6329a8e27128e4424cf1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:28 +0200 Subject: regulator: tps65910: Drop useless header The TPS65910 includes the legacy header for no reason, drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-1-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 2a0965ba1570..3a3027e0b94e 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3-70-g09d2 From d0d58fe27b344fb6d0edb5fd2038372b5e5ed95b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:29 +0200 Subject: regulator: s2mpa01: Drop useless header The TPS65910 includes the legacy header for no reason, drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-2-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/s2mpa01.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index b147ff6a16b1..c22fdde67f9c 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 052eff402fb754f3472833cb679ceef954ebf2a0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:30 +0200 Subject: regulator: rpi-panel-attiny: Drop useless header The RPI panel regulator driver includes the legacy header for no reason, this is a driver and is already included. Drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-3-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/rpi-panel-attiny-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/rpi-panel-attiny-regulator.c b/drivers/regulator/rpi-panel-attiny-regulator.c index ed046cc998c6..f52c3d47ecea 100644 --- a/drivers/regulator/rpi-panel-attiny-regulator.c +++ b/drivers/regulator/rpi-panel-attiny-regulator.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 2f26d97863f05b83b8f7872aff81ecb9d6b76b50 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:32 +0200 Subject: regulator: rc5t583: Drop useless header The RC5T583 includes the legacy header for no reason, drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-5-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/rc5t583-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index a5afca73715d..a25a141e86c4 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -16,7 +16,6 @@ #include #include #include -#include #include struct rc5t583_regulator_info { -- cgit v1.2.3-70-g09d2 From 4eb351fb89d68efeaca3625dccbbf492f5450801 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:33 +0200 Subject: regulator: mt6311: Drop useless header The mt6311 includes the legacy header for no reason, drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-6-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/mt6311-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c index b0771770cc26..63a51485f2cc 100644 --- a/drivers/regulator/mt6311-regulator.c +++ b/drivers/regulator/mt6311-regulator.c @@ -4,7 +4,6 @@ // Author: Henry Chen #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 2e903eac35ec0ea1f44af5a53d87d98309295fc3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:34 +0200 Subject: regulator: mcp16502: Drop useless header The mcp16502 regulator driver includes the legacy header for no reason, it is already using the proper include. Drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-7-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/mcp16502.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index 6c6f5a21362b..7a472a2ef48a 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -8,7 +8,6 @@ // // Inspired from tps65086-regulator.c -#include #include #include #include -- cgit v1.2.3-70-g09d2 From d150c73aa233d6469392282ef648dba5fd4b4821 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:35 +0200 Subject: regulator: max20086: Drop useless header The max20086 regulator driver includes the legacy header for no reason, it is already using the proper include. Drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-8-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/max20086-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c index fad31f5f435e..32f47b896fd1 100644 --- a/drivers/regulator/max20086-regulator.c +++ b/drivers/regulator/max20086-regulator.c @@ -6,7 +6,6 @@ // Copyright (C) 2018 Avnet, Inc. #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From e4d48f64fcd469feeb09fc452f8cd1dfc00b43f6 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:36 +0200 Subject: regulator: lp8755: Drop useless header The lp8755 includes the legacy header for no reason, drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-9-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/lp8755.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 4bc310f972ed..8d01e18046f3 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From a5c9a1444088099c6d52939ed2f34049d5d00b5f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:37 +0200 Subject: regulator: bd71828: Drop useless header The bd71828 includes the legacy header for no reason, drop the include. The documentation mentions GPIO but there is no usage of the GPIO namespace. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-10-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/bd71828-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c index f3205dc9d4fc..08d4ee369287 100644 --- a/drivers/regulator/bd71828-regulator.c +++ b/drivers/regulator/bd71828-regulator.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From f321708da4db6b15a8691dc64b2d5169234937bc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 8 Aug 2023 15:46:38 +0200 Subject: regulator: bd71815: Drop useless header The bd71815 regulator driver includes the legacy header for no reason, it is already using the proper include. Drop the include. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20230808-descriptors-regulator-v1-11-939b5e84dd18@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/bd71815-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/bd71815-regulator.c b/drivers/regulator/bd71815-regulator.c index 475b1e0110e7..26192d55a685 100644 --- a/drivers/regulator/bd71815-regulator.c +++ b/drivers/regulator/bd71815-regulator.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From 3a6d93eb5f27f313ce0f3fa3fb171cd0732c4878 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:22 +0000 Subject: regulator: da9121-regulator: Remove redundant of_match_ptr() macros Since the driver da9121-regulator depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove of_match_ptr() macros to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-2-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/da9121-regulator.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index 122124944749..80098035bb13 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -440,7 +440,7 @@ static const struct regulator_desc da9121_reg = { .of_match = "buck1", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -465,7 +465,7 @@ static const struct regulator_desc da9220_reg[2] = { .of_match = "buck1", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -484,7 +484,7 @@ static const struct regulator_desc da9220_reg[2] = { .of_match = "buck2", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -506,7 +506,7 @@ static const struct regulator_desc da9122_reg[2] = { .of_match = "buck1", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -525,7 +525,7 @@ static const struct regulator_desc da9122_reg[2] = { .of_match = "buck2", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -546,7 +546,7 @@ static const struct regulator_desc da9217_reg = { .of_match = "buck1", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -573,7 +573,7 @@ static const struct regulator_desc da9141_reg = { .of_match = "buck1", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -593,7 +593,7 @@ static const struct regulator_desc da9142_reg = { .of_match = "buck1", .of_parse_cb = da9121_of_parse_cb, .owner = THIS_MODULE, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .of_map_mode = da9121_map_mode, .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -1195,7 +1195,7 @@ static struct i2c_driver da9121_regulator_driver = { .driver = { .name = "da9121", .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(da9121_dt_ids), + .of_match_table = da9121_dt_ids, }, .probe = da9121_i2c_probe, .remove = da9121_i2c_remove, -- cgit v1.2.3-70-g09d2 From f410cfe8be5788cf09a3f32ce39946c339297821 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:23 +0000 Subject: regulator: lp87565: Remove redundant of_match_ptr() macros Since the driver lp87565-regulator depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove of_match_ptr() macros to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-3-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/lp87565-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index bdb60d8a7f3d..61ee5cf3f241 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -29,8 +29,8 @@ enum LP87565_regulator_id { .name = _name, \ .supply_name = _of "-in", \ .id = _id, \ - .of_match = of_match_ptr(_of), \ - .regulators_node = of_match_ptr("regulators"),\ + .of_match = _of, \ + .regulators_node = "regulators", \ .ops = &_ops, \ .n_voltages = _n, \ .type = REGULATOR_VOLTAGE, \ -- cgit v1.2.3-70-g09d2 From 656ed7467623674e6cc794a5b2ef79e8b8b81c3f Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:24 +0000 Subject: regulator: hi6421: Remove redundant of_match_ptr() macros Since the driver hi6421-regulator depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove of_match_ptr() macros to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-4-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/hi6421-regulator.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index 1b52423598d3..82e9e364d4d4 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -131,8 +131,8 @@ static const struct regulator_ops hi6421_buck345_ops; [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ - .of_match = of_match_ptr(#_match), \ - .regulators_node = of_match_ptr("regulators"), \ + .of_match = #_match, \ + .regulators_node = "regulators", \ .ops = &hi6421_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -170,8 +170,8 @@ static const struct regulator_ops hi6421_buck345_ops; [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ - .of_match = of_match_ptr(#_match), \ - .regulators_node = of_match_ptr("regulators"), \ + .of_match = #_match, \ + .regulators_node = "regulators", \ .ops = &hi6421_ldo_linear_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -210,8 +210,8 @@ static const struct regulator_ops hi6421_buck345_ops; [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ - .of_match = of_match_ptr(#_match), \ - .regulators_node = of_match_ptr("regulators"), \ + .of_match = #_match, \ + .regulators_node = "regulators", \ .ops = &hi6421_ldo_linear_range_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -247,8 +247,8 @@ static const struct regulator_ops hi6421_buck345_ops; [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ - .of_match = of_match_ptr(#_match), \ - .regulators_node = of_match_ptr("regulators"), \ + .of_match = #_match, \ + .regulators_node = "regulators", \ .ops = &hi6421_buck012_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -284,8 +284,8 @@ static const struct regulator_ops hi6421_buck345_ops; [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ - .of_match = of_match_ptr(#_match), \ - .regulators_node = of_match_ptr("regulators"), \ + .of_match = #_match, \ + .regulators_node = "regulators", \ .ops = &hi6421_buck345_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ -- cgit v1.2.3-70-g09d2 From 3988795eb08c4239e865c4c21a3d5fd6fb2bd055 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:25 +0000 Subject: regulator: mcp16502: Remove redundant of_match_ptr() macros Since the driver mcp16502 depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove of_match_ptr() macros to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-5-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/mcp16502.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index 7a472a2ef48a..0c15a19fe83a 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -110,7 +110,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode) #define MCP16502_REGULATOR(_name, _id, _ranges, _ops, _ramp_table) \ [_id] = { \ .name = _name, \ - .regulators_node = of_match_ptr("regulators"), \ + .regulators_node = "regulators", \ .id = _id, \ .ops = &(_ops), \ .type = REGULATOR_VOLTAGE, \ @@ -119,7 +119,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode) .linear_ranges = _ranges, \ .linear_min_sel = VDD_LOW_SEL, \ .n_linear_ranges = ARRAY_SIZE(_ranges), \ - .of_match = of_match_ptr(_name), \ + .of_match = _name, \ .of_map_mode = mcp16502_of_map_mode, \ .vsel_reg = (((_id) + 1) << 4), \ .vsel_mask = MCP16502_VSEL, \ @@ -587,7 +587,7 @@ static struct i2c_driver mcp16502_drv = { .driver = { .name = "mcp16502-regulator", .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(mcp16502_ids), + .of_match_table = mcp16502_ids, #ifdef CONFIG_PM .pm = &mcp16502_pm_ops, #endif -- cgit v1.2.3-70-g09d2 From c329adf3026034c84ddd61c0b19db53d40510ae7 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:26 +0000 Subject: regulator: mpq7920: Remove redundant of_match_ptr() macro Since the driver mpq7920 depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove the of_match_ptr() macro to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-6-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/mpq7920.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/mpq7920.c b/drivers/regulator/mpq7920.c index 4926c229109b..a670e09891e7 100644 --- a/drivers/regulator/mpq7920.c +++ b/drivers/regulator/mpq7920.c @@ -318,7 +318,7 @@ static struct i2c_driver mpq7920_regulator_driver = { .driver = { .name = "mpq7920", .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(mpq7920_of_match), + .of_match_table = mpq7920_of_match, }, .probe = mpq7920_i2c_probe, .id_table = mpq7920_id, -- cgit v1.2.3-70-g09d2 From 9e8925eb7fd6e5d93d9dfa9ca4628e897f0db8f1 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:27 +0000 Subject: regulator: pfuze100-regulator: Remove redundant of_match_ptr() macro Since the driver pfuze100-regulator depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove the of_match_ptr() macro to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-7-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/pfuze100-regulator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 8d7e6c323324..46854602b3ea 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -699,8 +699,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client) return -ENOMEM; if (client->dev.of_node) { - match = of_match_device(of_match_ptr(pfuze_dt_ids), - &client->dev); + match = of_match_device(pfuze_dt_ids, &client->dev); if (!match) { dev_err(&client->dev, "Error: No device match found\n"); return -ENODEV; -- cgit v1.2.3-70-g09d2 From 252b9116aff4d04176adc931cd11f02169df54f1 Mon Sep 17 00:00:00 2001 From: Chen Jiahao Date: Wed, 9 Aug 2023 10:04:28 +0000 Subject: regulator: tps6286x-regulator: Remove redundant of_match_ptr() macros Since the driver tps6286x-regulator depends on CONFIG_OF, it makes no difference to wrap of_match_ptr() here. Remove of_match_ptr() macros to clean it up. Signed-off-by: Chen Jiahao Link: https://lore.kernel.org/r/20230809100428.2669817-8-chenjiahao16@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/tps6286x-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/tps6286x-regulator.c b/drivers/regulator/tps6286x-regulator.c index c06f6d1dc737..758c70269653 100644 --- a/drivers/regulator/tps6286x-regulator.c +++ b/drivers/regulator/tps6286x-regulator.c @@ -84,11 +84,11 @@ static unsigned int tps6286x_of_map_mode(unsigned int mode) static const struct regulator_desc tps6286x_reg = { .name = "tps6286x", - .of_match = of_match_ptr("SW"), + .of_match = "SW", .owner = THIS_MODULE, .ops = &tps6286x_regulator_ops, .of_map_mode = tps6286x_of_map_mode, - .regulators_node = of_match_ptr("regulators"), + .regulators_node = "regulators", .type = REGULATOR_VOLTAGE, .n_voltages = ((TPS6286X_MAX_MV - TPS6286X_MIN_MV) / TPS6286X_STEP_MV) + 1, .min_uV = TPS6286X_MIN_MV * 1000, @@ -148,7 +148,7 @@ static struct i2c_driver tps6286x_regulator_driver = { .driver = { .name = "tps6286x", .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(tps6286x_dt_ids), + .of_match_table = tps6286x_dt_ids, }, .probe = tps6286x_i2c_probe, .id_table = tps6286x_i2c_id, -- cgit v1.2.3-70-g09d2 From 55975401fdf86ffe4736a557ae9d6f3d81ee5ba6 Mon Sep 17 00:00:00 2001 From: Li Zetao Date: Thu, 10 Aug 2023 19:48:58 +0800 Subject: regulator: qcom_rpm-regulator: Use devm_kmemdup to replace devm_kmalloc + memcpy Use the helper function devm_kmemdup() rather than duplicating its implementation, which helps to enhance code readability. Signed-off-by: Li Zetao Link: https://lore.kernel.org/r/20230810114858.2103928-1-lizetao1@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_rpm-regulator.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index f95bc9208c13..9366488f0383 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -956,11 +956,10 @@ static int rpm_reg_probe(struct platform_device *pdev) } for (reg = match->data; reg->name; reg++) { - vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); + vreg = devm_kmemdup(&pdev->dev, reg->template, sizeof(*vreg), GFP_KERNEL); if (!vreg) return -ENOMEM; - memcpy(vreg, reg->template, sizeof(*vreg)); mutex_init(&vreg->lock); vreg->dev = &pdev->dev; -- cgit v1.2.3-70-g09d2 From fddc9bb6e277b99b0410410794d156e963aa8f0b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Aug 2023 13:19:12 +0200 Subject: regulator: ltc3589: Fix Wvoid-pointer-to-enum-cast warning 'variant' is an enum, thus cast of pointer on 64-bit compile test with W=1 causes: ltc3589.c:394:22: error: cast to smaller integer type 'enum ltc3589_variant' from 'const void *' [-Werror,-Wvoid-pointer-to-enum-cast] Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230810111914.204847-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/ltc3589.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index cf931b8c36dc..d892c2a5df7b 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -391,8 +391,7 @@ static int ltc3589_probe(struct i2c_client *client) i2c_set_clientdata(client, ltc3589); if (client->dev.of_node) - ltc3589->variant = (enum ltc3589_variant) - of_device_get_match_data(&client->dev); + ltc3589->variant = (uintptr_t)of_device_get_match_data(&client->dev); else ltc3589->variant = id->driver_data; ltc3589->dev = dev; -- cgit v1.2.3-70-g09d2 From b29f42c6629bb3bd3d479592d40a7e4c73461a01 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Aug 2023 13:19:13 +0200 Subject: regulator: max77857: Fix Wvoid-pointer-to-enum-cast warning 'id' is an enum, thus cast of pointer on 64-bit compile test with W=1 causes: max77857-regulator.c:56:24: error: cast to smaller integer type 'enum max77857_id' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast] Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230810111914.204847-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/max77857-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c index 44a510547318..145ad0281857 100644 --- a/drivers/regulator/max77857-regulator.c +++ b/drivers/regulator/max77857-regulator.c @@ -53,7 +53,7 @@ enum max77857_id { static bool max77857_volatile_reg(struct device *dev, unsigned int reg) { - enum max77857_id id = (enum max77857_id)dev_get_drvdata(dev); + enum max77857_id id = (uintptr_t)dev_get_drvdata(dev); switch (id) { case ID_MAX77831: @@ -91,7 +91,7 @@ static int max77857_get_status(struct regulator_dev *rdev) static unsigned int max77857_get_mode(struct regulator_dev *rdev) { - enum max77857_id id = (enum max77857_id)rdev_get_drvdata(rdev); + enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev); unsigned int regval; int ret; @@ -125,7 +125,7 @@ static unsigned int max77857_get_mode(struct regulator_dev *rdev) static int max77857_set_mode(struct regulator_dev *rdev, unsigned int mode) { - enum max77857_id id = (enum max77857_id)rdev_get_drvdata(rdev); + enum max77857_id id = (uintptr_t)rdev_get_drvdata(rdev); unsigned int reg, val; switch (id) { -- cgit v1.2.3-70-g09d2 From c418920567ae6101826cc05cda042f71435830d0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 10 Aug 2023 13:19:14 +0200 Subject: regulator: lp872x: Fix Wvoid-pointer-to-enum-cast warning 'id' is an enum, thus cast of pointer on 64-bit compile test with W=1 causes: lp872x.c:867:5: error: cast to smaller integer type 'enum lp872x_regulator_id' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast] Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230810111914.204847-3-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/lp872x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 63aa227b1813..942f37082cb1 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -864,7 +864,7 @@ static struct lp872x_platform_data for (i = 0; i < num_matches; i++) { pdata->regulator_data[i].id = - (enum lp872x_regulator_id)match[i].driver_data; + (uintptr_t)match[i].driver_data; pdata->regulator_data[i].init_data = match[i].init_data; } out: -- cgit v1.2.3-70-g09d2 From edff54ac96eb25f01d26cc68923a6dbbb5b2f440 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 14 Aug 2023 23:07:59 +0200 Subject: regulator: rtq2208: Switch back to use struct i2c_driver's .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct i2c_driver::probe_new is about to go away. Switch the driver to use the probe callback with the same prototype. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230814210759.26395-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/rtq2208-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c index 2463aea4192c..2d54844c4226 100644 --- a/drivers/regulator/rtq2208-regulator.c +++ b/drivers/regulator/rtq2208-regulator.c @@ -574,7 +574,7 @@ static struct i2c_driver rtq2208_driver = { .name = "rtq2208", .of_match_table = rtq2208_device_tables, }, - .probe_new = rtq2208_probe, + .probe = rtq2208_probe, }; module_i2c_driver(rtq2208_driver); -- cgit v1.2.3-70-g09d2 From e21ac64e669e960688e79bf5babeed63132dac8a Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Aug 2023 14:55:49 +0100 Subject: regulator: raa215300: Fix resource leak in case of error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clk_register_clkdev() allocates memory by calling vclkdev_alloc() and this memory is not freed in the error path. Similarly, resources allocated by clk_register_fixed_rate() are not freed in the error path. Fix these issues by using devm_clk_hw_register_fixed_rate() and devm_clk_hw_register_clkdev(). After this, the static variable clk is not needed. Replace it with  local variable hw in probe() and drop calling clk_unregister_fixed_rate() from raa215300_rtc_unregister_device(). Fixes: 7bce16630837 ("regulator: Add Renesas PMIC RAA215300 driver") Cc: stable@kernel.org Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20230816135550.146657-2-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- drivers/regulator/raa215300.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c index 848a03a2fbd4..898f53cac02c 100644 --- a/drivers/regulator/raa215300.c +++ b/drivers/regulator/raa215300.c @@ -38,8 +38,6 @@ #define RAA215300_REG_BLOCK_EN_RTC_EN BIT(6) #define RAA215300_RTC_DEFAULT_ADDR 0x6f -static struct clk *clk; - static const struct regmap_config raa215300_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -49,10 +47,6 @@ static const struct regmap_config raa215300_regmap_config = { static void raa215300_rtc_unregister_device(void *data) { i2c_unregister_device(data); - if (!clk) { - clk_unregister_fixed_rate(clk); - clk = NULL; - } } static int raa215300_clk_present(struct i2c_client *client, const char *name) @@ -130,10 +124,16 @@ static int raa215300_i2c_probe(struct i2c_client *client) u32 addr = RAA215300_RTC_DEFAULT_ADDR; struct i2c_board_info info = {}; struct i2c_client *rtc_client; + struct clk_hw *hw; ssize_t size; - clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 32000); - clk_register_clkdev(clk, clk_name, NULL); + hw = devm_clk_hw_register_fixed_rate(dev, clk_name, NULL, 0, 32000); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + ret = devm_clk_hw_register_clkdev(dev, hw, clk_name, NULL); + if (ret) + return dev_err_probe(dev, ret, "Failed to initialize clkdev\n"); if (np) { int i; -- cgit v1.2.3-70-g09d2 From 727d7c1c3695657873d62030b968ba97c8698c54 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 16 Aug 2023 14:55:50 +0100 Subject: regulator: raa215300: Add const definition Add const definition to the initialized local variable name to avoid overriding. Also the second parameter in strscpy is const char * instead of char *. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20230816135550.146657-3-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- drivers/regulator/raa215300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c index 898f53cac02c..bdbf1e4ce468 100644 --- a/drivers/regulator/raa215300.c +++ b/drivers/regulator/raa215300.c @@ -119,7 +119,7 @@ static int raa215300_i2c_probe(struct i2c_client *client) } if (clk_name) { - char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0"; + const char *name = pmic_version >= 0x12 ? "isl1208" : "raa215300_a0"; struct device_node *np = client->dev.of_node; u32 addr = RAA215300_RTC_DEFAULT_ADDR; struct i2c_board_info info = {}; -- cgit v1.2.3-70-g09d2 From 35acbdfaf17c94d64ee336282f21b2981676748a Mon Sep 17 00:00:00 2001 From: Yue Haibing Date: Fri, 18 Aug 2023 20:42:27 +0800 Subject: regulator: db8500-prcmu: Remove unused declaration power_state_active_is_enabled() Commit 38e968380b27 ("regulators/db8500: split off shared dbx500 code") removed this but not its declaration. Signed-off-by: Yue Haibing Link: https://lore.kernel.org/r/20230818124227.15084-1-yuehaibing@huawei.com Signed-off-by: Mark Brown --- include/linux/regulator/db8500-prcmu.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/linux/regulator/db8500-prcmu.h b/include/linux/regulator/db8500-prcmu.h index f90df9ee703e..d58ff273157e 100644 --- a/include/linux/regulator/db8500-prcmu.h +++ b/include/linux/regulator/db8500-prcmu.h @@ -35,10 +35,4 @@ enum db8500_regulator_id { DB8500_NUM_REGULATORS }; -/* - * Exported interface for CPUIdle only. This function is called with all - * interrupts turned off. - */ -int power_state_active_is_enabled(void); - #endif -- cgit v1.2.3-70-g09d2 From 5c1212a67e5838aca49707ef96be71612a72ab43 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 18 Aug 2023 15:18:13 +0100 Subject: regulator: raa215300: Change rate from 32000->32768 Replace the rate 32000->32768 in devm_clk_hw_register_fixed_rate() as the 32kHz frequency mentioned in the hardware manual is actually 32.768kHz. Reported-by: Pavel Machek Closes: https://lore.kernel.org/all/ZN3%2FSjL50ls+3dnD@duo.ucw.cz/ Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20230818141815.314197-2-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- drivers/regulator/raa215300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c index bdbf1e4ce468..0628ed3d0a93 100644 --- a/drivers/regulator/raa215300.c +++ b/drivers/regulator/raa215300.c @@ -127,7 +127,7 @@ static int raa215300_i2c_probe(struct i2c_client *client) struct clk_hw *hw; ssize_t size; - hw = devm_clk_hw_register_fixed_rate(dev, clk_name, NULL, 0, 32000); + hw = devm_clk_hw_register_fixed_rate(dev, clk_name, NULL, 0, 32768); if (IS_ERR(hw)) return PTR_ERR(hw); -- cgit v1.2.3-70-g09d2 From 6673fc98953231f5d85f780d3025ea95c7584683 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 18 Aug 2023 15:18:14 +0100 Subject: regulator: raa215300: Add missing blank space Add the missing space in the comment block. Reported-by: Pavel Machek Closes: https://lore.kernel.org/all/ZN3%2FSjL50ls+3dnD@duo.ucw.cz/ Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20230818141815.314197-3-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- drivers/regulator/raa215300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/raa215300.c b/drivers/regulator/raa215300.c index 0628ed3d0a93..6982565c8aa4 100644 --- a/drivers/regulator/raa215300.c +++ b/drivers/regulator/raa215300.c @@ -86,7 +86,7 @@ static int raa215300_i2c_probe(struct i2c_client *client) val &= RAA215300_REG_BLOCK_EN_RTC_EN; regmap_write(regmap, RAA215300_REG_BLOCK_EN, val); - /*Clear the latched registers */ + /* Clear the latched registers */ regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_1, &val); regmap_write(regmap, RAA215300_FAULT_LATCHED_STATUS_1, val); regmap_read(regmap, RAA215300_FAULT_LATCHED_STATUS_2, &val); -- cgit v1.2.3-70-g09d2 From 8845252f6690e4fceca67f2bb7ee2920939d3ac5 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 18 Aug 2023 15:18:15 +0100 Subject: regulator: raa215300: Update help description Add module description to the help section and update the existing help description. Reported-by: Pavel Machek Closes: https://lore.kernel.org/all/ZN3%2FSjL50ls+3dnD@duo.ucw.cz/ Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20230818141815.314197-4-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 086596239356..186b97c5aa16 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1072,7 +1072,11 @@ config REGULATOR_RAA215300 depends on COMMON_CLK depends on I2C help - Support for the Renesas RAA215300 PMIC. + If you say yes to this option, support will be included for the + Renesas RAA215300 PMIC. + + Say M here if you want to include support for Renesas RAA215300 PMIC + as a module. The module will be named "raa215300". config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator" -- cgit v1.2.3-70-g09d2 From c01467355f8eb126cab0ef28b66bb506fe6a2e21 Mon Sep 17 00:00:00 2001 From: Andre Werner Date: Fri, 18 Aug 2023 10:37:21 +0200 Subject: mfd: tps65086: Read DEVICE ID register 1 from device This commit prepares a following commit for the regulator part of the MFD. The driver should support different device chips that differ in their register definitions, for instance to control LDOA1 and SWB2. So it is necessary to use a dedicated regulator description for a specific device variant. Thus, the content from DEVICEID Register 1 is used to choose a dedicated configuration between the different device variants. Signed-off-by: Andre Werner Link: https://lore.kernel.org/r/20230818083721.29790-2-andre.werner@systec-electronic.com Signed-off-by: Lee Jones --- drivers/mfd/tps65086.c | 17 ++++++++++++----- include/linux/mfd/tps65086.h | 20 ++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c index 6a21000aad4a..9bb7d7d8dcfc 100644 --- a/drivers/mfd/tps65086.c +++ b/drivers/mfd/tps65086.c @@ -81,16 +81,23 @@ static int tps65086_probe(struct i2c_client *client) return PTR_ERR(tps->regmap); } - ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version); + /* Store device ID to load regulator configuration that fit to IC variant */ + ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &tps->chip_id); if (ret) { - dev_err(tps->dev, "Failed to read revision register\n"); + dev_err(tps->dev, "Failed to read revision register 1\n"); + return ret; + } + + ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version); + if (ret) { + dev_err(tps->dev, "Failed to read revision register 2\n"); return ret; } dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n", - (version & TPS65086_DEVICEID_PART_MASK), - (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A', - (version & TPS65086_DEVICEID_REV_MASK) >> 6); + (version & TPS65086_DEVICEID2_PART_MASK), + (char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A', + (version & TPS65086_DEVICEID2_REV_MASK) >> 6); if (tps->irq > 0) { ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0, diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h index 16f87cccc003..87e590de6ca5 100644 --- a/include/linux/mfd/tps65086.h +++ b/include/linux/mfd/tps65086.h @@ -13,8 +13,9 @@ #include /* List of registers for TPS65086 */ -#define TPS65086_DEVICEID 0x01 -#define TPS65086_IRQ 0x02 +#define TPS65086_DEVICEID1 0x00 +#define TPS65086_DEVICEID2 0x01 +#define TPS65086_IRQ 0x02 #define TPS65086_IRQ_MASK 0x03 #define TPS65086_PMICSTAT 0x04 #define TPS65086_SHUTDNSRC 0x05 @@ -75,10 +76,16 @@ #define TPS65086_IRQ_SHUTDN_MASK BIT(3) #define TPS65086_IRQ_FAULT_MASK BIT(7) -/* DEVICEID Register field definitions */ -#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0) -#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4) -#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6) +/* DEVICEID1 Register field definitions */ +#define TPS6508640_ID 0x00 +#define TPS65086401_ID 0x01 +#define TPS6508641_ID 0x10 +#define TPS65086470_ID 0x70 + +/* DEVICEID2 Register field definitions */ +#define TPS65086_DEVICEID2_PART_MASK GENMASK(3, 0) +#define TPS65086_DEVICEID2_OTP_MASK GENMASK(5, 4) +#define TPS65086_DEVICEID2_REV_MASK GENMASK(7, 6) /* VID Masks */ #define BUCK_VID_MASK GENMASK(7, 1) @@ -100,6 +107,7 @@ enum tps65086_irqs { struct tps65086 { struct device *dev; struct regmap *regmap; + unsigned int chip_id; /* IRQ Data */ int irq; -- cgit v1.2.3-70-g09d2 From 3a5e6e49855661ad39b8fbb1dbd041178af98e00 Mon Sep 17 00:00:00 2001 From: Andre Werner Date: Fri, 18 Aug 2023 10:37:24 +0200 Subject: regulator: tps65086: Select dedicated regulator config for chip variant Some configurations differ between chip variants, e,g. the register to control the on of state of LDOA1 and SWB2. Thus, it is necessary to choose the correct configuration for a dedicated device. If the wrong configuration was used, the LDOA1 output that was disabled by the bootloader was enabled in Kernel again. Each chip variant gets its dedicated configuration selected by the chip ID previously collected from MFD probe function. The VTT enum value (tps65086_regulators) is shifted because not all chip variants have a separate SWB2 switch. Sometimes they are merged. So the configuration possibilities differ, thus the regulator configuration arrays have a different length. Signed-off-by: Andre Werner Link: https://lore.kernel.org/r/20230818083721.29790-5-andre.werner@systec-electronic.com Signed-off-by: Mark Brown --- drivers/regulator/tps65086-regulator.c | 188 +++++++++++++++++++++++++++++++-- include/linux/mfd/tps65086.h | 3 + 2 files changed, 183 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index 663789198ba5..2d284c64eeb7 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -15,7 +15,15 @@ #include enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1, - LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT }; + LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 }; + +/* Selector for regulator configuration regarding PMIC chip ID. */ +enum tps65086_ids { + TPS6508640 = 0, + TPS65086401, + TPS6508641, + TPS65086470, +}; #define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \ [_id] = { \ @@ -57,12 +65,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1, }, \ } + +#define TPS65086_REGULATOR_CONFIG(_chip_id, _config) \ + [_chip_id] = { \ + .config = _config, \ + .num_elems = ARRAY_SIZE(_config), \ + } + struct tps65086_regulator { struct regulator_desc desc; unsigned int decay_reg; unsigned int decay_mask; }; +struct tps65086_regulator_config { + struct tps65086_regulator * const config; + const unsigned int num_elems; +}; + static const struct linear_range tps65086_10mv_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000), @@ -114,7 +134,125 @@ static int tps65086_of_parse_cb(struct device_node *dev, const struct regulator_desc *desc, struct regulator_config *config); -static struct tps65086_regulator regulators[] = { +static struct tps65086_regulator tps6508640_regulator_config[] = { + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK1CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), + tps65086_10mv_ranges, TPS65086_BUCK2CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), + tps65086_10mv_ranges, TPS65086_BUCK3DECAY, + BIT(0)), + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK4VID, + BIT(0)), + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK5CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK6CTRL, + BIT(0)), + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, + VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7), + tps65086_ldoa1_ranges, 0, 0), + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), + TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), + TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)), +}; + +static struct tps65086_regulator tps65086401_regulator_config[] = { + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK1CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), + tps65086_10mv_ranges, TPS65086_BUCK2CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), + tps65086_10mv_ranges, TPS65086_BUCK3DECAY, + BIT(0)), + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK4VID, + BIT(0)), + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK5CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK6CTRL, + BIT(0)), + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, + VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7), + tps65086_ldoa1_ranges, 0, 0), + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), + TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), +}; + +static struct tps65086_regulator tps6508641_regulator_config[] = { + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK1CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), + tps65086_10mv_ranges, TPS65086_BUCK2CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), + tps65086_10mv_ranges, TPS65086_BUCK3DECAY, + BIT(0)), + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK4VID, + BIT(0)), + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK5CTRL, + BIT(0)), + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), + tps65086_10mv_ranges, TPS65086_BUCK6CTRL, + BIT(0)), + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, + VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7), + tps65086_ldoa1_ranges, 0, 0), + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), + tps65086_ldoa23_ranges, 0, 0), + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), + TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), +}; + +static struct tps65086_regulator tps65086470_regulator_config[] = { TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), tps65086_10mv_ranges, TPS65086_BUCK1CTRL, @@ -148,16 +286,25 @@ static struct tps65086_regulator regulators[] = { TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), tps65086_ldoa23_ranges, 0, 0), + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)), - TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), +}; + +static const struct tps65086_regulator_config regulator_configs[] = { + TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config), + TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config), + TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config), + TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config) }; static int tps65086_of_parse_cb(struct device_node *node, const struct regulator_desc *desc, struct regulator_config *config) { + struct tps65086 * const tps = dev_get_drvdata(config->dev); + struct tps65086_regulator *regulators = tps->reg_config->config; int ret; /* Check for 25mV step mode */ @@ -203,9 +350,30 @@ static int tps65086_regulator_probe(struct platform_device *pdev) { struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; + unsigned int selector_reg_config; struct regulator_dev *rdev; int i; + /* Select regulator configuration for used PMIC device */ + switch (tps->chip_id) { + case TPS6508640_ID: + selector_reg_config = TPS6508640; + break; + case TPS65086401_ID: + selector_reg_config = TPS65086401; + break; + case TPS6508641_ID: + selector_reg_config = TPS6508641; + break; + case TPS65086470_ID: + selector_reg_config = TPS65086470; + break; + default: + dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n"); + return -ENODEV; + } + tps->reg_config = ®ulator_configs[selector_reg_config]; + platform_set_drvdata(pdev, tps); config.dev = &pdev->dev; @@ -213,12 +381,16 @@ static int tps65086_regulator_probe(struct platform_device *pdev) config.driver_data = tps; config.regmap = tps->regmap; - for (i = 0; i < ARRAY_SIZE(regulators); i++) { - rdev = devm_regulator_register(&pdev->dev, ®ulators[i].desc, - &config); + for (i = 0; i < tps->reg_config->num_elems; ++i) { + struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc; + + dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n", + i, desc_ptr->name, desc_ptr->id); + + rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config); if (IS_ERR(rdev)) { - dev_err(tps->dev, "failed to register %s regulator\n", - pdev->name); + dev_err(tps->dev, "failed to register %d \"%s\" regulator\n", + i, desc_ptr->name); return PTR_ERR(rdev); } } diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h index 87e590de6ca5..9185b5cd8371 100644 --- a/include/linux/mfd/tps65086.h +++ b/include/linux/mfd/tps65086.h @@ -99,6 +99,8 @@ enum tps65086_irqs { TPS65086_IRQ_FAULT, }; +struct tps65086_regulator_config; + /** * struct tps65086 - state holder for the tps65086 driver * @@ -108,6 +110,7 @@ struct tps65086 { struct device *dev; struct regmap *regmap; unsigned int chip_id; + const struct tps65086_regulator_config *reg_config; /* IRQ Data */ int irq; -- cgit v1.2.3-70-g09d2 From 2796a01cdf2c639e605088c53a1ac36923ade93c Mon Sep 17 00:00:00 2001 From: Alec Li Date: Mon, 21 Aug 2023 03:53:54 +0000 Subject: regulator: aw37503: add regulator driver for Awinic AW37503 Add regulator driver for the device Awinic AW37503 which is single inductor - dual output power supply device. AW37503 device is designed to support general positive/negative driven applications like TFT display panels. AW37503 regulator driver supports to enable/disable and set voltage on its output. Signed-off-by: Alec Li Link: https://lore.kernel.org/r/20230821035355.1269976-2-like@awinic.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 8 ++ drivers/regulator/Makefile | 1 + drivers/regulator/aw37503-regulator.c | 240 ++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 drivers/regulator/aw37503-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 186b97c5aa16..965d4f0c18a6 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -178,6 +178,14 @@ config REGULATOR_ATC260X ATC260x PMICs. This will enable support for all the software controllable DCDC/LDO regulators. +config REGULATOR_AW37503 + tristate "Awinic AW37503 Dual Output Power regulators" + depends on I2C && GPIOLIB + select REGMAP_I2C + help + This driver supports AW37503 single inductor - dual output + power supply specifically designed for display panels. + config REGULATOR_AXP20X tristate "X-POWERS AXP20X PMIC Regulators" depends on MFD_AXP20X diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 08727557b402..23074714a81a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_ARM_SCMI) += scmi-regulator.o obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o obj-$(CONFIG_REGULATOR_ATC260X) += atc260x-regulator.o +obj-$(CONFIG_REGULATOR_AW37503) += aw37503-regulator.o obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o obj-$(CONFIG_REGULATOR_BD71815) += bd71815-regulator.o diff --git a/drivers/regulator/aw37503-regulator.c b/drivers/regulator/aw37503-regulator.c new file mode 100644 index 000000000000..e01ef6ad3eb8 --- /dev/null +++ b/drivers/regulator/aw37503-regulator.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// AWINIC AW37503 Regulator Driver +// +// Copyright (C) 2023 awinic. All Rights Reserved +// +// Author: + +#include +#include +#include +#include +#include +#include +#include + +#define AW37503_REG_VPOS 0x00 +#define AW37503_REG_VNEG 0x01 +#define AW37503_REG_APPS 0x03 +#define AW37503_REG_CONTROL 0x04 +#define AW37503_REG_WPRTEN 0x21 + +#define AW37503_VOUT_MASK 0x1F +#define AW37503_VOUT_N_VOLTAGE 0x15 +#define AW37503_VOUT_VMIN 4000000 +#define AW37503_VOUT_VMAX 6000000 +#define AW37503_VOUT_STEP 100000 + +#define AW37503_REG_APPS_DIS_VPOS BIT(1) +#define AW37503_REG_APPS_DIS_VNEG BIT(0) + +#define AW37503_REGULATOR_ID_VPOS 0 +#define AW37503_REGULATOR_ID_VNEG 1 +#define AW37503_MAX_REGULATORS 2 + +struct aw37503_reg_pdata { + struct gpio_desc *en_gpiod; + int ena_gpio_state; +}; + +struct aw37503_regulator { + struct device *dev; + struct aw37503_reg_pdata reg_pdata[AW37503_MAX_REGULATORS]; +}; + +static int aw37503_regulator_enable(struct regulator_dev *rdev) +{ + struct aw37503_regulator *chip = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id]; + int ret; + + if (!IS_ERR(rpdata->en_gpiod)) { + gpiod_set_value_cansleep(rpdata->en_gpiod, 1); + rpdata->ena_gpio_state = 1; + } + + /* Hardware automatically enable discharge bit in enable */ + if (rdev->constraints->active_discharge == + REGULATOR_ACTIVE_DISCHARGE_DISABLE) { + ret = regulator_set_active_discharge_regmap(rdev, false); + if (ret < 0) { + dev_err(chip->dev, "Failed to disable active discharge: %d\n", + ret); + return ret; + } + } + + return 0; +} + +static int aw37503_regulator_disable(struct regulator_dev *rdev) +{ + struct aw37503_regulator *chip = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id]; + + if (!IS_ERR(rpdata->en_gpiod)) { + gpiod_set_value_cansleep(rpdata->en_gpiod, 0); + rpdata->ena_gpio_state = 0; + } + + return 0; +} + +static int aw37503_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct aw37503_regulator *chip = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[id]; + + if (!IS_ERR(rpdata->en_gpiod)) + return rpdata->ena_gpio_state; + + return 1; +} + +static const struct regulator_ops aw37503_regulator_ops = { + .enable = aw37503_regulator_enable, + .disable = aw37503_regulator_disable, + .is_enabled = aw37503_regulator_is_enabled, + .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, + .set_active_discharge = regulator_set_active_discharge_regmap, +}; + +static int aw37503_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *config) +{ + struct aw37503_regulator *chip = config->driver_data; + struct aw37503_reg_pdata *rpdata = &chip->reg_pdata[desc->id]; + int ret; + + rpdata->en_gpiod = devm_fwnode_gpiod_get(chip->dev, of_fwnode_handle(np), + "enable", GPIOD_OUT_LOW, + "enable"); + + if (IS_ERR(rpdata->en_gpiod)) { + ret = PTR_ERR(rpdata->en_gpiod); + + /* Ignore the error other than probe defer */ + if (ret == -EPROBE_DEFER) + return ret; + return 0; + } + + return 0; +} + +#define AW37503_REGULATOR_DESC(_id, _name) \ + [AW37503_REGULATOR_ID_##_id] = { \ + .name = "aw37503-"#_name, \ + .supply_name = "vin", \ + .id = AW37503_REGULATOR_ID_##_id, \ + .of_match = of_match_ptr(#_name), \ + .of_parse_cb = aw37503_of_parse_cb, \ + .ops = &aw37503_regulator_ops, \ + .n_voltages = AW37503_VOUT_N_VOLTAGE, \ + .min_uV = AW37503_VOUT_VMIN, \ + .uV_step = AW37503_VOUT_STEP, \ + .enable_time = 500, \ + .vsel_mask = AW37503_VOUT_MASK, \ + .vsel_reg = AW37503_REG_##_id, \ + .active_discharge_off = 0, \ + .active_discharge_on = AW37503_REG_APPS_DIS_##_id, \ + .active_discharge_mask = AW37503_REG_APPS_DIS_##_id, \ + .active_discharge_reg = AW37503_REG_APPS, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +static const struct regulator_desc aw_regs_desc[AW37503_MAX_REGULATORS] = { + AW37503_REGULATOR_DESC(VPOS, outp), + AW37503_REGULATOR_DESC(VNEG, outn), +}; + +static const struct regmap_range aw37503_no_reg_ranges[] = { + regmap_reg_range(AW37503_REG_CONTROL + 1, + AW37503_REG_WPRTEN - 1), +}; + +static const struct regmap_access_table aw37503_no_reg_table = { + .no_ranges = aw37503_no_reg_ranges, + .n_no_ranges = ARRAY_SIZE(aw37503_no_reg_ranges), +}; + +static const struct regmap_config aw37503_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = AW37503_REG_WPRTEN, + .rd_table = &aw37503_no_reg_table, + .wr_table = &aw37503_no_reg_table, +}; + +static int aw37503_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct aw37503_regulator *chip; + struct regulator_dev *rdev; + struct regmap *regmap; + struct regulator_config config = { }; + int id; + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + regmap = devm_regmap_init_i2c(client, &aw37503_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to init regmap\n"); + + i2c_set_clientdata(client, chip); + chip->dev = dev; + + config.regmap = regmap; + config.dev = dev; + config.driver_data = chip; + + for (id = 0; id < AW37503_MAX_REGULATORS; ++id) { + rdev = devm_regulator_register(dev, &aw_regs_desc[id], + &config); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "Failed to register regulator %s\n", + aw_regs_desc[id].name); + } + return 0; +} + +static const struct i2c_device_id aw37503_id[] = { + {.name = "aw37503",}, + {}, +}; +MODULE_DEVICE_TABLE(i2c, aw37503_id); + +static const struct of_device_id aw37503_of_match[] = { + {.compatible = "awinic,aw37503",}, + { /* Sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, aw37503_of_match); + +static struct i2c_driver aw37503_i2c_driver = { + .driver = { + .name = "aw37503", + .of_match_table = aw37503_of_match, + }, + .probe_new = aw37503_probe, + .id_table = aw37503_id, +}; + +module_i2c_driver(aw37503_i2c_driver); + +MODULE_DESCRIPTION("aw37503 regulator driver"); +MODULE_AUTHOR("Alec Li "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 86a1b61a0c7316febecd03d47eaf893eb5a57659 Mon Sep 17 00:00:00 2001 From: Alec Li Date: Mon, 21 Aug 2023 03:53:55 +0000 Subject: regulator: dt-bindings: Add Awinic AW37503 Add aw37503 regulator device-tree binding documentation. Signed-off-by: Alec Li Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230821035355.1269976-3-like@awinic.com Signed-off-by: Mark Brown --- .../bindings/regulator/awinic,aw37503.yaml | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml diff --git a/Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml b/Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml new file mode 100644 index 000000000000..c92a881ed60e --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/awinic,aw37503.yaml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/awinic,aw37503.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Awinic AW37503 Voltage Regulator + +maintainers: + - Alec Li + +description: + The AW37503 are dual voltage regulator, designed to support positive/negative + supply for driving TFT-LCD panels. It support software-configurable output + switching and monitoring. The output voltages can be programmed via an I2C + compatible interface. + +properties: + compatible: + const: awinic,aw37503 + + reg: + maxItems: 1 + +patternProperties: + "^out[pn]$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + description: + Properties for single regulator. + + properties: + enable-gpios: + maxItems: 1 + description: + GPIO specifier to enable the GPIO control (on/off) for regulator. + + required: + - regulator-name + +required: + - compatible + - reg + - outp + - outn + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@3e { + compatible = "awinic,aw37503"; + reg = <0x3e>; + + outp { + regulator-name = "outp"; + regulator-boot-on; + regulator-always-on; + enable-gpios = <&gpio 17 GPIO_ACTIVE_LOW>; + }; + + outn { + regulator-name = "outn"; + regulator-boot-on; + regulator-always-on; + enable-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + }; + }; + }; +... + -- cgit v1.2.3-70-g09d2 From ed7c6a2ba6a682f191f289de01e8eb0a1366c3eb Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 22 Aug 2023 12:03:43 +0200 Subject: dt-bindings: regulator: qcom,rpmh-regulator: allow i, j, l, m & n as RPMh resource name suffix Add "i", "j", "l", "m" and "n" to the allowed subffix list as they can be used as RPMh resource name suffixes on new platforms. Signed-off-by: Neil Armstrong Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20230822-topic-sm8x50-upstream-rpmh-regulator-suffix-v2-1-136b315085a4@linaro.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index e758093365bc..127a6f39b7f0 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml @@ -92,7 +92,7 @@ properties: RPMh resource name suffix used for the regulators found on this PMIC. $ref: /schemas/types.yaml#/definitions/string - enum: [a, b, c, d, e, f, g, h, k] + enum: [a, b, c, d, e, f, g, h, i, j, k, l, m, n] qcom,always-wait-for-ack: description: | -- cgit v1.2.3-70-g09d2 From 21cc7f816c670423a9dae06ad7de5fbc40da97c7 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 24 Aug 2023 21:56:17 +0200 Subject: regulator: aw37503: Switch back to use struct i2c_driver's .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct i2c_driver::probe_new is about to go away. Switch the driver to use the probe callback with the same prototype. Signed-off-by: Uwe Kleine-König Date: Thu, 24 Aug 2023 23:48:22 +0100 Subject: regulator: userspace-consumer: Drop event support for this cycle Drop commit 22475bcc2083 ("regulator: userspace-consumer: Add regulator event support") since Zev Weiss points out that it leaks the constants we use for notifications out as ABI which isn't ideal, we should have something more abstracted there. There's a definite need for this feature but it needs some more work on the interface. Signed-off-by: Mark Brown events; - data->events = 0; - mutex_unlock(&events_lock); - - return sprintf(buf, "0x%lx\n", e); -} - static DEVICE_ATTR_RO(name); static DEVICE_ATTR_RW(state); -static DEVICE_ATTR_RO(events); static struct attribute *attributes[] = { &dev_attr_name.attr, &dev_attr_state.attr, - &dev_attr_events.attr, NULL, }; @@ -137,28 +115,12 @@ static const struct attribute_group attr_group = { .is_visible = attr_visible, }; -static int regulator_userspace_notify(struct notifier_block *nb, - unsigned long event, - void *ignored) -{ - struct userspace_consumer_data *data = - container_of(nb, struct userspace_consumer_data, nb); - - mutex_lock(&events_lock); - data->events |= event; - mutex_unlock(&events_lock); - - sysfs_notify(data->kobj, NULL, dev_attr_events.attr.name); - - return NOTIFY_OK; -} - static int regulator_userspace_consumer_probe(struct platform_device *pdev) { struct regulator_userspace_consumer_data tmpdata; struct regulator_userspace_consumer_data *pdata; struct userspace_consumer_data *drvdata; - int i, ret; + int ret; pdata = dev_get_platdata(&pdev->dev); if (!pdata) { @@ -191,7 +153,6 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) drvdata->num_supplies = pdata->num_supplies; drvdata->supplies = pdata->supplies; drvdata->no_autoswitch = pdata->no_autoswitch; - drvdata->kobj = &pdev->dev.kobj; mutex_init(&drvdata->lock); @@ -225,13 +186,6 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) } drvdata->enabled = !!ret; - drvdata->nb.notifier_call = regulator_userspace_notify; - for (i = 0; i < drvdata->num_supplies; i++) { - ret = devm_regulator_register_notifier(drvdata->supplies[i].consumer, &drvdata->nb); - if (ret) - goto err_enable; - } - return 0; err_enable: @@ -243,10 +197,6 @@ err_enable: static int regulator_userspace_consumer_remove(struct platform_device *pdev) { struct userspace_consumer_data *data = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < data->num_supplies; i++) - devm_regulator_unregister_notifier(data->supplies[i].consumer, &data->nb); sysfs_remove_group(&pdev->dev.kobj, &attr_group); -- cgit v1.2.3-70-g09d2