From 54bd53b9c11ed856abeedbf1ce92a19b546f56cf Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Fri, 12 Jun 2020 12:05:18 +0800 Subject: [PATCH 01/67] dt-bindings: regulator: Add DT binding for cros-ec-regulator Add DT binding documentation for cros-ec-regulator, a voltage regulator controlled by ChromeOS EC. Signed-off-by: Pi-Hsun Shih Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20200612040526.192878-2-pihsun@chromium.org Signed-off-by: Mark Brown --- .../regulator/google,cros-ec-regulator.yaml | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/google,cros-ec-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/google,cros-ec-regulator.yaml b/Documentation/devicetree/bindings/regulator/google,cros-ec-regulator.yaml new file mode 100644 index 000000000000..c9453d7ce227 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/google,cros-ec-regulator.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/google,cros-ec-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ChromeOS EC controlled voltage regulators + +maintainers: + - Pi-Hsun Shih + +description: + Any property defined as part of the core regulator binding, defined in + regulator.yaml, can also be used. + +allOf: + - $ref: "regulator.yaml#" + +properties: + compatible: + const: google,cros-ec-regulator + + reg: + maxItems: 1 + description: Identifier for the voltage regulator to ChromeOS EC. + +required: + - compatible + - reg + +examples: + - | + spi0 { + #address-cells = <1>; + #size-cells = <0>; + + cros_ec: ec@0 { + compatible = "google,cros-ec-spi"; + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + regulator@0 { + compatible = "google,cros-ec-regulator"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + reg = <0>; + }; + }; + }; +... From dff08caf35ecef4f7647f8b1e40877a254852a2b Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Fri, 12 Jun 2020 12:05:19 +0800 Subject: [PATCH 02/67] platform/chrome: cros_ec: Add command for regulator control. Add host commands for voltage regulator control through ChromeOS EC. Signed-off-by: Pi-Hsun Shih Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20200612040526.192878-3-pihsun@chromium.org Signed-off-by: Mark Brown --- drivers/platform/chrome/cros_ec_trace.c | 5 ++ .../linux/platform_data/cros_ec_commands.h | 82 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_trace.c b/drivers/platform/chrome/cros_ec_trace.c index 523a39bd0ff6..425e9441b7ca 100644 --- a/drivers/platform/chrome/cros_ec_trace.c +++ b/drivers/platform/chrome/cros_ec_trace.c @@ -161,6 +161,11 @@ TRACE_SYMBOL(EC_CMD_ADC_READ), \ TRACE_SYMBOL(EC_CMD_ROLLBACK_INFO), \ TRACE_SYMBOL(EC_CMD_AP_RESET), \ + TRACE_SYMBOL(EC_CMD_REGULATOR_GET_INFO), \ + TRACE_SYMBOL(EC_CMD_REGULATOR_ENABLE), \ + TRACE_SYMBOL(EC_CMD_REGULATOR_IS_ENABLED), \ + TRACE_SYMBOL(EC_CMD_REGULATOR_SET_VOLTAGE), \ + TRACE_SYMBOL(EC_CMD_REGULATOR_GET_VOLTAGE), \ TRACE_SYMBOL(EC_CMD_CR51_BASE), \ TRACE_SYMBOL(EC_CMD_CR51_LAST), \ TRACE_SYMBOL(EC_CMD_FP_PASSTHRU), \ diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 69210881ebac..a417b51b5764 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -5430,6 +5430,88 @@ struct ec_response_rollback_info { /* Issue AP reset */ #define EC_CMD_AP_RESET 0x0125 +/*****************************************************************************/ +/* Voltage regulator controls */ + +/* + * Get basic info of voltage regulator for given index. + * + * Returns the regulator name and supported voltage list in mV. + */ +#define EC_CMD_REGULATOR_GET_INFO 0x012B + +/* Maximum length of regulator name */ +#define EC_REGULATOR_NAME_MAX_LEN 16 + +/* Maximum length of the supported voltage list. */ +#define EC_REGULATOR_VOLTAGE_MAX_COUNT 16 + +struct ec_params_regulator_get_info { + uint32_t index; +} __ec_align4; + +struct ec_response_regulator_get_info { + char name[EC_REGULATOR_NAME_MAX_LEN]; + uint16_t num_voltages; + uint16_t voltages_mv[EC_REGULATOR_VOLTAGE_MAX_COUNT]; +} __ec_align1; + +/* + * Configure the regulator as enabled / disabled. + */ +#define EC_CMD_REGULATOR_ENABLE 0x012C + +struct ec_params_regulator_enable { + uint32_t index; + uint8_t enable; +} __ec_align4; + +/* + * Query if the regulator is enabled. + * + * Returns 1 if the regulator is enabled, 0 if not. + */ +#define EC_CMD_REGULATOR_IS_ENABLED 0x012D + +struct ec_params_regulator_is_enabled { + uint32_t index; +} __ec_align4; + +struct ec_response_regulator_is_enabled { + uint8_t enabled; +} __ec_align1; + +/* + * Set voltage for the voltage regulator within the range specified. + * + * The driver should select the voltage in range closest to min_mv. + * + * Also note that this might be called before the regulator is enabled, and the + * setting should be in effect after the regulator is enabled. + */ +#define EC_CMD_REGULATOR_SET_VOLTAGE 0x012E + +struct ec_params_regulator_set_voltage { + uint32_t index; + uint32_t min_mv; + uint32_t max_mv; +} __ec_align4; + +/* + * Get the currently configured voltage for the voltage regulator. + * + * Note that this might be called before the regulator is enabled. + */ +#define EC_CMD_REGULATOR_GET_VOLTAGE 0x012F + +struct ec_params_regulator_get_voltage { + uint32_t index; +} __ec_align4; + +struct ec_response_regulator_get_voltage { + uint32_t voltage_mv; +} __ec_align4; + /*****************************************************************************/ /* The command range 0x200-0x2FF is reserved for Rotor. */ From 8d9f8d57e023893bfa708d83e3a787e77766a378 Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Fri, 12 Jun 2020 12:05:20 +0800 Subject: [PATCH 03/67] regulator: Add driver for cros-ec-regulator Add driver for cros-ec-regulator, representing a voltage regulator that is connected and controlled by ChromeOS EC, and is controlled by kernel with EC host commands. Signed-off-by: Pi-Hsun Shih Reviewed-by: Prashant Malani Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20200612040526.192878-4-pihsun@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/cros-ec-regulator.c | 257 ++++++++++++++++++++++++++ 3 files changed, 268 insertions(+) create mode 100644 drivers/regulator/cros-ec-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8f677f5d79b4..c398e90e0e73 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -238,6 +238,16 @@ config REGULATOR_CPCAP Say y here for CPCAP regulator found on some Motorola phones and tablets such as Droid 4. +config REGULATOR_CROS_EC + tristate "ChromeOS EC regulators" + depends on CROS_EC && OF + help + This driver supports voltage regulators that is connected to ChromeOS + EC and controlled through EC host commands. + + This driver can also be built as a module. If so, the module + will be called cros-ec-regulator. + config REGULATOR_DA903X tristate "Dialog Semiconductor DA9030/DA9034 regulators" depends on PMIC_DA903X diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index e8f163371071..46592c160d22 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o +obj-$(CONFIG_REGULATOR_CROS_EC) += cros-ec-regulator.o obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o diff --git a/drivers/regulator/cros-ec-regulator.c b/drivers/regulator/cros-ec-regulator.c new file mode 100644 index 000000000000..35f97246bc48 --- /dev/null +++ b/drivers/regulator/cros-ec-regulator.c @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright 2020 Google LLC. + +#include +#include +#include +#include +#include +#include +#include +#include + +struct cros_ec_regulator_data { + struct regulator_desc desc; + struct regulator_dev *dev; + struct cros_ec_device *ec_dev; + + u32 index; + + u16 *voltages_mV; + u16 num_voltages; +}; + +static int cros_ec_cmd(struct cros_ec_device *ec, u32 version, u32 command, + void *outdata, u32 outsize, void *indata, u32 insize) +{ + struct cros_ec_command *msg; + int ret; + + msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + msg->version = version; + msg->command = command; + msg->outsize = outsize; + msg->insize = insize; + + if (outdata && outsize > 0) + memcpy(msg->data, outdata, outsize); + + ret = cros_ec_cmd_xfer_status(ec, msg); + if (ret < 0) + goto cleanup; + + if (insize) + memcpy(indata, msg->data, insize); + +cleanup: + kfree(msg); + return ret; +} + +static int cros_ec_regulator_enable(struct regulator_dev *dev) +{ + struct cros_ec_regulator_data *data = rdev_get_drvdata(dev); + struct ec_params_regulator_enable cmd = { + .index = data->index, + .enable = 1, + }; + + return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd, + sizeof(cmd), NULL, 0); +} + +static int cros_ec_regulator_disable(struct regulator_dev *dev) +{ + struct cros_ec_regulator_data *data = rdev_get_drvdata(dev); + struct ec_params_regulator_enable cmd = { + .index = data->index, + .enable = 0, + }; + + return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd, + sizeof(cmd), NULL, 0); +} + +static int cros_ec_regulator_is_enabled(struct regulator_dev *dev) +{ + struct cros_ec_regulator_data *data = rdev_get_drvdata(dev); + struct ec_params_regulator_is_enabled cmd = { + .index = data->index, + }; + struct ec_response_regulator_is_enabled resp; + int ret; + + ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_IS_ENABLED, &cmd, + sizeof(cmd), &resp, sizeof(resp)); + if (ret < 0) + return ret; + return resp.enabled; +} + +static int cros_ec_regulator_list_voltage(struct regulator_dev *dev, + unsigned int selector) +{ + struct cros_ec_regulator_data *data = rdev_get_drvdata(dev); + + if (selector >= data->num_voltages) + return -EINVAL; + + return data->voltages_mV[selector] * 1000; +} + +static int cros_ec_regulator_get_voltage(struct regulator_dev *dev) +{ + struct cros_ec_regulator_data *data = rdev_get_drvdata(dev); + struct ec_params_regulator_get_voltage cmd = { + .index = data->index, + }; + struct ec_response_regulator_get_voltage resp; + int ret; + + ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_VOLTAGE, &cmd, + sizeof(cmd), &resp, sizeof(resp)); + if (ret < 0) + return ret; + return resp.voltage_mv * 1000; +} + +static int cros_ec_regulator_set_voltage(struct regulator_dev *dev, int min_uV, + int max_uV, unsigned int *selector) +{ + struct cros_ec_regulator_data *data = rdev_get_drvdata(dev); + int min_mV = DIV_ROUND_UP(min_uV, 1000); + int max_mV = max_uV / 1000; + struct ec_params_regulator_set_voltage cmd = { + .index = data->index, + .min_mv = min_mV, + .max_mv = max_mV, + }; + + /* + * This can happen when the given range [min_uV, max_uV] doesn't + * contain any voltage that can be represented exactly in mV. + */ + if (min_mV > max_mV) + return -EINVAL; + + return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_SET_VOLTAGE, &cmd, + sizeof(cmd), NULL, 0); +} + +static struct regulator_ops cros_ec_regulator_voltage_ops = { + .enable = cros_ec_regulator_enable, + .disable = cros_ec_regulator_disable, + .is_enabled = cros_ec_regulator_is_enabled, + .list_voltage = cros_ec_regulator_list_voltage, + .get_voltage = cros_ec_regulator_get_voltage, + .set_voltage = cros_ec_regulator_set_voltage, +}; + +static int cros_ec_regulator_init_info(struct device *dev, + struct cros_ec_regulator_data *data) +{ + struct ec_params_regulator_get_info cmd = { + .index = data->index, + }; + struct ec_response_regulator_get_info resp; + int ret; + + ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_INFO, &cmd, + sizeof(cmd), &resp, sizeof(resp)); + if (ret < 0) + return ret; + + data->num_voltages = + min_t(u16, ARRAY_SIZE(resp.voltages_mv), resp.num_voltages); + data->voltages_mV = + devm_kmemdup(dev, resp.voltages_mv, + sizeof(u16) * data->num_voltages, GFP_KERNEL); + data->desc.n_voltages = data->num_voltages; + + /* Make sure the returned name is always a valid string */ + resp.name[ARRAY_SIZE(resp.name) - 1] = '\0'; + data->desc.name = devm_kstrdup(dev, resp.name, GFP_KERNEL); + if (!data->desc.name) + return -ENOMEM; + + return 0; +} + +static int cros_ec_regulator_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct cros_ec_regulator_data *drvdata; + struct regulator_init_data *init_data; + struct regulator_config cfg = {}; + struct regulator_desc *desc; + int ret; + + drvdata = devm_kzalloc( + &pdev->dev, sizeof(struct cros_ec_regulator_data), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->ec_dev = dev_get_drvdata(dev->parent); + desc = &drvdata->desc; + + init_data = of_get_regulator_init_data(dev, np, desc); + if (!init_data) + return -EINVAL; + + ret = of_property_read_u32(np, "reg", &drvdata->index); + if (ret < 0) + return ret; + + desc->owner = THIS_MODULE; + desc->type = REGULATOR_VOLTAGE; + desc->ops = &cros_ec_regulator_voltage_ops; + + ret = cros_ec_regulator_init_info(dev, drvdata); + if (ret < 0) + return ret; + + cfg.dev = &pdev->dev; + cfg.init_data = init_data; + cfg.driver_data = drvdata; + cfg.of_node = np; + + drvdata->dev = devm_regulator_register(dev, &drvdata->desc, &cfg); + if (IS_ERR(drvdata->dev)) { + ret = PTR_ERR(drvdata->dev); + dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); + goto free_name; + } + + platform_set_drvdata(pdev, drvdata); + + return 0; + +free_name: + kfree(desc->name); + return ret; +} + +static const struct of_device_id regulator_cros_ec_of_match[] = { + { .compatible = "google,cros-ec-regulator", }, + {} +}; +MODULE_DEVICE_TABLE(of, regulator_cros_ec_of_match); + +static struct platform_driver cros_ec_regulator_driver = { + .probe = cros_ec_regulator_probe, + .driver = { + .name = "cros-ec-regulator", + .of_match_table = regulator_cros_ec_of_match, + }, +}; + +module_platform_driver(cros_ec_regulator_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ChromeOS EC controlled regulator"); +MODULE_AUTHOR("Pi-Hsun Shih "); From 1f0b740004f09d2f1b716fd6c2fdca81004ded05 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 9 Jun 2020 13:46:09 +0100 Subject: [PATCH 04/67] regulator: gpio: Fix trivial spelling decriptor -> descriptor. Signed-off-by: Kieran Bingham Link: https://lore.kernel.org/r/20200609124610.3445662-17-kieran.bingham+renesas@ideasonboard.com Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 110ee6fe76c4..181451f922f1 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -311,7 +311,7 @@ static int gpio_regulator_probe(struct platform_device *pdev) /* * The signal will be inverted by the GPIO core if flagged so in the - * decriptor. + * descriptor. */ if (config->enabled_at_boot) gflags = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE; From d3f3723387f97118c337689fc73e4199fb4331ce Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Tue, 9 Jun 2020 13:46:02 +0100 Subject: [PATCH 05/67] regulator: Fix trivial spelling The word 'descriptor' is misspelled throughout the tree. Fix it up accordingly: decriptors -> descriptors Signed-off-by: Kieran Bingham Link: https://lore.kernel.org/r/20200609124610.3445662-10-kieran.bingham+renesas@ideasonboard.com Signed-off-by: Mark Brown --- drivers/regulator/fixed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index bc0bbd99e98d..d54830e48b8d 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -210,7 +210,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) /* * The signal will be inverted by the GPIO core if flagged so in the - * decriptor. + * descriptor. */ if (config->enabled_at_boot) gflags = GPIOD_OUT_HIGH; From cae62a937912bd4b3faf8e268cc0ffcf00ec5850 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 18 Jun 2020 00:32:43 +0200 Subject: [PATCH 06/67] regulator: anatop: Constify anatop_core_rops anatop_core_rops is not modified and can therefore be made const which allows the compiler to put it in read-only memory. Before: text data bss dec hex filename 4502 412 0 4914 1332 drivers/regulator/anatop-regulator.o After: text data bss dec hex filename 4634 280 0 4914 1332 drivers/regulator/anatop-regulator.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200617223247.25566-2-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index ca92b3de0e9c..f9856d4e295f 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -139,7 +139,7 @@ static struct regulator_ops anatop_rops = { .map_voltage = regulator_map_voltage_linear, }; -static struct regulator_ops anatop_core_rops = { +static const struct regulator_ops anatop_core_rops = { .enable = anatop_regmap_enable, .disable = anatop_regmap_disable, .is_enabled = anatop_regmap_is_enabled, From bcf39c1eb1e059ec612bf06f4aa7b3972dcc85e8 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 18 Jun 2020 00:32:44 +0200 Subject: [PATCH 07/67] regulator: cpcap: Constify cpcap_regulator_ops cpcap_regulator_ops is not modified and can be made const to allow the compiler to put it in read-only memory. Before: text data bss dec hex filename 14472 236 0 14708 3974 drivers/regulator/cpcap-regulator.o After: text data bss dec hex filename 14604 104 0 14708 3974 drivers/regulator/cpcap-regulator.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200617223247.25566-3-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/cpcap-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index f80781d58a28..14642603e755 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -256,7 +256,7 @@ static int cpcap_regulator_set_mode(struct regulator_dev *rdev, CPCAP_BIT_AUDIO_LOW_PWR, value); } -static struct regulator_ops cpcap_regulator_ops = { +static const struct regulator_ops cpcap_regulator_ops = { .enable = cpcap_regulator_enable, .disable = cpcap_regulator_disable, .is_enabled = regulator_is_enabled_regmap, From b37f076d4bfdd29b3aa497480b226759f659e25f Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 18 Jun 2020 00:32:45 +0200 Subject: [PATCH 08/67] regulator: ltc3676: Constify ltc3676_regulators ltc3676_regulators is not modified and can be made const to allow the compiler to put it in read-only memory. Before: text data bss dec hex filename 4361 2064 8 6433 1921 drivers/regulator/ltc3676.o After: text data bss dec hex filename 6121 304 8 6433 1921 drivers/regulator/ltc3676.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200617223247.25566-4-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/ltc3676.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c index e12e52c69e52..093b3e4a6303 100644 --- a/drivers/regulator/ltc3676.c +++ b/drivers/regulator/ltc3676.c @@ -221,7 +221,7 @@ static const struct regulator_ops ltc3676_fixed_regulator_ops = { #define LTC3676_FIXED_REG(_id, _name, _en_reg, _en_bit) \ LTC3676_REG(_id, _name, fixed, LTC3676_ ## _en_reg, _en_bit, 0, 0) -static struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = { +static const struct regulator_desc ltc3676_regulators[LTC3676_NUM_REGULATORS] = { LTC3676_LINEAR_REG(SW1, sw1, BUCK1, DVB1A), LTC3676_LINEAR_REG(SW2, sw2, BUCK2, DVB2A), LTC3676_LINEAR_REG(SW3, sw3, BUCK3, DVB3A), From b08af72d6e5319e96527816c4b3b08d0b1a6f242 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 18 Jun 2020 00:32:46 +0200 Subject: [PATCH 09/67] regulator: max8907: Constify static structs These are not modified so make them const to allow the compiler to put them in read-only memory. Before: text data bss dec hex filename 2753 7328 0 10081 2761 drivers/regulator/max8907-regulator.o After: text data bss dec hex filename 9405 684 0 10089 2769 drivers/regulator/max8907-regulator.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200617223247.25566-5-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/max8907-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c index 96dc0eea7659..1a6fd68f3fb1 100644 --- a/drivers/regulator/max8907-regulator.c +++ b/drivers/regulator/max8907-regulator.c @@ -109,7 +109,7 @@ struct max8907_regulator { static const struct regulator_ops max8907_mbatt_ops = { }; -static struct regulator_ops max8907_ldo_ops = { +static const struct regulator_ops max8907_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -128,7 +128,7 @@ static const struct regulator_ops max8907_fixed_ops = { .list_voltage = regulator_list_voltage_linear, }; -static struct regulator_ops max8907_out5v_ops = { +static const struct regulator_ops max8907_out5v_ops = { .list_voltage = regulator_list_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -145,7 +145,7 @@ static const struct regulator_ops max8907_bbat_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; -static struct regulator_desc max8907_regulators[] = { +static const struct regulator_desc max8907_regulators[] = { REG_MBATT(), REG_LDO(SD1, "in-v1", MAX8907_REG_SDCTL1, 650000, 2225000, 25000), REG_LDO(SD2, "in-v2", MAX8907_REG_SDCTL2, 637500, 1425000, 12500), From 9ed84d24de480e81294e00814c142234bc17ce0c Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 18 Jun 2020 00:32:47 +0200 Subject: [PATCH 10/67] regulator: max8997: Constify struct regulator_ops These are not modified so make them const to allow the compiler to put them in read-only memory. Before: text data bss dec hex filename 13114 8596 0 21710 54ce drivers/regulator/max8997-regulator.o After: text data bss dec hex filename 14038 7672 0 21710 54ce drivers/regulator/max8997-regulator.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200617223247.25566-6-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/max8997-regulator.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c index 4d2487279a0a..ba47a5e2fbcb 100644 --- a/drivers/regulator/max8997-regulator.c +++ b/drivers/regulator/max8997-regulator.c @@ -732,7 +732,7 @@ static int max8997_reg_disable_suspend(struct regulator_dev *rdev) return max8997_update_reg(i2c, reg, ~pattern, mask); } -static struct regulator_ops max8997_ldo_ops = { +static const struct regulator_ops max8997_ldo_ops = { .list_voltage = max8997_list_voltage, .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, @@ -742,7 +742,7 @@ static struct regulator_ops max8997_ldo_ops = { .set_suspend_disable = max8997_reg_disable_suspend, }; -static struct regulator_ops max8997_buck_ops = { +static const struct regulator_ops max8997_buck_ops = { .list_voltage = max8997_list_voltage, .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, @@ -753,7 +753,7 @@ static struct regulator_ops max8997_buck_ops = { .set_suspend_disable = max8997_reg_disable_suspend, }; -static struct regulator_ops max8997_fixedvolt_ops = { +static const struct regulator_ops max8997_fixedvolt_ops = { .list_voltage = max8997_list_voltage, .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, @@ -761,7 +761,7 @@ static struct regulator_ops max8997_fixedvolt_ops = { .set_suspend_disable = max8997_reg_disable_suspend, }; -static struct regulator_ops max8997_safeout_ops = { +static const struct regulator_ops max8997_safeout_ops = { .list_voltage = regulator_list_voltage_table, .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, @@ -771,7 +771,7 @@ static struct regulator_ops max8997_safeout_ops = { .set_suspend_disable = max8997_reg_disable_suspend, }; -static struct regulator_ops max8997_fixedstate_ops = { +static const struct regulator_ops max8997_fixedstate_ops = { .list_voltage = max8997_list_voltage_charger_cv, .get_voltage_sel = max8997_get_voltage_sel, .set_voltage = max8997_set_voltage_charger_cv, @@ -805,7 +805,7 @@ static int max8997_get_current_limit(struct regulator_dev *rdev) return max8997_list_voltage(rdev, sel); } -static struct regulator_ops max8997_charger_ops = { +static const struct regulator_ops max8997_charger_ops = { .is_enabled = max8997_reg_is_enabled, .enable = max8997_reg_enable, .disable = max8997_reg_disable, @@ -813,7 +813,7 @@ static struct regulator_ops max8997_charger_ops = { .set_current_limit = max8997_set_current_limit, }; -static struct regulator_ops max8997_charger_fixedstate_ops = { +static const struct regulator_ops max8997_charger_fixedstate_ops = { .get_current_limit = max8997_get_current_limit, .set_current_limit = max8997_set_current_limit, }; From a7503a9d8fcfac3fefdb63fc61efedef41635e94 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Tue, 23 Jun 2020 22:01:10 +0800 Subject: [PATCH 11/67] regulator: pfuze100: add condition check for 'ramp_delay = 0' Checking for 'ramp_delay = 0' to avoid Coverity warning report. Signed-off-by: Robin Gong Link: https://lore.kernel.org/r/1592920870-12693-1-git-send-email-yibin.gong@nxp.com Signed-off-by: Mark Brown --- drivers/regulator/pfuze100-regulator.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 4c8e8b472287..7e8ba9246167 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -128,7 +128,7 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); bool reg_has_ramp_delay; - unsigned int ramp_bits; + unsigned int ramp_bits = 0; int ret; switch (pfuze100->chip_id) { @@ -149,8 +149,11 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) } if (reg_has_ramp_delay) { - ramp_delay = 12500 / ramp_delay; - ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); + if (ramp_delay > 0) { + ramp_delay = 12500 / ramp_delay; + ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); + } + ret = regmap_update_bits(pfuze100->regmap, rdev->desc->vsel_reg + 4, 0xc0, ramp_bits << 6); From da6690767cbd344998f36081815c85f3d467e78c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:05 +0100 Subject: [PATCH 12/67] regulator: consumer: Supply missing prototypes for 3 core functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit regulator_suspend_enable(), regulator_suspend_disable() and regulator_set_suspend_voltage() are all exported members of the API, but are all missing prototypes. Fixes the following W=1 warning(s): drivers/regulator/core.c:3805:5: warning: no previous prototype for ‘regulator_suspend_enable’ [-Wmissing-prototypes] 3805 | int regulator_suspend_enable(struct regulator_dev *rdev, | ^~~~~~~~~~~~~~~~~~~~~~~~ drivers/regulator/core.c:3812:5: warning: no previous prototype for ‘regulator_suspend_disable’ [-Wmissing-prototypes] 3812 | int regulator_suspend_disable(struct regulator_dev *rdev, | ^~~~~~~~~~~~~~~~~~~~~~~~~ drivers/regulator/core.c:3851:5: warning: no previous prototype for ‘regulator_set_suspend_voltage’ [-Wmissing-prototypes] 3851 | int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-2-lee.jones@linaro.org Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 6a92fd3105a3..2024944fd2f7 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -32,10 +32,12 @@ #define __LINUX_REGULATOR_CONSUMER_H_ #include +#include struct device; struct notifier_block; struct regmap; +struct regulator_dev; /* * Regulator operating modes. @@ -277,6 +279,14 @@ int regulator_unregister_notifier(struct regulator *regulator, void devm_regulator_unregister_notifier(struct regulator *regulator, struct notifier_block *nb); +/* regulator suspend */ +int regulator_suspend_enable(struct regulator_dev *rdev, + suspend_state_t state); +int regulator_suspend_disable(struct regulator_dev *rdev, + suspend_state_t state); +int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, + int max_uV, suspend_state_t state); + /* driver data - core doesn't touch */ void *regulator_get_drvdata(struct regulator *regulator); void regulator_set_drvdata(struct regulator *regulator, void *data); From d3cc3dfcc20e72d537550dbeebbe4a8faa7c2606 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:08 +0100 Subject: [PATCH 13/67] regulator: dbx500-prcmu: Remove unused function dbx500_regulator_testcase() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There isn't any code present within the current kernel to override this 'weak' function. Besides returning '0', which is never checked anyway, the whole function appears to be superfluous. Consequently fixes W=1 warning: drivers/regulator/dbx500-prcmu.c:113:27: warning: no previous prototype for ‘dbx500_regulator_testcase’ [-Wmissing-prototypes] 113 | int __attribute__((weak)) dbx500_regulator_testcase( | ^~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-5-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/dbx500-prcmu.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index f604c8db6d0e..c3ad6aa6b5d3 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -110,13 +110,6 @@ static int ux500_regulator_status_show(struct seq_file *s, void *p) } DEFINE_SHOW_ATTRIBUTE(ux500_regulator_status); -int __attribute__((weak)) dbx500_regulator_testcase( - struct dbx500_regulator_info *regulator_info, - int num_regulators) -{ - return 0; -} - int ux500_regulator_debug_init(struct platform_device *pdev, struct dbx500_regulator_info *regulator_info, @@ -152,7 +145,6 @@ ux500_regulator_debug_init(struct platform_device *pdev, if (!rdebug.state_after_suspend) goto exit_free; - dbx500_regulator_testcase(regulator_info, num_regulators); return 0; exit_free: From aeee55b76bfd100d2612f50d2f9526d760ee2e37 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:09 +0100 Subject: [PATCH 14/67] regulator: ab8500: Remove unused embedded struct expand_register Used primarily for the AB8540 which lost support in early 2018. It is now deemed safe to remove this legacy data structure. Also fixes W=1 issue: drivers/regulator/ab8500.c:88: warning: Function parameter or member 'expand_register' not described in 'ab8500_regulator_info' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-6-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 716ca5bb178e..47b8b6f7b571 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -59,6 +59,7 @@ struct ab8500_shared_mode { * @voltage_bank: bank to control regulator voltage * @voltage_reg: register to control regulator voltage * @voltage_mask: mask to control regulator voltage + * @expand_register: */ struct ab8500_regulator_info { struct device *dev; @@ -79,12 +80,6 @@ struct ab8500_regulator_info { u8 voltage_bank; u8 voltage_reg; u8 voltage_mask; - struct { - u8 voltage_limit; - u8 voltage_bank; - u8 voltage_reg; - u8 voltage_mask; - } expand_register; }; /* voltage tables for the vauxn/vintcore supplies */ From 2f5add1e42165c7eb7e4367e1180ae76aa13d394 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:10 +0100 Subject: [PATCH 15/67] regulator: wm8350-regulator: Repair odd formatting in documentation Kerneldoc expects function arguments to be in the format '@.*:'. If this format is not followed the kerneldoc tooling/parsers/validators get confused. Fixes the following W=1 warning(s): drivers/regulator/wm8350-regulator.c:1234: warning: Function parameter or member 'wm8350' not described in 'wm8350_register_led' drivers/regulator/wm8350-regulator.c:1234: warning: Function parameter or member 'lednum' not described in 'wm8350_register_led' drivers/regulator/wm8350-regulator.c:1234: warning: Function parameter or member 'dcdc' not described in 'wm8350_register_led' drivers/regulator/wm8350-regulator.c:1234: warning: Function parameter or member 'isink' not described in 'wm8350_register_led' drivers/regulator/wm8350-regulator.c:1234: warning: Function parameter or member 'pdata' not described in 'wm8350_register_led' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-7-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index ae5f0e7fce8b..2e7bfdf7c87b 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1216,11 +1216,11 @@ EXPORT_SYMBOL_GPL(wm8350_register_regulator); /** * wm8350_register_led - Register a WM8350 LED output * - * @param wm8350 The WM8350 device to configure. - * @param lednum LED device index to create. - * @param dcdc The DCDC to use for the LED. - * @param isink The ISINK to use for the LED. - * @param pdata Configuration for the LED. + * @wm8350: The WM8350 device to configure. + * @lednum: LED device index to create. + * @dcdc: The DCDC to use for the LED. + * @isink: The ISINK to use for the LED. + * @pdata: Configuration for the LED. * * The WM8350 supports the use of an ISINK together with a DCDC to * provide a power-efficient LED driver. This function registers the From b89a5effb3345a484584cc2b090af62e1ecb0871 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:11 +0100 Subject: [PATCH 16/67] regulator: cpcap-regulator: Remove declared and set, but never used variable 'ignore' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's okay to not check the return value that you're not conserned about, however it is not okay to assign a variable and not check or use the result. Fixes W=1 warnings(s): drivers/regulator/cpcap-regulator.c:172:13: warning: variable ‘ignore’ set but not used [-Wunused-but-set-variable] 172 | int error, ignore; | ^~~~~~ drivers/regulator/cpcap-regulator.c: In function ‘cpcap_regulator_disable’: drivers/regulator/cpcap-regulator.c:196:13: warning: variable ‘ignore’ set but not used [-Wunused-but-set-variable] 196 | int error, ignore; | ^~~~~~ Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-8-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/cpcap-regulator.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index 14642603e755..e6fa243d8197 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -169,7 +169,7 @@ enum cpcap_regulator_id { static int cpcap_regulator_enable(struct regulator_dev *rdev) { struct cpcap_regulator *regulator = rdev_get_drvdata(rdev); - int error, ignore; + int error; error = regulator_enable_regmap(rdev); if (error) @@ -180,7 +180,7 @@ static int cpcap_regulator_enable(struct regulator_dev *rdev) regulator->assign_mask, regulator->assign_mask); if (error) - ignore = regulator_disable_regmap(rdev); + regulator_disable_regmap(rdev); } return error; @@ -193,7 +193,7 @@ static int cpcap_regulator_enable(struct regulator_dev *rdev) static int cpcap_regulator_disable(struct regulator_dev *rdev) { struct cpcap_regulator *regulator = rdev_get_drvdata(rdev); - int error, ignore; + int error; if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) { error = regmap_update_bits(rdev->regmap, regulator->assign_reg, @@ -204,9 +204,9 @@ static int cpcap_regulator_disable(struct regulator_dev *rdev) error = regulator_disable_regmap(rdev); if (error && (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC)) { - ignore = regmap_update_bits(rdev->regmap, regulator->assign_reg, - regulator->assign_mask, - regulator->assign_mask); + regmap_update_bits(rdev->regmap, regulator->assign_reg, + regulator->assign_mask, + regulator->assign_mask); } return error; From 7b804ce0c2e0bbf77b3a1d4b457520145822c496 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:12 +0100 Subject: [PATCH 17/67] regulator: cpcap-regulator: Demote kerneldoc header to standard comment Nothing about this comment identifies it as a kerneldoc header. They're missing all of their struct's property descriptions and the correct 'struct *' header. Fixes the following W=1 warning(s): drivers/regulator/cpcap-regulator.c:99: warning: cannot understand function prototype: 'struct cpcap_regulator ' drivers/regulator/cpcap-regulator.c:337: warning: cannot understand function prototype: 'const struct cpcap_regulator omap4_regulators[] = ' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-9-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/cpcap-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index e6fa243d8197..79b3eb3222c6 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -89,7 +89,7 @@ */ #define CPCAP_REG_OFF_MODE_SEC BIT(15) -/** +/* * SoC specific configuration for CPCAP regulator. There are at least three * different SoCs each with their own parameters: omap3, omap4 and tegra2. * @@ -325,7 +325,7 @@ static const unsigned int vvib_val_tbl[] = { 1300000, 1800000, 2000000, static const unsigned int vusb_val_tbl[] = { 0, 3300000, }; static const unsigned int vaudio_val_tbl[] = { 0, 2775000, }; -/** +/* * SoC specific configuration for omap4. The data below is comes from Motorola * Linux kernel tree. It's basically the values of cpcap_regltr_data, * cpcap_regulator_mode_values and cpcap_regulator_off_mode_values, see From 0c32f8aa0711af177248c2cba9cb105f18e0c9bb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 25 Jun 2020 17:36:14 +0100 Subject: [PATCH 18/67] regulator: max14577-regulator: Demote kerneldoc header to standard comment Nothing about this comment identifies it as a kerneldoc header. It's missing all of it's function argument descriptions and the correct function header. Fixes the following W=1 warning(s): drivers/regulator/max14577-regulator.c:166: warning: Function parameter or member 'max14577' not described in 'max14577_get_regma drivers/regulator/max14577-regulator.c:166: warning: Function parameter or member 'reg_id' not described in 'max14577_get_regmap' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200625163614.4001403-11-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/max14577-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c index 07a150c9bbf2..e34face736f4 100644 --- a/drivers/regulator/max14577-regulator.c +++ b/drivers/regulator/max14577-regulator.c @@ -155,7 +155,7 @@ static const struct regulator_desc max77836_supported_regulators[] = { [MAX77836_LDO2] = MAX77836_LDO_REG(2), }; -/** +/* * Registers for regulators of max77836 use different I2C slave addresses so * different regmaps must be used for them. * From 36f69fa96a23a054d3aea5793ce2ef3d95907713 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:30 +0100 Subject: [PATCH 19/67] regulator: max8998: Staticify internal function max8998_get_current_limit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit max8998_get_current_limit() is only used via the .get_current_limit, so it doesn't need to be publicly supported, or to have its own external prototype. Instead, we'll make it static. Fixes the following W=1 warning: drivers/regulator/max8998.c:418:5: warning: no previous prototype for ‘max8998_get_current_limit’ [-Wmissing-prototypes] 418 | int max8998_get_current_limit(struct regulator_dev *rdev) | ^~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Lee Jones Cc: Kyungmin Park Cc: Marek Szyprowski Link: https://lore.kernel.org/r/20200626065738.93412-2-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/max8998.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 340413bba0c5..ac69bdd398cb 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -415,7 +415,7 @@ static int max8998_set_current_limit(struct regulator_dev *rdev, sel, rdev->desc->csel_mask); } -int max8998_get_current_limit(struct regulator_dev *rdev) +static int max8998_get_current_limit(struct regulator_dev *rdev) { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c; From 7cb5f692077e3b91dcb706cbf58d495d066439ce Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:31 +0100 Subject: [PATCH 20/67] regulator: qcom-rpmh-regulator: Repair dodgy kerneldoc header formatting W=1 kernel builds report a lack of descriptions for various enum properties and function arguments. In reality they are documented, but the formatting was not as expected '@.*:'. Instead, some weird arg identifiers were used or none at all. This change fixes the following warnings: drivers/regulator/qcom-rpmh-regulator.c:33: warning: Enum value 'VRM' not described in enum 'rpmh_regulator_type' drivers/regulator/qcom-rpmh-regulator.c:33: warning: Enum value 'XOB' not described in enum 'rpmh_regulator_type' drivers/regulator/qcom-rpmh-regulator.c:416: warning: Function parameter or member 'vreg' not described in 'rpmh_regulator_init_vreg' drivers/regulator/qcom-rpmh-regulator.c:416: warning: Function parameter or member 'dev' not described in 'rpmh_regulator_init_vreg' drivers/regulator/qcom-rpmh-regulator.c:416: warning: Function parameter or member 'node' not described in 'rpmh_regulator_init_vreg' drivers/regulator/qcom-rpmh-regulator.c:416: warning: Function parameter or member 'pmic_id' not described in 'rpmh_regulator_init_vreg' drivers/regulator/qcom-rpmh-regulator.c:416: warning: Function parameter or member 'pmic_rpmh_data' not described in 'rpmh_regulator_init_vreg' Signed-off-by: Lee Jones Reviewed-by: Bjorn Andersson Cc: Andy Gross Cc: Bjorn Andersson Cc: linux-arm-msm@vger.kernel.org Link: https://lore.kernel.org/r/20200626065738.93412-3-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/qcom-rpmh-regulator.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index 79bdc129cb50..08dcc614efa7 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -22,9 +22,9 @@ /** * enum rpmh_regulator_type - supported RPMh accelerator types - * %VRM: RPMh VRM accelerator which supports voting on enable, voltage, + * @VRM: RPMh VRM accelerator which supports voting on enable, voltage, * and mode of LDO, SMPS, and BOB type PMIC regulators. - * %XOB: RPMh XOB accelerator which supports voting on the enable state + * @XOB: RPMh XOB accelerator which supports voting on the enable state * of PMIC regulators. */ enum rpmh_regulator_type { @@ -399,13 +399,13 @@ static const struct regulator_ops rpmh_regulator_xob_ops = { /** * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator - * vreg: Pointer to the individual rpmh-regulator resource - * dev: Pointer to the top level rpmh-regulator PMIC device - * node: Pointer to the individual rpmh-regulator resource + * @vreg: Pointer to the individual rpmh-regulator resource + * @dev: Pointer to the top level rpmh-regulator PMIC device + * @node: Pointer to the individual rpmh-regulator resource * device node - * pmic_id: String used to identify the top level rpmh-regulator + * @pmic_id: String used to identify the top level rpmh-regulator * PMIC device on the board - * pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator + * @pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator * resources defined for the top level PMIC device * * Return: 0 on success, errno on failure From 4e773e7392fb561eb4ae10deb526aa1ac8c13f61 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:32 +0100 Subject: [PATCH 21/67] regulator: pwm-regulator: Demote kerneldoc header to standard comment This particular comment doesn't have anything to do with documenting functions or data structures. Instead it is used as a section header. Fixes W=1 warning: drivers/regulator/pwm-regulator.c:55: warning: Function parameter or member 'rdev' not described in 'pwm_regulator_init_state' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200626065738.93412-4-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/pwm-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 638329bd0745..3234b118b53e 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -48,7 +48,7 @@ struct pwm_voltages { unsigned int dutycycle; }; -/** +/* * Voltage table call-backs */ static void pwm_regulator_init_state(struct regulator_dev *rdev) From ec84a7dff4474d0af6ef003719509e30aa93071d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:33 +0100 Subject: [PATCH 22/67] regulator: stpmic1_regulator: Properly document 'struct stpmic1_regulator_cfg' In kerneldoc format, data structures have to start with 'struct' else the kerneldoc tooling/parsers/validators get confused. Fixes the following W=1 kernel build warning: drivers/regulator/stpmic1_regulator.c:25: warning: cannot understand function prototype: 'struct stpmic1_regulator_cfg ' Signed-off-by: Lee Jones Cc: Pascal Paillet Link: https://lore.kernel.org/r/20200626065738.93412-5-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/stpmic1_regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c index adc9973d1b2f..73e0ab2baeaa 100644 --- a/drivers/regulator/stpmic1_regulator.c +++ b/drivers/regulator/stpmic1_regulator.c @@ -15,7 +15,7 @@ #include /** - * stpmic1 regulator description: this structure is used as driver data + * struct stpmic1 regulator description: this structure is used as driver data * @desc: regulator framework description * @mask_reset_reg: mask reset register address * @mask_reset_mask: mask rank and mask reset register mask From f10a5e499cf3e0978845cd85d8a375bcfa193907 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:34 +0100 Subject: [PATCH 23/67] regulator: tps65217-regulator: Remove pointless 'is unsigned int <0' check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'rid' is declared as unsigned int, so there is little point checking for <0. Removing these checks fixes the following W=1 warnings: drivers/regulator/tps65217-regulator.c: In function ‘tps65217_pmic_set_suspend_enable’: drivers/regulator/tps65217-regulator.c:127:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] 127 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ^ drivers/regulator/tps65217-regulator.c: In function ‘tps65217_pmic_set_suspend_disable’: drivers/regulator/tps65217-regulator.c:140:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] 140 | if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) | ^ Signed-off-by: Lee Jones Cc: Russ Dill Cc: Keerthy Cc: AnilKumar Ch Cc: linux-omap@vger.kernel.org Link: https://lore.kernel.org/r/20200626065738.93412-6-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index d27dbbafcf72..f2d3a4a9f3e7 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -124,7 +124,7 @@ static int tps65217_pmic_set_suspend_enable(struct regulator_dev *dev) struct tps65217 *tps = rdev_get_drvdata(dev); unsigned int rid = rdev_get_id(dev); - if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) + if (rid > TPS65217_LDO_4) return -EINVAL; return tps65217_clear_bits(tps, dev->desc->bypass_reg, @@ -137,7 +137,7 @@ static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev) struct tps65217 *tps = rdev_get_drvdata(dev); unsigned int rid = rdev_get_id(dev); - if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) + if (rid > TPS65217_LDO_4) return -EINVAL; if (!tps->strobes[rid]) From 44455a6d3bcab53ae8330a009d513ade0f12c0c0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:35 +0100 Subject: [PATCH 24/67] regulator: tps65217-regulator: Use the returned value of tps65217_reg_read() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now the aforementioned return value has been ignored. Previous and current calls to tps65217_reg_read() return instantly when the value is not 0, so let's do that. Fixes the following W=1 warning: drivers/regulator/tps65217-regulator.c: In function ‘tps65217_regulator_probe’: drivers/regulator/tps65217-regulator.c:227:9: warning: variable ‘ret’ set but not used [-Wunused-but-set-variable] 227 | int i, ret; | ^~~ Signed-off-by: Lee Jones Cc: Russ Dill Cc: Keerthy Cc: AnilKumar Ch Cc: linux-omap@vger.kernel.org Link: https://lore.kernel.org/r/20200626065738.93412-7-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index f2d3a4a9f3e7..3f5ea029e2e3 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -254,6 +254,9 @@ static int tps65217_regulator_probe(struct platform_device *pdev) /* Store default strobe info */ ret = tps65217_reg_read(tps, regulators[i].bypass_reg, &val); + if (ret) + return ret; + tps->strobes[i] = val & regulators[i].bypass_mask; } From 02d88863198c48675ceb2a244e5985c5650e5fe6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:36 +0100 Subject: [PATCH 25/67] regulator: tps65218-regulator: Remove pointless 'is unsigned int <0' check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'rid' is declared as unsigned int, so there is little point checking for <0. Removing these checks fixes the following W=1 warnings: drivers/regulator/tps65218-regulator.c: In function ‘tps65218_pmic_set_suspend_enable’: drivers/regulator/tps65218-regulator.c:131:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] 131 | if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) | ^ drivers/regulator/tps65218-regulator.c: In function ‘tps65218_pmic_set_suspend_disable’: drivers/regulator/tps65218-regulator.c:144:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] 144 | if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) | ^ Signed-off-by: Lee Jones Cc: Keerthy Cc: Tero Kristo Cc: Dave Gerlach Cc: linux-omap@vger.kernel.org Link: https://lore.kernel.org/r/20200626065738.93412-8-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 05d13f807918..9133d0af793a 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -128,7 +128,7 @@ static int tps65218_pmic_set_suspend_enable(struct regulator_dev *dev) struct tps65218 *tps = rdev_get_drvdata(dev); unsigned int rid = rdev_get_id(dev); - if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) + if (rid > TPS65218_LDO_1) return -EINVAL; return tps65218_clear_bits(tps, dev->desc->bypass_reg, @@ -141,7 +141,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) struct tps65218 *tps = rdev_get_drvdata(dev); unsigned int rid = rdev_get_id(dev); - if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) + if (rid > TPS65218_LDO_1) return -EINVAL; /* From 0c5261663785b6505bf5d0f210f1ff0e4bd5ef2c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:37 +0100 Subject: [PATCH 26/67] regulator: wm8400-regulator: Repair dodgy kerneldoc header formatting W=1 kernel builds report a lack of descriptions for various function arguments. In reality they are documented, but the formatting was not as expected '@.*:'. Instead, some weird arg identifiers were used. This change fixes the following warnings: drivers/regulator/wm8400-regulator.c:243: warning: Function parameter or member 'dev' not described in 'wm8400_register_regulator' drivers/regulator/wm8400-regulator.c:243: warning: Function parameter or member 'reg' not described in 'wm8400_register_regulator' drivers/regulator/wm8400-regulator.c:243: warning: Function parameter or member 'initdata' not described in 'wm8400_register_regulator' Signed-off-by: Lee Jones Acked-by: Charles Keepax Cc: patches@opensource.cirrus.com Link: https://lore.kernel.org/r/20200626065738.93412-9-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/wm8400-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index 4cb1fbb59722..e9fd13707721 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -234,9 +234,9 @@ static struct platform_driver wm8400_regulator_driver = { * the regulator API. It is intended to be called from the * platform_init() callback of the WM8400 MFD driver. * - * @param dev The WM8400 device to operate on. - * @param reg The regulator to control. - * @param initdata Regulator initdata for the regulator. + * @dev: The WM8400 device to operate on. + * @reg: The regulator to control. + * @initdata: Regulator initdata for the regulator. */ int wm8400_register_regulator(struct device *dev, int reg, struct regulator_init_data *initdata) From bfa29acd18e53ff44135f2eae2b942419a8582cc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 26 Jun 2020 07:57:38 +0100 Subject: [PATCH 27/67] regulator: qcom_smd-regulator: Remove unused 'struct regulator_desc pmi8994_boost' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was an upstreaming error. Remove it as it's not to be used. Fixes the following W=1 kernel build warning: drivers/regulator/qcom_smd-regulator.c:477:36: warning: ‘pmi8994_boost’ defined but not used [-Wunused-const-variable=] Signed-off-by: Lee Jones Reviewed-by: Bjorn Andersson Cc: Andy Gross Cc: Bjorn Andersson Cc: linux-arm-msm@vger.kernel.org Link: https://lore.kernel.org/r/20200626065738.93412-10-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/qcom_smd-regulator.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 53a64d856926..4c0a469d8a11 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -474,15 +474,6 @@ static const struct regulator_desc pmi8994_bby = { .ops = &rpm_bob_ops, }; -static const struct regulator_desc pmi8994_boost = { - .linear_ranges = (struct linear_range[]) { - REGULATOR_LINEAR_RANGE(4000000, 0, 30, 50000), - }, - .n_linear_ranges = 1, - .n_voltages = 31, - .ops = &rpm_smps_ldo_ops, -}; - static const struct regulator_desc pm8998_ftsmps = { .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000), From 4fe66d5a62fbe1b050e783e7a01f986632c08c44 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Fri, 26 Jun 2020 11:55:14 -0700 Subject: [PATCH 28/67] regulator: Add support for QCOM PMIC VBUS booster Some Qualcomm PMICs have the capability to source the VBUS output to connected peripherals. This driver will register a regulator to the regulator list to enable or disable this source by an external driver. Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/r/20200626185516.18018-5-wcheng@codeaurora.org Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 +++ drivers/regulator/Makefile | 1 + drivers/regulator/qcom_usb_vbus-regulator.c | 97 +++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 drivers/regulator/qcom_usb_vbus-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c398e90e0e73..a63e02b7034d 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -836,6 +836,16 @@ config REGULATOR_QCOM_SPMI Qualcomm SPMI PMICs as a module. The module will be named "qcom_spmi-regulator". +config REGULATOR_QCOM_USB_VBUS + tristate "Qualcomm USB Vbus regulator driver" + depends on SPMI || COMPILE_TEST + help + If you say yes to this option, support will be included for the + regulator used to enable the VBUS output. + + Say M here if you want to include support for enabling the VBUS output + as a module. The module will be named "qcom_usb_vbus_regulator". + config REGULATOR_RC5T583 tristate "RICOH RC5T583 Power regulators" depends on MFD_RC5T583 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 46592c160d22..9f8b6c7494dd 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -93,6 +93,7 @@ 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 obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o +obj-$(CONFIG_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c new file mode 100644 index 000000000000..342d92373598 --- /dev/null +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Qualcomm PMIC VBUS output regulator driver +// +// Copyright (c) 2020, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CMD_OTG 0x40 +#define OTG_EN BIT(0) +#define OTG_CFG 0x53 +#define OTG_EN_SRC_CFG BIT(1) + +static const struct regulator_ops qcom_usb_vbus_reg_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static struct regulator_desc qcom_usb_vbus_rdesc = { + .name = "usb_vbus", + .ops = &qcom_usb_vbus_reg_ops, + .owner = THIS_MODULE, + .type = REGULATOR_VOLTAGE, +}; + +static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regulator_dev *rdev; + struct regmap *regmap; + struct regulator_config config = { }; + struct regulator_init_data *init_data; + int ret; + u32 base; + + ret = of_property_read_u32(dev->of_node, "reg", &base); + if (ret < 0) { + dev_err(dev, "no base address found\n"); + return ret; + } + + regmap = dev_get_regmap(dev->parent, NULL); + if (regmap) { + dev_err(dev, "Failed to get regmap\n"); + return -ENOENT; + } + + init_data = of_get_regulator_init_data(dev, dev->of_node, + &qcom_usb_vbus_rdesc); + if (!init_data) + return -ENOMEM; + + qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; + qcom_usb_vbus_rdesc.enable_mask = OTG_EN; + config.dev = dev; + config.init_data = init_data; + config.regmap = regmap; + + rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(dev, "not able to register vbus reg %d\n", ret); + return ret; + } + + /* Disable HW logic for VBUS enable */ + regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); + + return 0; +} + +static const struct of_device_id qcom_usb_vbus_regulator_match[] = { + { .compatible = "qcom,pm8150b-vbus-reg" }, + { } +}; +MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match); + +static struct platform_driver qcom_usb_vbus_regulator_driver = { + .driver = { + .name = "qcom-usb-vbus-regulator", + .of_match_table = qcom_usb_vbus_regulator_match, + }, + .probe = qcom_usb_vbus_regulator_probe, +}; +module_platform_driver(qcom_usb_vbus_regulator_driver); + +MODULE_DESCRIPTION("Qualcomm USB vbus regulator driver"); +MODULE_LICENSE("GPL v2"); From a824bab7c62d7ecd8ccfe9693da7ccb7e4683760 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Fri, 26 Jun 2020 11:55:15 -0700 Subject: [PATCH 29/67] regulator: Add dt-binding for QCOM PMIC VBUS output regulator This describes how to enable the Qualcomm PMIC VBUS booster used for providing power to connected USB peripherals when the USB role is host mode. The driver itself will register the vbus_usb regulator, so that external drivers can utilize the enable/disable regulator APIs. Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/r/20200626185516.18018-6-wcheng@codeaurora.org Signed-off-by: Mark Brown --- .../regulator/qcom,usb-vbus-regulator.yaml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml new file mode 100644 index 000000000000..12ed98c28aaa --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/qcom,usb-vbus-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: The Qualcomm PMIC VBUS output regulator driver + +maintainers: + - Wesley Cheng + +description: | + This regulator driver controls the VBUS output by the Qualcomm PMIC. This + regulator will be enabled in situations where the device is required to + provide power to the connected peripheral. + +properties: + compatible: + enum: + - qcom,pm8150b-vbus-reg + + reg: + maxItems: 1 + description: VBUS output base address + +required: + - compatible + +additionalProperties: false + +examples: + - | + pm8150b { + #address-cells = <1>; + #size-cells = <0>; + pm8150b_vbus: dcdc@1100 { + compatible = "qcom,pm8150b-vbus-reg"; + reg = <0x1100>; + }; + }; +... From 8d41df6469eec8d784137aeeebf87dca7460ce37 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Mon, 29 Jun 2020 21:46:31 +0200 Subject: [PATCH 30/67] regulator: qcom_rpm: Constify struct regulator_ops These are never modified, so make them const to allow the compiler to put them in read-only memory. Before: text data bss dec hex filename 17485 500 8 17993 4649 drivers/regulator/qcom_rpm-regulator.o After: text data bss dec hex filename 17881 104 8 17993 4649 drivers/regulator/qcom_rpm-regulator.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200629194632.8147-2-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_rpm-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 0066f850f15d..7f9d66ac37ff 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -407,7 +407,7 @@ static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA) return ret; } -static struct regulator_ops uV_ops = { +static const struct regulator_ops uV_ops = { .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = rpm_reg_set_uV_sel, @@ -420,7 +420,7 @@ static struct regulator_ops uV_ops = { .set_load = rpm_reg_set_load, }; -static struct regulator_ops mV_ops = { +static const struct regulator_ops mV_ops = { .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = rpm_reg_set_mV_sel, @@ -433,7 +433,7 @@ static struct regulator_ops mV_ops = { .set_load = rpm_reg_set_load, }; -static struct regulator_ops switch_ops = { +static const struct regulator_ops switch_ops = { .enable = rpm_reg_switch_enable, .disable = rpm_reg_switch_disable, .is_enabled = rpm_reg_is_enabled, From 3b619e3e2d1a89f383a0a0c527818dcb2bc66f92 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Mon, 29 Jun 2020 21:46:32 +0200 Subject: [PATCH 31/67] regulator: qcom_spmi: Constify struct regulator_ops These are never modified, so make them const to allow the compiler to put them in read-only memory. Before: text data bss dec hex filename 20362 2592 152 23106 5a42 drivers/regulator/qcom_spmi-regulator.o After: text data bss dec hex filename 21814 1140 152 23106 5a42 drivers/regulator/qcom_spmi-regulator.o Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200629194632.8147-3-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_spmi-regulator.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 95737e4dd6bb..5ee7c5305d95 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -380,7 +380,7 @@ struct spmi_regulator_mapping { enum spmi_regulator_logical_type logical_type; u32 revision_min; u32 revision_max; - struct regulator_ops *ops; + const struct regulator_ops *ops; struct spmi_voltage_set_points *set_points; int hpm_min_load; }; @@ -1261,7 +1261,7 @@ spmi_regulator_saw_set_voltage(struct regulator_dev *rdev, unsigned selector) static struct regulator_ops spmi_saw_ops = {}; -static struct regulator_ops spmi_smps_ops = { +static const struct regulator_ops spmi_smps_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1276,7 +1276,7 @@ static struct regulator_ops spmi_smps_ops = { .set_pull_down = spmi_regulator_common_set_pull_down, }; -static struct regulator_ops spmi_ldo_ops = { +static const struct regulator_ops spmi_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1293,7 +1293,7 @@ static struct regulator_ops spmi_ldo_ops = { .set_soft_start = spmi_regulator_common_set_soft_start, }; -static struct regulator_ops spmi_ln_ldo_ops = { +static const struct regulator_ops spmi_ln_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1305,7 +1305,7 @@ static struct regulator_ops spmi_ln_ldo_ops = { .get_bypass = spmi_regulator_common_get_bypass, }; -static struct regulator_ops spmi_vs_ops = { +static const struct regulator_ops spmi_vs_ops = { .enable = spmi_regulator_vs_enable, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1316,7 +1316,7 @@ static struct regulator_ops spmi_vs_ops = { .get_mode = spmi_regulator_common_get_mode, }; -static struct regulator_ops spmi_boost_ops = { +static const struct regulator_ops spmi_boost_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1327,7 +1327,7 @@ static struct regulator_ops spmi_boost_ops = { .set_input_current_limit = spmi_regulator_set_ilim, }; -static struct regulator_ops spmi_ftsmps_ops = { +static const struct regulator_ops spmi_ftsmps_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1342,7 +1342,7 @@ static struct regulator_ops spmi_ftsmps_ops = { .set_pull_down = spmi_regulator_common_set_pull_down, }; -static struct regulator_ops spmi_ult_lo_smps_ops = { +static const struct regulator_ops spmi_ult_lo_smps_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1356,7 +1356,7 @@ static struct regulator_ops spmi_ult_lo_smps_ops = { .set_pull_down = spmi_regulator_common_set_pull_down, }; -static struct regulator_ops spmi_ult_ho_smps_ops = { +static const struct regulator_ops spmi_ult_ho_smps_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1371,7 +1371,7 @@ static struct regulator_ops spmi_ult_ho_smps_ops = { .set_pull_down = spmi_regulator_common_set_pull_down, }; -static struct regulator_ops spmi_ult_ldo_ops = { +static const struct regulator_ops spmi_ult_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1388,7 +1388,7 @@ static struct regulator_ops spmi_ult_ldo_ops = { .set_soft_start = spmi_regulator_common_set_soft_start, }; -static struct regulator_ops spmi_ftsmps426_ops = { +static const struct regulator_ops spmi_ftsmps426_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -1403,7 +1403,7 @@ static struct regulator_ops spmi_ftsmps426_ops = { .set_pull_down = spmi_regulator_common_set_pull_down, }; -static struct regulator_ops spmi_hfs430_ops = { +static const struct regulator_ops spmi_hfs430_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, From 47894c859479a9e3472657c7acf2c7ba35778059 Mon Sep 17 00:00:00 2001 From: Kathiravan T Date: Tue, 23 Jun 2020 10:47:50 +0530 Subject: [PATCH 32/67] regulator: qcom_smd: Add MP5496 regulators IPQ6018 SoC uses the PMIC MP5496. SMPA2 and LDOA2 regulator controls the APSS and SDCC voltage scaling respectively. Add support for the same. Signed-off-by: Kathiravan T Link: https://lore.kernel.org/r/1592889472-6843-5-git-send-email-kathirav@codeaurora.org Signed-off-by: Mark Brown --- drivers/regulator/qcom_smd-regulator.c | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 4c0a469d8a11..a64b4e4f64ed 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -198,6 +198,15 @@ static const struct regulator_ops rpm_bob_ops = { .set_voltage = rpm_reg_set_voltage, }; +static const struct regulator_ops rpm_mp5496_ops = { + .enable = rpm_reg_enable, + .disable = rpm_reg_disable, + .is_enabled = rpm_reg_is_enabled, + .list_voltage = regulator_list_voltage_linear_range, + + .set_voltage = rpm_reg_set_voltage, +}; + static const struct regulator_desc pma8084_hfsmps = { .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(375000, 0, 95, 12500), @@ -586,6 +595,24 @@ static const struct regulator_desc pms405_pldo600 = { .ops = &rpm_smps_ldo_ops, }; +static const struct regulator_desc mp5496_smpa2 = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(725000, 0, 27, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 28, + .ops = &rpm_mp5496_ops, +}; + +static const struct regulator_desc mp5496_ldoa2 = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1800000, 0, 60, 25000), + }, + .n_linear_ranges = 1, + .n_voltages = 61, + .ops = &rpm_mp5496_ops, +}; + struct rpm_regulator_data { const char *name; u32 type; @@ -594,6 +621,12 @@ struct rpm_regulator_data { const char *supply; }; +static const struct rpm_regulator_data rpm_mp5496_regulators[] = { + { "s2", QCOM_SMD_RPM_SMPA, 2, &mp5496_smpa2, "s2" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &mp5496_ldoa2, "l2" }, + {} +}; + static const struct rpm_regulator_data rpm_pm8841_regulators[] = { { "s1", QCOM_SMD_RPM_SMPB, 1, &pm8x41_hfsmps, "vdd_s1" }, { "s2", QCOM_SMD_RPM_SMPB, 2, &pm8841_ftsmps, "vdd_s2" }, @@ -892,6 +925,7 @@ static const struct rpm_regulator_data rpm_pms405_regulators[] = { }; static const struct of_device_id rpm_of_match[] = { + { .compatible = "qcom,rpm-mp5496-regulators", .data = &rpm_mp5496_regulators }, { .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators }, { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, From 93e39d096d7312e38cf502be4e516cff7acf34fa Mon Sep 17 00:00:00 2001 From: Kathiravan T Date: Tue, 23 Jun 2020 10:47:49 +0530 Subject: [PATCH 33/67] regulator: add MP5496 regulator compatible IPQ6018 uses the PMIC MP5496. Add the binding for the same. Signed-off-by: Kathiravan T Link: https://lore.kernel.org/r/1592889472-6843-4-git-send-email-kathirav@codeaurora.org Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index dea4384f4c03..728c0010a60a 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -19,6 +19,7 @@ Regulator nodes are identified by their compatible: Usage: required Value type: Definition: must be one of: + "qcom,rpm-mp5496-regulators" "qcom,rpm-pm8841-regulators" "qcom,rpm-pm8916-regulators" "qcom,rpm-pm8941-regulators" From 81fdcef3a615f5d4ef2a2bd87a65d46f6816d687 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Mon, 22 Jun 2020 22:43:26 +0200 Subject: [PATCH 34/67] regulator: lp87565: enable voltage regardless of ENx pin This driver enables outputs by setting bit EN_BUCKn in the BUCKn_CTRL1 register. However, if bit EN_PIN_CTRLn in the same register is set, the output is actually enabled only if EN_BUCKn is set AND an enable pin is active. Since the driver does not touch EN_PIN_CTRLn, the choice is left to the hardware, which in turn gets this bit from OTP memory, and in absence of OTP data it uses a default value that is documented in the datasheet for LP8752x, but not for LP8756x. Thus the driver doesn't really "know" whether it is actually enabling the output or not. In order to make sure activation is always driver-controlled, just clear the EN_PIN_CTRLn bit. Now all activation solely depend on the EN_BUCKn bit. Signed-off-by: Luca Ceresoli Link: https://lore.kernel.org/r/20200622204329.11147-2-luca@lucaceresoli.net Signed-off-by: Mark Brown --- drivers/regulator/lp87565-regulator.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index 5d525dacf959..fbed6bc80c1a 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -11,8 +11,8 @@ #include -#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, _er, _em, \ - _delay, _lr, _cr) \ +#define LP87565_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, \ + _er, _em, _ev, _delay, _lr, _cr) \ [_id] = { \ .desc = { \ .name = _name, \ @@ -28,6 +28,7 @@ .vsel_mask = _vm, \ .enable_reg = _er, \ .enable_mask = _em, \ + .enable_val = _ev, \ .ramp_delay = _delay, \ .linear_ranges = _lr, \ .n_linear_ranges = ARRAY_SIZE(_lr), \ @@ -121,38 +122,54 @@ static const struct lp87565_regulator regulators[] = { LP87565_REGULATOR("BUCK0", LP87565_BUCK_0, "buck0", lp87565_buck_ops, 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK0_CTRL_1, + LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, LP87565_BUCK_CTRL_1_EN, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), LP87565_REGULATOR("BUCK1", LP87565_BUCK_1, "buck1", lp87565_buck_ops, 256, LP87565_REG_BUCK1_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK1_CTRL_1, + LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, LP87565_BUCK_CTRL_1_EN, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK1_CTRL_2), LP87565_REGULATOR("BUCK2", LP87565_BUCK_2, "buck2", lp87565_buck_ops, 256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK2_CTRL_1, + LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, LP87565_BUCK_CTRL_1_EN, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2), LP87565_REGULATOR("BUCK3", LP87565_BUCK_3, "buck3", lp87565_buck_ops, 256, LP87565_REG_BUCK3_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK3_CTRL_1, + LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, LP87565_BUCK_CTRL_1_EN, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK3_CTRL_2), LP87565_REGULATOR("BUCK10", LP87565_BUCK_10, "buck10", lp87565_buck_ops, 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK0_CTRL_1, LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, + LP87565_BUCK_CTRL_1_EN | LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), LP87565_REGULATOR("BUCK23", LP87565_BUCK_23, "buck23", lp87565_buck_ops, 256, LP87565_REG_BUCK2_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK2_CTRL_1, + LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL, LP87565_BUCK_CTRL_1_EN, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK2_CTRL_2), LP87565_REGULATOR("BUCK3210", LP87565_BUCK_3210, "buck3210", lp87565_buck_ops, 256, LP87565_REG_BUCK0_VOUT, LP87565_BUCK_VSET, LP87565_REG_BUCK0_CTRL_1, LP87565_BUCK_CTRL_1_EN | + LP87565_BUCK_CTRL_1_EN_PIN_CTRL | + LP87565_BUCK_CTRL_1_FPWM_MP_0_2, + LP87565_BUCK_CTRL_1_EN | LP87565_BUCK_CTRL_1_FPWM_MP_0_2, 3230, buck0_1_2_3_ranges, LP87565_REG_BUCK0_CTRL_2), }; From 1c537b2d729698717f01fcea13721818be5adde7 Mon Sep 17 00:00:00 2001 From: Anand K Mistry Date: Thu, 2 Jul 2020 16:23:17 +1000 Subject: [PATCH 35/67] regulator: mt6397: Move buck modes into header file This will allow device trees to make use of these constants. Signed-off-by: Anand K Mistry Link: https://lore.kernel.org/r/20200702162231.v2.1.Icf69e2041b1af4548347018186c3ba6310f53e66@changeid Signed-off-by: Mark Brown --- drivers/regulator/mt6397-regulator.c | 4 +--- .../regulator/mediatek,mt6397-regulator.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 include/dt-bindings/regulator/mediatek,mt6397-regulator.h diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index 269c2a6028e8..d51e98ce1138 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -13,9 +13,7 @@ #include #include #include - -#define MT6397_BUCK_MODE_AUTO 0 -#define MT6397_BUCK_MODE_FORCE_PWM 1 +#include /* * MT6397 regulators' information diff --git a/include/dt-bindings/regulator/mediatek,mt6397-regulator.h b/include/dt-bindings/regulator/mediatek,mt6397-regulator.h new file mode 100644 index 000000000000..99869a8665cf --- /dev/null +++ b/include/dt-bindings/regulator/mediatek,mt6397-regulator.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DT_BINDINGS_REGULATOR_MEDIATEK_MT6397_H_ +#define _DT_BINDINGS_REGULATOR_MEDIATEK_MT6397_H_ + +/* + * Buck mode constants which may be used in devicetree properties (eg. + * regulator-initial-mode, regulator-allowed-modes). + * See the manufacturer's datasheet for more information on these modes. + */ + +#define MT6397_BUCK_MODE_AUTO 0 +#define MT6397_BUCK_MODE_FORCE_PWM 1 + +#endif From 8096236db4349c43a2b19b8ceb11b0b997354223 Mon Sep 17 00:00:00 2001 From: Anand K Mistry Date: Thu, 2 Jul 2020 16:23:19 +1000 Subject: [PATCH 36/67] regulator: mt6397: Implement of_map_mode Implementing of_map_mode is necessary to be able to specify operating modes in the devicetree using 'regulator-allowed-modes', and to change regulator modes. Signed-off-by: Anand K Mistry Link: https://lore.kernel.org/r/20200702162231.v2.3.I7acfb591bfacf3b1b04a3d388385098bfcc9fecd@changeid Signed-off-by: Mark Brown --- drivers/regulator/mt6397-regulator.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index d51e98ce1138..0a30df5e414f 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -53,6 +53,7 @@ struct mt6397_regulator_info { .vsel_mask = vosel_mask, \ .enable_reg = enreg, \ .enable_mask = BIT(0), \ + .of_map_mode = mt6397_map_mode, \ }, \ .qi = BIT(13), \ .vselon_reg = voselon, \ @@ -144,6 +145,18 @@ static const unsigned int ldo_volt_table7[] = { 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, }; +static unsigned int mt6397_map_mode(unsigned int mode) +{ + switch (mode) { + case MT6397_BUCK_MODE_AUTO: + return REGULATOR_MODE_NORMAL; + case MT6397_BUCK_MODE_FORCE_PWM: + return REGULATOR_MODE_FAST; + default: + return REGULATOR_MODE_INVALID; + } +} + static int mt6397_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode) { From 347f12d573412cb7ba4781b58f42f0ca7eecde6d Mon Sep 17 00:00:00 2001 From: Anand K Mistry Date: Thu, 2 Jul 2020 16:23:18 +1000 Subject: [PATCH 37/67] regulator: mt6397: Document valid modes Document valid mode values for BUCK regulators. Signed-off-by: Anand K Mistry Link: https://lore.kernel.org/r/20200702162231.v2.2.I0a814b246cfe47f8dd1e25553ee881cbcfd0d8eb@changeid Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/mt6397-regulator.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt index 01141fb00875..c080086d3e62 100644 --- a/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt @@ -16,6 +16,9 @@ LDO: ldo_vemc3v3, ldo_vgp1, ldo_vgp2, ldo_vgp3, ldo_vgp4, ldo_vgp5, ldo_vgp6, ldo_vibr +BUCK regulators can set regulator-initial-mode and regulator-allowed-modes to +values specified in dt-bindings/regulator/mediatek,mt6397-regulator.h + Example: pmic { compatible = "mediatek,mt6397"; From 38fc6f295726366a0135ca87ab98f3ab92afd81f Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Thu, 2 Jul 2020 17:14:38 +0800 Subject: [PATCH 38/67] regulator: add support for SY8827N regulator The SY8827N from Silergy Corp is a single output DC/DC converter. The voltage can be controlled via I2C. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200702171438.20edc523@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 7 ++ drivers/regulator/Makefile | 1 + drivers/regulator/sy8827n.c | 185 ++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/regulator/sy8827n.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index a63e02b7034d..faa4cbfdc5d0 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1009,6 +1009,13 @@ config REGULATOR_SY8824X help This driver supports SY8824C single output regulator. +config REGULATOR_SY8827N + tristate "Silergy SY8827N regulator" + depends on I2C && (OF || COMPILE_TEST) + select REGMAP_I2C + help + This driver supports SY8827N single output regulator. + config REGULATOR_TPS51632 tristate "TI TPS51632 Power Regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 9f8b6c7494dd..a20670a1eab0 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -122,6 +122,7 @@ obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o +obj-$(CONFIG_REGULATOR_SY8827N) += sy8827n.o obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c new file mode 100644 index 000000000000..b207217f74d8 --- /dev/null +++ b/drivers/regulator/sy8827n.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// SY8827N regulator driver +// +// Copyright (C) 2020 Synaptics Incorporated +// +// Author: Jisheng Zhang + +#include +#include +#include +#include +#include +#include +#include + +#define SY8827N_VSEL0 0 +#define SY8827N_BUCK_EN (1 << 7) +#define SY8827N_MODE (1 << 6) +#define SY8827N_VSEL1 1 +#define SY8827N_CTRL 2 + +#define SY8827N_NVOLTAGES 64 +#define SY8827N_VSELMIN 600000 +#define SY8827N_VSELSTEP 12500 + +struct sy8827n_device_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_init_data *regulator; + struct gpio_desc *en_gpio; + unsigned int vsel_reg; +}; + +static int sy8827n_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + struct sy8827n_device_info *di = rdev_get_drvdata(rdev); + + switch (mode) { + case REGULATOR_MODE_FAST: + regmap_update_bits(rdev->regmap, di->vsel_reg, + SY8827N_MODE, SY8827N_MODE); + break; + case REGULATOR_MODE_NORMAL: + regmap_update_bits(rdev->regmap, di->vsel_reg, + SY8827N_MODE, 0); + break; + default: + return -EINVAL; + } + return 0; +} + +static unsigned int sy8827n_get_mode(struct regulator_dev *rdev) +{ + struct sy8827n_device_info *di = rdev_get_drvdata(rdev); + u32 val; + int ret = 0; + + ret = regmap_read(rdev->regmap, di->vsel_reg, &val); + if (ret < 0) + return ret; + if (val & SY8827N_MODE) + return REGULATOR_MODE_FAST; + else + return REGULATOR_MODE_NORMAL; +} + +static const struct regulator_ops sy8827n_regulator_ops = { + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .map_voltage = regulator_map_voltage_linear, + .list_voltage = regulator_list_voltage_linear, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_mode = sy8827n_set_mode, + .get_mode = sy8827n_get_mode, +}; + +static int sy8827n_regulator_register(struct sy8827n_device_info *di, + struct regulator_config *config) +{ + struct regulator_desc *rdesc = &di->desc; + struct regulator_dev *rdev; + + rdesc->name = "sy8827n-reg"; + rdesc->supply_name = "vin"; + rdesc->ops = &sy8827n_regulator_ops; + rdesc->type = REGULATOR_VOLTAGE; + rdesc->n_voltages = SY8827N_NVOLTAGES; + rdesc->enable_reg = di->vsel_reg; + rdesc->enable_mask = SY8827N_BUCK_EN; + rdesc->min_uV = SY8827N_VSELMIN; + rdesc->uV_step = SY8827N_VSELSTEP; + rdesc->vsel_reg = di->vsel_reg; + rdesc->vsel_mask = rdesc->n_voltages - 1; + rdesc->owner = THIS_MODULE; + + rdev = devm_regulator_register(di->dev, &di->desc, config); + return PTR_ERR_OR_ZERO(rdev); +} + +static const struct regmap_config sy8827n_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int sy8827n_i2c_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device_node *np = dev->of_node; + struct sy8827n_device_info *di; + struct regulator_config config = { }; + struct regmap *regmap; + int ret; + + di = devm_kzalloc(dev, sizeof(struct sy8827n_device_info), GFP_KERNEL); + if (!di) + return -ENOMEM; + + di->regulator = of_get_regulator_init_data(dev, np, &di->desc); + if (!di->regulator) { + dev_err(dev, "Platform data not found!\n"); + return -EINVAL; + } + + di->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(di->en_gpio)) + return PTR_ERR(di->en_gpio); + + if (of_property_read_bool(np, "silergy,vsel-state-high")) + di->vsel_reg = SY8827N_VSEL1; + else + di->vsel_reg = SY8827N_VSEL0; + + di->dev = dev; + + regmap = devm_regmap_init_i2c(client, &sy8827n_regmap_config); + if (IS_ERR(regmap)) { + dev_err(dev, "Failed to allocate regmap!\n"); + return PTR_ERR(regmap); + } + i2c_set_clientdata(client, di); + + config.dev = di->dev; + config.init_data = di->regulator; + config.regmap = regmap; + config.driver_data = di; + config.of_node = np; + + ret = sy8827n_regulator_register(di, &config); + if (ret < 0) + dev_err(dev, "Failed to register regulator!\n"); + return ret; +} + +static const struct of_device_id sy8827n_dt_ids[] = { + { + .compatible = "silergy,sy8827n", + }, + { } +}; +MODULE_DEVICE_TABLE(of, sy8827n_dt_ids); + +static const struct i2c_device_id sy8827n_id[] = { + { "sy8827n", }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, sy8827n_id); + +static struct i2c_driver sy8827n_regulator_driver = { + .driver = { + .name = "sy8827n-regulator", + .of_match_table = of_match_ptr(sy8827n_dt_ids), + }, + .probe_new = sy8827n_i2c_probe, + .id_table = sy8827n_id, +}; +module_i2c_driver(sy8827n_regulator_driver); + +MODULE_AUTHOR("Jisheng Zhang "); +MODULE_DESCRIPTION("SY8827N regulator driver"); +MODULE_LICENSE("GPL v2"); From 573016266e6767f7917feeda8e1e3b19673f4981 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Thu, 2 Jul 2020 17:13:35 +0800 Subject: [PATCH 39/67] regulator: add document bindings for sy8827n Add device tree binding information for sy8827n regulator driver. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200702171335.59f5e79b@xhacker.debian Signed-off-by: Mark Brown --- .../bindings/regulator/silergy,sy8827n.yaml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml diff --git a/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml b/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml new file mode 100644 index 000000000000..15983cdc7c28 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/silergy,sy8827n.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: silergy sy8827n PMIC + +maintainers: + - Jisheng Zhang + +properties: + compatible: + enum: + - silergy,sy8827n + + reg: + maxItems: 1 + + enable-gpios: + description: GPIO to enable/disable the regulator. + maxItems: 1 + + silergy,vsel-state-high: + type: boolean + description: + Indicates if the VSEL pin is set to high. + If this property is missing, assume the VSEL pin is set to low. + +required: + - compatible + - reg + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + regulator@60 { + compatible = "silergy,sy8827n"; + reg = <0x60>; + }; + }; + +... From 6c8b65950b1c75b9e41b5bf314f5d7b81df91272 Mon Sep 17 00:00:00 2001 From: Anand K Mistry Date: Thu, 2 Jul 2020 13:15:22 +1000 Subject: [PATCH 40/67] regulator: da9211: Move buck modes into header file This will allow device trees to make use of these constants. Signed-off-by: Anand K Mistry Link: https://lore.kernel.org/r/20200702131350.1.I96e67ab7b4568287eb939e8a572cbc03e87f1aa0@changeid Signed-off-by: Mark Brown --- drivers/regulator/da9211-regulator.c | 5 +---- .../dt-bindings/regulator/dlg,da9211-regulator.h | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 include/dt-bindings/regulator/dlg,da9211-regulator.h diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 2ea4362ffa5c..1f9b75b41346 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "da9211-regulator.h" /* DEVICE IDs */ @@ -24,10 +25,6 @@ #define DA9213_DEVICE_ID 0x23 #define DA9215_DEVICE_ID 0x24 -#define DA9211_BUCK_MODE_SLEEP 1 -#define DA9211_BUCK_MODE_SYNC 2 -#define DA9211_BUCK_MODE_AUTO 3 - /* DA9211 REGULATOR IDs */ #define DA9211_ID_BUCKA 0 #define DA9211_ID_BUCKB 1 diff --git a/include/dt-bindings/regulator/dlg,da9211-regulator.h b/include/dt-bindings/regulator/dlg,da9211-regulator.h new file mode 100644 index 000000000000..cdce2d54c8ba --- /dev/null +++ b/include/dt-bindings/regulator/dlg,da9211-regulator.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _DT_BINDINGS_REGULATOR_DLG_DA9211_H +#define _DT_BINDINGS_REGULATOR_DLG_DA9211_H + +/* + * These buck mode constants may be used to specify values in device tree + * properties (e.g. regulator-initial-mode, regulator-allowed-modes). + * A description of the following modes is in the manufacturers datasheet. + */ + +#define DA9211_BUCK_MODE_SLEEP 1 +#define DA9211_BUCK_MODE_SYNC 2 +#define DA9211_BUCK_MODE_AUTO 3 + +#endif From 6f1f1a8039e5f7a61e932d6a9a50708c56e21033 Mon Sep 17 00:00:00 2001 From: Anand K Mistry Date: Thu, 2 Jul 2020 13:15:24 +1000 Subject: [PATCH 41/67] regulator: da9211: Implement of_map_mode Implementing of_map_mode is necessary to be able to specify operating modes in the devicetree using 'regulator-allowed-modes', and to change regulator modes. Signed-off-by: Anand K Mistry Link: https://lore.kernel.org/r/20200702131350.3.I6a0bc18fcdb2fe13e838a31e6d034d0e095368bc@changeid Signed-off-by: Mark Brown --- drivers/regulator/da9211-regulator.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 1f9b75b41346..297b3aa7c753 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -86,6 +86,20 @@ static const int da9215_current_limits[] = { 5600000, 5800000, 6000000, 6200000, 6400000, 6600000, 6800000, 7000000 }; +static unsigned int da9211_map_buck_mode(unsigned int mode) +{ + switch (mode) { + case DA9211_BUCK_MODE_SLEEP: + return REGULATOR_MODE_STANDBY; + case DA9211_BUCK_MODE_SYNC: + return REGULATOR_MODE_FAST; + case DA9211_BUCK_MODE_AUTO: + return REGULATOR_MODE_NORMAL; + default: + return REGULATOR_MODE_INVALID; + } +} + static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) { int id = rdev_get_id(rdev); @@ -233,6 +247,7 @@ static const struct regulator_ops da9211_buck_ops = { .vsel_reg = DA9211_REG_VBUCKA_A + DA9211_ID_##_id * 2,\ .vsel_mask = DA9211_VBUCK_MASK,\ .owner = THIS_MODULE,\ + .of_map_mode = da9211_map_buck_mode,\ } static struct regulator_desc da9211_regulators[] = { @@ -242,8 +257,14 @@ static struct regulator_desc da9211_regulators[] = { #ifdef CONFIG_OF static struct of_regulator_match da9211_matches[] = { - [DA9211_ID_BUCKA] = { .name = "BUCKA" }, - [DA9211_ID_BUCKB] = { .name = "BUCKB" }, + [DA9211_ID_BUCKA] = { + .name = "BUCKA", + .desc = &da9211_regulators[DA9211_ID_BUCKA], + }, + [DA9211_ID_BUCKB] = { + .name = "BUCKB", + .desc = &da9211_regulators[DA9211_ID_BUCKB], + }, }; static struct da9211_pdata *da9211_parse_regulators_dt( From 650e5adae0197bb9ecaa48b98b8ada1cc6772fb0 Mon Sep 17 00:00:00 2001 From: Anand K Mistry Date: Thu, 2 Jul 2020 13:15:23 +1000 Subject: [PATCH 42/67] regulator: da9211: Document allowed modes This patch adds a description of how operating modes may be specified. Signed-off-by: Anand K Mistry Link: https://lore.kernel.org/r/20200702131350.2.I6131e251d13f60d8c5347bb4faa9dc2364c87848@changeid Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/da9211.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/da9211.txt b/Documentation/devicetree/bindings/regulator/da9211.txt index 27717e816e71..eb871447d508 100644 --- a/Documentation/devicetree/bindings/regulator/da9211.txt +++ b/Documentation/devicetree/bindings/regulator/da9211.txt @@ -15,6 +15,8 @@ Required properties: Optional properties: - enable-gpios: platform gpio for control of BUCKA/BUCKB. - Any optional property defined in regulator.txt + - regulator-initial-mode and regulator-allowed-modes may be specified using + mode values from dt-bindings/regulator/dlg,da9211-regulator.h Example 1) DA9211 pmic: da9211@68 { @@ -30,6 +32,8 @@ Example 1) DA9211 regulator-min-microamp = <2000000>; regulator-max-microamp = <5000000>; enable-gpios = <&gpio 27 0>; + regulator-allowed-modes = ; }; }; }; From 94462138f368a5e079d53d578509276e4366d0c1 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 2 Jul 2020 12:56:59 +0100 Subject: [PATCH 43/67] regulator: fix null pointer check on regmap The null pointer check on regmap that checks for a dev_get_regmap failure is currently returning -ENOENT if the regmap succeeded. Fix this by adding in the missing ! operator. Fixes: 4fe66d5a62fb ("regulator: Add support for QCOM PMIC VBUS booster") Signed-off-by: Colin Ian King Addresses-Coverity: ("Dereference after null check") Link: https://lore.kernel.org/r/20200702115659.38208-1-colin.king@canonical.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_usb_vbus-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index 342d92373598..8ba947f3585f 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -49,7 +49,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) } regmap = dev_get_regmap(dev->parent, NULL); - if (regmap) { + if (!regmap) { dev_err(dev, "Failed to get regmap\n"); return -ENOENT; } From e2c6678bd836861093eecd733610f77b2d87e9f8 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Thu, 2 Jul 2020 10:02:00 +0800 Subject: [PATCH 44/67] regulator: mp886x: use .probe_new Use the new .probe_new for mp886x. It does not use the const struct i2c_device_id * argument, so convert it to utilise the simplified i2c driver registration. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200702100200.1a4c65d1@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/mp886x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index 1786f7162019..d3d475f717f4 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -206,8 +206,7 @@ static const struct regmap_config mp886x_regmap_config = { .val_bits = 8, }; -static int mp886x_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mp886x_i2c_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct device_node *np = dev->of_node; @@ -280,7 +279,7 @@ static struct i2c_driver mp886x_regulator_driver = { .name = "mp886x-regulator", .of_match_table = of_match_ptr(mp886x_dt_ids), }, - .probe = mp886x_i2c_probe, + .probe_new = mp886x_i2c_probe, .id_table = mp886x_id, }; module_i2c_driver(mp886x_regulator_driver); From e6dea51e2d41679d37a81d0b1247c039092af46b Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Thu, 2 Jul 2020 23:08:45 +0200 Subject: [PATCH 45/67] regulator: fan53880: Add initial support This patch adds support for ON Semiconductor FAN53880 regulator. The FAN53880 is an I2C porgrammable power management IC (PMIC) that contains a BUCK (step-down converter), four LDOs (low dropouts) and one BOOST (step-up converter). It is designed for mobile power applications. Signed-off-by: Christoph Fritz Link: https://lore.kernel.org/r/20200702210846.31659-2-chf.fritz@googlemail.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 ++ drivers/regulator/Makefile | 1 + drivers/regulator/fan53880.c | 179 +++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 drivers/regulator/fan53880.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index faa4cbfdc5d0..2c6a8c4bdf06 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -336,6 +336,16 @@ config REGULATOR_FAN53555 input voltage supply of 2.5V to 5.5V. The output voltage is programmed through an I2C interface. +config REGULATOR_FAN53880 + tristate "Fairchild FAN53880 Regulator" + depends on I2C + select REGMAP_I2C + help + This driver supports Fairchild (ON Semiconductor) FAN53880 + regulator. The regulator is a programmable power management IC + (PMIC), it is controlled by I2C and provides one BUCK, one BOOST + and four LDO outputs. + config REGULATOR_GPIO tristate "GPIO regulator support" depends on GPIOLIB || COMPILE_TEST diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index a20670a1eab0..85bc3ef0be1c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_REGULATOR_DA9211) += da9211-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o +obj-$(CONFIG_REGULATOR_FAN53880) += fan53880.o obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o obj-$(CONFIG_REGULATOR_HI6421V530) += hi6421v530-regulator.o diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c new file mode 100644 index 000000000000..285acc705a55 --- /dev/null +++ b/drivers/regulator/fan53880.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include +#include +#include +#include + +enum fan53880_regulator_ids { + FAN53880_LDO1, + FAN53880_LDO2, + FAN53880_LDO3, + FAN53880_LDO4, + FAN53880_BUCK, + FAN53880_BOOST, +}; + +enum fan53880_registers { + FAN53880_PRODUCT_ID = 0x00, + FAN53880_SILICON_REV, + FAN53880_BUCKVOUT, + FAN53880_BOOSTVOUT, + FAN53880_LDO1VOUT, + FAN53880_LDO2VOUT, + FAN53880_LDO3VOUT, + FAN53880_LDO4VOUT, + FAN53880_IOUT, + FAN53880_ENABLE, + FAN53880_ENABLE_BOOST, +}; + +#define FAN53880_ID 0x01 + +static const struct regulator_ops fan53880_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +#define FAN53880_LDO(_num, _supply, _default) \ + [FAN53880_LDO ## _num] = { \ + .name = "LDO"#_num, \ + .of_match = of_match_ptr("LDO"#_num), \ + .regulators_node = of_match_ptr("regulators"), \ + .type = REGULATOR_VOLTAGE, \ + .linear_ranges = (struct linear_range[]) { \ + REGULATOR_LINEAR_RANGE(_default, 0x0, 0x0, 0), \ + REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \ + }, \ + .n_linear_ranges = 2, \ + .vsel_reg = FAN53880_LDO ## _num ## VOUT, \ + .vsel_mask = 0x7f, \ + .enable_reg = FAN53880_ENABLE, \ + .enable_mask = BIT(_num - 1), \ + .enable_time = 150, \ + .supply_name = _supply, \ + .ops = &fan53880_ops, \ + } + +static const struct regulator_desc fan53880_regulators[] = { + FAN53880_LDO(1, "VIN12", 2800000), + FAN53880_LDO(2, "VIN12", 2800000), + FAN53880_LDO(3, "VIN3", 1800000), + FAN53880_LDO(4, "VIN4", 1800000), + [FAN53880_BUCK] = { + .name = "BUCK", + .of_match = of_match_ptr("BUCK"), + .regulators_node = of_match_ptr("regulators"), + .type = REGULATOR_VOLTAGE, + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0), + REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500), + }, + .n_linear_ranges = 2, + .vsel_reg = FAN53880_BUCKVOUT, + .vsel_mask = 0x7f, + .enable_reg = FAN53880_ENABLE, + .enable_mask = 0x10, + .enable_time = 480, + .supply_name = "PVIN", + .ops = &fan53880_ops, + }, + [FAN53880_BOOST] = { + .name = "BOOST", + .of_match = of_match_ptr("BOOST"), + .regulators_node = of_match_ptr("regulators"), + .type = REGULATOR_VOLTAGE, + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0), + REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000), + }, + .n_linear_ranges = 2, + .vsel_reg = FAN53880_BOOSTVOUT, + .vsel_mask = 0x7f, + .enable_reg = FAN53880_ENABLE_BOOST, + .enable_mask = 0xff, + .enable_time = 580, + .supply_name = "PVIN", + .ops = &fan53880_ops, + }, +}; + +static const struct regmap_config fan53880_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = FAN53880_ENABLE_BOOST, +}; + +static int fan53880_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regulator_config config = { }; + struct regulator_dev *rdev; + struct regmap *regmap; + int i, ret; + unsigned int data; + + regmap = devm_regmap_init_i2c(i2c, &fan53880_regmap); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); + return ret; + } + + ret = regmap_read(regmap, FAN53880_PRODUCT_ID, &data); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read PRODUCT_ID: %d\n", ret); + return ret; + } + if (data != FAN53880_ID) { + dev_err(&i2c->dev, "Unsupported device id: 0x%x.\n", data); + return -ENODEV; + } + + config.dev = &i2c->dev; + config.init_data = NULL; + + for (i = 0; i < ARRAY_SIZE(fan53880_regulators); i++) { + rdev = devm_regulator_register(&i2c->dev, + &fan53880_regulators[i], + &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(&i2c->dev, "Failed to register %s: %d\n", + fan53880_regulators[i].name, ret); + return ret; + } + } + + return 0; +} + +static const struct of_device_id fan53880_dt_ids[] = { + { .compatible = "onnn,fan53880", }, + {} +}; +MODULE_DEVICE_TABLE(of, fan53880_dt_ids); + +static const struct i2c_device_id fan53880_i2c_id[] = { + { "fan53880", }, + {} +}; +MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id); + +static struct i2c_driver fan53880_regulator_driver = { + .driver = { + .name = "fan53880", + .of_match_table = of_match_ptr(fan53880_dt_ids), + }, + .probe = fan53880_i2c_probe, + .id_table = fan53880_i2c_id, +}; +module_i2c_driver(fan53880_regulator_driver); + +MODULE_DESCRIPTION("FAN53880 PMIC voltage regulator driver"); +MODULE_AUTHOR("Christoph Fritz "); +MODULE_LICENSE("GPL"); From 643ddb618a5fd1819e790e86be85ae50c2c4abc4 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Thu, 2 Jul 2020 23:08:46 +0200 Subject: [PATCH 46/67] dt-bindings: regulator: Document bindings for fan53880 Add device tree binding information for fan53880 regulator driver. Signed-off-by: Christoph Fritz Link: https://lore.kernel.org/r/20200702210846.31659-3-chf.fritz@googlemail.com Signed-off-by: Mark Brown --- .../bindings/regulator/onnn,fan53880.yaml | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml diff --git a/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml b/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml new file mode 100644 index 000000000000..eb61e04ef852 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/onnn,fan53880.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Onsemi FAN53880 PMIC + +maintainers: + - Christoph Fritz + +description: | + The FAN53880 is an I2C porgrammable power management IC (PMIC) + that contains a BUCK (step-down converter), four low dropouts (LDO) + and one BOOST (step-up converter) output. It is designed for mobile + power applications. + +properties: + $nodename: + pattern: "pmic@[0-9a-f]{1,2}" + compatible: + enum: + - onnn,fan53880 + + reg: + maxItems: 1 + + VIN12-supply: + description: Input supply phandle(s) for LDO1 and LDO2 + + VIN3-supply: + description: Input supply phandle(s) for LDO3 + + VIN4-supply: + description: Input supply phandle(s) for LDO4 + + PVIN-supply: + description: Input supply phandle(s) for BUCK and BOOST + + regulators: + type: object + $ref: regulator.yaml# + description: | + list of regulators provided by this controller, must be named + after their hardware counterparts LDO[1-4], BUCK and BOOST + + patternProperties: + "^LDO[1-4]$": + type: object + $ref: regulator.yaml# + + "^BUCK|BOOST$": + type: object + $ref: regulator.yaml# + + additionalProperties: false + +required: + - compatible + - reg + - regulators + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@35 { + compatible = "onnn,fan53880"; + reg = <0x35>; + + PVIN-supply = <&fixreg_example_vcc>; + + regulators { + BUCK { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; + }; + }; +... From 0935ff5f1f0a44f66a13e075ed49f97ad99d2fdc Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Sat, 4 Jul 2020 00:19:35 +0800 Subject: [PATCH 47/67] regulator: pca9450: add pca9450 pmic driver Add NXP pca9450 pmic driver. Signed-off-by: Robin Gong Reviewed-by: Frieder Schrempf Link: https://lore.kernel.org/r/1593793178-9737-2-git-send-email-yibin.gong@nxp.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/pca9450-regulator.c | 843 ++++++++++++++++++++++++++ include/linux/regulator/pca9450.h | 219 +++++++ 4 files changed, 1071 insertions(+) create mode 100644 drivers/regulator/pca9450-regulator.c create mode 100644 include/linux/regulator/pca9450.h diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2c6a8c4bdf06..8f9bef574af2 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -750,6 +750,14 @@ config REGULATOR_PBIAS This driver provides support for OMAP pbias modelled regulators. +config REGULATOR_PCA9450 + tristate "NXP PCA9450A/PCA9450B/PCA9450C regulator driver" + depends on I2C + select REGMAP_I2C + help + Say y here to support the NXP PCA9450A/PCA9450B/PCA9450C PMIC + regulator driver. + config REGULATOR_PCAP tristate "Motorola PCAP2 regulator driver" depends on EZX_PCAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 85bc3ef0be1c..6adfe769a47c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -96,6 +96,7 @@ obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o obj-$(CONFIG_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus-regulator.o obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o +obj-$(CONFIG_REGULATOR_PCA9450) += pca9450-regulator.o obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o obj-$(CONFIG_REGULATOR_PV88080) += pv88080-regulator.o diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c new file mode 100644 index 000000000000..02250459aa90 --- /dev/null +++ b/drivers/regulator/pca9450-regulator.c @@ -0,0 +1,843 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2020 NXP. + * NXP PCA9450 pmic driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct pc9450_dvs_config { + unsigned int run_reg; /* dvs0 */ + unsigned int run_mask; + unsigned int standby_reg; /* dvs1 */ + unsigned int standby_mask; +}; + +struct pca9450_regulator_desc { + struct regulator_desc desc; + const struct pc9450_dvs_config dvs; +}; + +struct pca9450 { + struct device *dev; + struct regmap *regmap; + enum pca9450_chip_type type; + unsigned int rcnt; + int irq; +}; + +static const struct regmap_range pca9450_status_range = { + .range_min = PCA9450_REG_INT1, + .range_max = PCA9450_REG_PWRON_STAT, +}; + +static const struct regmap_access_table pca9450_volatile_regs = { + .yes_ranges = &pca9450_status_range, + .n_yes_ranges = 1, +}; + +static const struct regmap_config pca9450_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_table = &pca9450_volatile_regs, + .max_register = PCA9450_MAX_REGISTER - 1, + .cache_type = REGCACHE_RBTREE, +}; + +/* + * BUCK1/2/3 + * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting + * 00: 25mV/1usec + * 01: 25mV/2usec + * 10: 25mV/4usec + * 11: 25mV/8usec + */ +static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev, + int ramp_delay) +{ + int id = rdev_get_id(rdev); + unsigned int ramp_value; + + switch (ramp_delay) { + case 1 ... 3125: + ramp_value = BUCK1_RAMP_3P125MV; + break; + case 3126 ... 6250: + ramp_value = BUCK1_RAMP_6P25MV; + break; + case 6251 ... 12500: + ramp_value = BUCK1_RAMP_12P5MV; + break; + case 12501 ... 25000: + ramp_value = BUCK1_RAMP_25MV; + break; + default: + ramp_value = BUCK1_RAMP_25MV; + } + + return regmap_update_bits(rdev->regmap, PCA9450_REG_BUCK1CTRL + id * 3, + BUCK1_RAMP_MASK, ramp_value << 6); +} + +static struct regulator_ops pca9450_dvs_buck_regulator_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = pca9450_dvs_set_ramp_delay, +}; + +static struct regulator_ops pca9450_buck_regulator_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, +}; + +static struct regulator_ops pca9450_ldo_regulator_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, +}; + +/* + * BUCK1/2/3 + * 0.60 to 2.1875V (12.5mV step) + */ +static const struct linear_range pca9450_dvs_buck_volts[] = { + REGULATOR_LINEAR_RANGE(600000, 0x00, 0x7F, 12500), +}; + +/* + * BUCK4/5/6 + * 0.6V to 3.4V (25mV step) + */ +static const struct linear_range pca9450_buck_volts[] = { + REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000), + REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0), +}; + +/* + * LDO1 + * 1.6 to 3.3V () + */ +static const struct linear_range pca9450_ldo1_volts[] = { + REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000), + REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000), +}; + +/* + * LDO2 + * 0.8 to 1.15V (50mV step) + */ +static const struct linear_range pca9450_ldo2_volts[] = { + REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000), +}; + +/* + * LDO3/4 + * 0.8 to 3.3V (100mV step) + */ +static const struct linear_range pca9450_ldo34_volts[] = { + REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000), + REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0), +}; + +/* + * LDO5 + * 1.8 to 3.3V (100mV step) + */ +static const struct linear_range pca9450_ldo5_volts[] = { + REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), +}; + +static int buck_set_dvs(const struct regulator_desc *desc, + struct device_node *np, struct regmap *regmap, + char *prop, unsigned int reg, unsigned int mask) +{ + int ret, i; + uint32_t uv; + + ret = of_property_read_u32(np, prop, &uv); + if (ret == -EINVAL) + return 0; + else if (ret) + return ret; + + for (i = 0; i < desc->n_voltages; i++) { + ret = regulator_desc_list_voltage_linear_range(desc, i); + if (ret < 0) + continue; + if (ret == uv) { + i <<= ffs(desc->vsel_mask) - 1; + ret = regmap_update_bits(regmap, reg, mask, i); + break; + } + } + + return ret; +} + +static int pca9450_set_dvs_levels(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *cfg) +{ + struct pca9450_regulator_desc *data = container_of(desc, + struct pca9450_regulator_desc, desc); + const struct pc9450_dvs_config *dvs = &data->dvs; + unsigned int reg, mask; + char *prop; + int i, ret = 0; + + for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) { + switch (i) { + case PCA9450_DVS_LEVEL_RUN: + prop = "nxp,dvs-run-voltage"; + reg = dvs->run_reg; + mask = dvs->run_mask; + break; + case PCA9450_DVS_LEVEL_STANDBY: + prop = "nxp,dvs-standby-voltage"; + reg = dvs->standby_reg; + mask = dvs->standby_mask; + break; + default: + return -EINVAL; + } + + ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask); + if (ret) + break; + } + + return ret; +} + +static const struct pca9450_regulator_desc pca9450a_regulators[] = { + { + .desc = { + .name = "buck1", + .of_match = of_match_ptr("BUCK1"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK1, + .ops = &pca9450_dvs_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM, + .linear_ranges = pca9450_dvs_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts), + .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0, + .vsel_mask = BUCK1OUT_DVS0_MASK, + .enable_reg = PCA9450_REG_BUCK1CTRL, + .enable_mask = BUCK1_ENMODE_MASK, + .owner = THIS_MODULE, + .of_parse_cb = pca9450_set_dvs_levels, + }, + .dvs = { + .run_reg = PCA9450_REG_BUCK1OUT_DVS0, + .run_mask = BUCK1OUT_DVS0_MASK, + .standby_reg = PCA9450_REG_BUCK1OUT_DVS1, + .standby_mask = BUCK1OUT_DVS1_MASK, + }, + }, + { + .desc = { + .name = "buck2", + .of_match = of_match_ptr("BUCK2"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK2, + .ops = &pca9450_dvs_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM, + .linear_ranges = pca9450_dvs_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts), + .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0, + .vsel_mask = BUCK2OUT_DVS0_MASK, + .enable_reg = PCA9450_REG_BUCK2CTRL, + .enable_mask = BUCK1_ENMODE_MASK, + .owner = THIS_MODULE, + .of_parse_cb = pca9450_set_dvs_levels, + }, + .dvs = { + .run_reg = PCA9450_REG_BUCK2OUT_DVS0, + .run_mask = BUCK2OUT_DVS0_MASK, + .standby_reg = PCA9450_REG_BUCK2OUT_DVS1, + .standby_mask = BUCK2OUT_DVS1_MASK, + }, + }, + { + .desc = { + .name = "buck3", + .of_match = of_match_ptr("BUCK3"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK3, + .ops = &pca9450_dvs_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK3_VOLTAGE_NUM, + .linear_ranges = pca9450_dvs_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts), + .vsel_reg = PCA9450_REG_BUCK3OUT_DVS0, + .vsel_mask = BUCK3OUT_DVS0_MASK, + .enable_reg = PCA9450_REG_BUCK3CTRL, + .enable_mask = BUCK3_ENMODE_MASK, + .owner = THIS_MODULE, + .of_parse_cb = pca9450_set_dvs_levels, + }, + .dvs = { + .run_reg = PCA9450_REG_BUCK3OUT_DVS0, + .run_mask = BUCK3OUT_DVS0_MASK, + .standby_reg = PCA9450_REG_BUCK3OUT_DVS1, + .standby_mask = BUCK3OUT_DVS1_MASK, + }, + }, + { + .desc = { + .name = "buck4", + .of_match = of_match_ptr("BUCK4"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK4, + .ops = &pca9450_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM, + .linear_ranges = pca9450_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts), + .vsel_reg = PCA9450_REG_BUCK4OUT, + .vsel_mask = BUCK4OUT_MASK, + .enable_reg = PCA9450_REG_BUCK4CTRL, + .enable_mask = BUCK4_ENMODE_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "buck5", + .of_match = of_match_ptr("BUCK5"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK5, + .ops = &pca9450_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM, + .linear_ranges = pca9450_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts), + .vsel_reg = PCA9450_REG_BUCK5OUT, + .vsel_mask = BUCK5OUT_MASK, + .enable_reg = PCA9450_REG_BUCK5CTRL, + .enable_mask = BUCK5_ENMODE_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "buck6", + .of_match = of_match_ptr("BUCK6"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK6, + .ops = &pca9450_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM, + .linear_ranges = pca9450_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts), + .vsel_reg = PCA9450_REG_BUCK6OUT, + .vsel_mask = BUCK6OUT_MASK, + .enable_reg = PCA9450_REG_BUCK6CTRL, + .enable_mask = BUCK6_ENMODE_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo1", + .of_match = of_match_ptr("LDO1"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO1, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO1_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo1_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts), + .vsel_reg = PCA9450_REG_LDO1CTRL, + .vsel_mask = LDO1OUT_MASK, + .enable_reg = PCA9450_REG_LDO1CTRL, + .enable_mask = LDO1_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo2", + .of_match = of_match_ptr("LDO2"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO2, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO2_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo2_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts), + .vsel_reg = PCA9450_REG_LDO2CTRL, + .vsel_mask = LDO2OUT_MASK, + .enable_reg = PCA9450_REG_LDO2CTRL, + .enable_mask = LDO2_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo3", + .of_match = of_match_ptr("LDO3"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO3, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO3_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo34_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts), + .vsel_reg = PCA9450_REG_LDO3CTRL, + .vsel_mask = LDO3OUT_MASK, + .enable_reg = PCA9450_REG_LDO3CTRL, + .enable_mask = LDO3_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo4", + .of_match = of_match_ptr("LDO4"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO4, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO4_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo34_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts), + .vsel_reg = PCA9450_REG_LDO4CTRL, + .vsel_mask = LDO4OUT_MASK, + .enable_reg = PCA9450_REG_LDO4CTRL, + .enable_mask = LDO4_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo5", + .of_match = of_match_ptr("LDO5"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO5, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO5_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo5_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts), + .vsel_reg = PCA9450_REG_LDO5CTRL_H, + .vsel_mask = LDO5HOUT_MASK, + .enable_reg = PCA9450_REG_LDO5CTRL_H, + .enable_mask = LDO5H_EN_MASK, + .owner = THIS_MODULE, + }, + }, +}; + +/* + * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase + * on PCA9450C as no Buck3. + */ +static const struct pca9450_regulator_desc pca9450bc_regulators[] = { + { + .desc = { + .name = "buck1", + .of_match = of_match_ptr("BUCK1"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK1, + .ops = &pca9450_dvs_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM, + .linear_ranges = pca9450_dvs_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts), + .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0, + .vsel_mask = BUCK1OUT_DVS0_MASK, + .enable_reg = PCA9450_REG_BUCK1CTRL, + .enable_mask = BUCK1_ENMODE_MASK, + .owner = THIS_MODULE, + .of_parse_cb = pca9450_set_dvs_levels, + }, + .dvs = { + .run_reg = PCA9450_REG_BUCK1OUT_DVS0, + .run_mask = BUCK1OUT_DVS0_MASK, + .standby_reg = PCA9450_REG_BUCK1OUT_DVS1, + .standby_mask = BUCK1OUT_DVS1_MASK, + }, + }, + { + .desc = { + .name = "buck2", + .of_match = of_match_ptr("BUCK2"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK2, + .ops = &pca9450_dvs_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM, + .linear_ranges = pca9450_dvs_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts), + .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0, + .vsel_mask = BUCK2OUT_DVS0_MASK, + .enable_reg = PCA9450_REG_BUCK2CTRL, + .enable_mask = BUCK1_ENMODE_MASK, + .owner = THIS_MODULE, + .of_parse_cb = pca9450_set_dvs_levels, + }, + .dvs = { + .run_reg = PCA9450_REG_BUCK2OUT_DVS0, + .run_mask = BUCK2OUT_DVS0_MASK, + .standby_reg = PCA9450_REG_BUCK2OUT_DVS1, + .standby_mask = BUCK2OUT_DVS1_MASK, + }, + }, + { + .desc = { + .name = "buck4", + .of_match = of_match_ptr("BUCK4"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK4, + .ops = &pca9450_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM, + .linear_ranges = pca9450_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts), + .vsel_reg = PCA9450_REG_BUCK4OUT, + .vsel_mask = BUCK4OUT_MASK, + .enable_reg = PCA9450_REG_BUCK4CTRL, + .enable_mask = BUCK4_ENMODE_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "buck5", + .of_match = of_match_ptr("BUCK5"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK5, + .ops = &pca9450_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM, + .linear_ranges = pca9450_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts), + .vsel_reg = PCA9450_REG_BUCK5OUT, + .vsel_mask = BUCK5OUT_MASK, + .enable_reg = PCA9450_REG_BUCK5CTRL, + .enable_mask = BUCK5_ENMODE_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "buck6", + .of_match = of_match_ptr("BUCK6"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_BUCK6, + .ops = &pca9450_buck_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM, + .linear_ranges = pca9450_buck_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts), + .vsel_reg = PCA9450_REG_BUCK6OUT, + .vsel_mask = BUCK6OUT_MASK, + .enable_reg = PCA9450_REG_BUCK6CTRL, + .enable_mask = BUCK6_ENMODE_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo1", + .of_match = of_match_ptr("LDO1"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO1, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO1_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo1_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts), + .vsel_reg = PCA9450_REG_LDO1CTRL, + .vsel_mask = LDO1OUT_MASK, + .enable_reg = PCA9450_REG_LDO1CTRL, + .enable_mask = LDO1_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo2", + .of_match = of_match_ptr("LDO2"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO2, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO2_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo2_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts), + .vsel_reg = PCA9450_REG_LDO2CTRL, + .vsel_mask = LDO2OUT_MASK, + .enable_reg = PCA9450_REG_LDO2CTRL, + .enable_mask = LDO2_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo3", + .of_match = of_match_ptr("LDO3"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO3, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO3_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo34_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts), + .vsel_reg = PCA9450_REG_LDO3CTRL, + .vsel_mask = LDO3OUT_MASK, + .enable_reg = PCA9450_REG_LDO3CTRL, + .enable_mask = LDO3_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo4", + .of_match = of_match_ptr("LDO4"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO4, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO4_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo34_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts), + .vsel_reg = PCA9450_REG_LDO4CTRL, + .vsel_mask = LDO4OUT_MASK, + .enable_reg = PCA9450_REG_LDO4CTRL, + .enable_mask = LDO4_EN_MASK, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "ldo5", + .of_match = of_match_ptr("LDO5"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO5, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO5_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo5_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts), + .vsel_reg = PCA9450_REG_LDO5CTRL_H, + .vsel_mask = LDO5HOUT_MASK, + .enable_reg = PCA9450_REG_LDO5CTRL_H, + .enable_mask = LDO5H_EN_MASK, + .owner = THIS_MODULE, + }, + }, +}; + +static irqreturn_t pca9450_irq_handler(int irq, void *data) +{ + struct pca9450 *pca9450 = data; + struct regmap *regmap = pca9450->regmap; + unsigned int status; + int ret; + + ret = regmap_read(regmap, PCA9450_REG_INT1, &status); + if (ret < 0) { + dev_err(pca9450->dev, + "Failed to read INT1(%d)\n", ret); + return IRQ_NONE; + } + + if (status & IRQ_PWRON) + dev_warn(pca9450->dev, "PWRON interrupt.\n"); + + if (status & IRQ_WDOGB) + dev_warn(pca9450->dev, "WDOGB interrupt.\n"); + + if (status & IRQ_VR_FLT1) + dev_warn(pca9450->dev, "VRFLT1 interrupt.\n"); + + if (status & IRQ_VR_FLT2) + dev_warn(pca9450->dev, "VRFLT2 interrupt.\n"); + + if (status & IRQ_LOWVSYS) + dev_warn(pca9450->dev, "LOWVSYS interrupt.\n"); + + if (status & IRQ_THERM_105) + dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n"); + + if (status & IRQ_THERM_125) + dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n"); + + return IRQ_HANDLED; +} + +static int pca9450_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + enum pca9450_chip_type type = (unsigned int)(uintptr_t) + of_device_get_match_data(&i2c->dev); + const struct pca9450_regulator_desc *regulator_desc; + struct regulator_config config = { }; + struct pca9450 *pca9450; + unsigned int device_id, i; + int ret; + + if (!i2c->irq) { + dev_err(&i2c->dev, "No IRQ configured?\n"); + return -EINVAL; + } + + pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL); + if (!pca9450) + return -ENOMEM; + + switch (type) { + case PCA9450_TYPE_PCA9450A: + regulator_desc = pca9450a_regulators; + pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators); + break; + case PCA9450_TYPE_PCA9450BC: + regulator_desc = pca9450bc_regulators; + pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators); + break; + default: + dev_err(&i2c->dev, "Unknown device type"); + return -EINVAL; + } + + pca9450->irq = i2c->irq; + pca9450->type = type; + pca9450->dev = &i2c->dev; + + dev_set_drvdata(&i2c->dev, pca9450); + + pca9450->regmap = devm_regmap_init_i2c(i2c, + &pca9450_regmap_config); + if (IS_ERR(pca9450->regmap)) { + dev_err(&i2c->dev, "regmap initialization failed\n"); + return PTR_ERR(pca9450->regmap); + } + + ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id); + if (ret) { + dev_err(&i2c->dev, "Read device id error\n"); + return ret; + } + + /* Check your board and dts for match the right pmic */ + if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) || + ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) { + dev_err(&i2c->dev, "Device id(%x) mismatched\n", + device_id >> 4); + return -EINVAL; + } + + for (i = 0; i < pca9450->rcnt; i++) { + const struct regulator_desc *desc; + struct regulator_dev *rdev; + const struct pca9450_regulator_desc *r; + + r = ®ulator_desc[i]; + desc = &r->desc; + + config.regmap = pca9450->regmap; + config.dev = pca9450->dev; + + rdev = devm_regulator_register(pca9450->dev, desc, &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(pca9450->dev, + "Failed to register regulator(%s): %d\n", + desc->name, ret); + return ret; + } + } + + ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL, + pca9450_irq_handler, + (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), + "pca9450-irq", pca9450); + if (ret != 0) { + dev_err(pca9450->dev, "Failed to request IRQ: %d\n", + pca9450->irq); + return ret; + } + /* Unmask all interrupt except PWRON/WDOG/RSVD */ + ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK, + IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS | + IRQ_THERM_105 | IRQ_THERM_125, + IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD); + if (ret) { + dev_err(&i2c->dev, "Unmask irq error\n"); + return ret; + } + + dev_info(&i2c->dev, "%s probed.\n", + type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc"); + + return 0; +} + +static const struct of_device_id pca9450_of_match[] = { + { + .compatible = "nxp,pca9450a", + .data = (void *)PCA9450_TYPE_PCA9450A, + }, + { + .compatible = "nxp,pca9450b", + .data = (void *)PCA9450_TYPE_PCA9450BC, + }, + { + .compatible = "nxp,pca9450c", + .data = (void *)PCA9450_TYPE_PCA9450BC, + }, + { } +}; +MODULE_DEVICE_TABLE(of, pca9450_of_match); + +static struct i2c_driver pca9450_i2c_driver = { + .driver = { + .name = "nxp-pca9450", + .of_match_table = pca9450_of_match, + }, + .probe = pca9450_i2c_probe, +}; + +static int __init pca9450_i2c_init(void) +{ + return i2c_add_driver(&pca9450_i2c_driver); +} +module_init(pca9450_i2c_init); + +static void __exit pca9450_i2c_exit(void) +{ + i2c_del_driver(&pca9450_i2c_driver); +} +module_exit(pca9450_i2c_exit); + +MODULE_AUTHOR("Robin Gong "); +MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h new file mode 100644 index 000000000000..1bbd3014f906 --- /dev/null +++ b/include/linux/regulator/pca9450.h @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright 2020 NXP. */ + +#ifndef __LINUX_REG_PCA9450_H__ +#define __LINUX_REG_PCA9450_H__ + +#include + +enum pca9450_chip_type { + PCA9450_TYPE_PCA9450A = 0, + PCA9450_TYPE_PCA9450BC, + PCA9450_TYPE_AMOUNT, +}; + +enum { + PCA9450_BUCK1 = 0, + PCA9450_BUCK2, + PCA9450_BUCK3, + PCA9450_BUCK4, + PCA9450_BUCK5, + PCA9450_BUCK6, + PCA9450_LDO1, + PCA9450_LDO2, + PCA9450_LDO3, + PCA9450_LDO4, + PCA9450_LDO5, + PCA9450_REGULATOR_CNT, +}; + +enum { + PCA9450_DVS_LEVEL_RUN = 0, + PCA9450_DVS_LEVEL_STANDBY, + PCA9450_DVS_LEVEL_MAX, +}; + +#define PCA9450_BUCK1_VOLTAGE_NUM 0x80 +#define PCA9450_BUCK2_VOLTAGE_NUM 0x80 +#define PCA9450_BUCK3_VOLTAGE_NUM 0x80 +#define PCA9450_BUCK4_VOLTAGE_NUM 0x80 + +#define PCA9450_BUCK5_VOLTAGE_NUM 0x80 +#define PCA9450_BUCK6_VOLTAGE_NUM 0x80 + +#define PCA9450_LDO1_VOLTAGE_NUM 0x08 +#define PCA9450_LDO2_VOLTAGE_NUM 0x08 +#define PCA9450_LDO3_VOLTAGE_NUM 0x20 +#define PCA9450_LDO4_VOLTAGE_NUM 0x20 +#define PCA9450_LDO5_VOLTAGE_NUM 0x10 + +enum { + PCA9450_REG_DEV_ID = 0x00, + PCA9450_REG_INT1 = 0x01, + PCA9450_REG_INT1_MSK = 0x02, + PCA9450_REG_STATUS1 = 0x03, + PCA9450_REG_STATUS2 = 0x04, + PCA9450_REG_PWRON_STAT = 0x05, + PCA9450_REG_SWRST = 0x06, + PCA9450_REG_PWRCTRL = 0x07, + PCA9450_REG_RESET_CTRL = 0x08, + PCA9450_REG_CONFIG1 = 0x09, + PCA9450_REG_CONFIG2 = 0x0A, + PCA9450_REG_BUCK123_DVS = 0x0C, + PCA9450_REG_BUCK1OUT_LIMIT = 0x0D, + PCA9450_REG_BUCK2OUT_LIMIT = 0x0E, + PCA9450_REG_BUCK3OUT_LIMIT = 0x0F, + PCA9450_REG_BUCK1CTRL = 0x10, + PCA9450_REG_BUCK1OUT_DVS0 = 0x11, + PCA9450_REG_BUCK1OUT_DVS1 = 0x12, + PCA9450_REG_BUCK2CTRL = 0x13, + PCA9450_REG_BUCK2OUT_DVS0 = 0x14, + PCA9450_REG_BUCK2OUT_DVS1 = 0x15, + PCA9450_REG_BUCK3CTRL = 0x16, + PCA9450_REG_BUCK3OUT_DVS0 = 0x17, + PCA9450_REG_BUCK3OUT_DVS1 = 0x18, + PCA9450_REG_BUCK4CTRL = 0x19, + PCA9450_REG_BUCK4OUT = 0x1A, + PCA9450_REG_BUCK5CTRL = 0x1B, + PCA9450_REG_BUCK5OUT = 0x1C, + PCA9450_REG_BUCK6CTRL = 0x1D, + PCA9450_REG_BUCK6OUT = 0x1E, + PCA9450_REG_LDO_AD_CTRL = 0x20, + PCA9450_REG_LDO1CTRL = 0x21, + PCA9450_REG_LDO2CTRL = 0x22, + PCA9450_REG_LDO3CTRL = 0x23, + PCA9450_REG_LDO4CTRL = 0x24, + PCA9450_REG_LDO5CTRL_L = 0x25, + PCA9450_REG_LDO5CTRL_H = 0x26, + PCA9450_REG_LOADSW_CTRL = 0x2A, + PCA9450_REG_VRFLT1_STS = 0x2B, + PCA9450_REG_VRFLT2_STS = 0x2C, + PCA9450_REG_VRFLT1_MASK = 0x2D, + PCA9450_REG_VRFLT2_MASK = 0x2E, + PCA9450_MAX_REGISTER = 0x2F, +}; + +/* PCA9450 BUCK ENMODE bits */ +#define BUCK_ENMODE_OFF 0x00 +#define BUCK_ENMODE_ONREQ 0x01 +#define BUCK_ENMODE_ONREQ_STBYREQ 0x02 +#define BUCK_ENMODE_ON 0x03 + +/* PCA9450_REG_BUCK1_CTRL bits */ +#define BUCK1_RAMP_MASK 0xC0 +#define BUCK1_RAMP_25MV 0x0 +#define BUCK1_RAMP_12P5MV 0x1 +#define BUCK1_RAMP_6P25MV 0x2 +#define BUCK1_RAMP_3P125MV 0x3 +#define BUCK1_DVS_CTRL 0x10 +#define BUCK1_AD 0x08 +#define BUCK1_FPWM 0x04 +#define BUCK1_ENMODE_MASK 0x03 + +/* PCA9450_REG_BUCK2_CTRL bits */ +#define BUCK2_RAMP_MASK 0xC0 +#define BUCK2_RAMP_25MV 0x0 +#define BUCK2_RAMP_12P5MV 0x1 +#define BUCK2_RAMP_6P25MV 0x2 +#define BUCK2_RAMP_3P125MV 0x3 +#define BUCK2_DVS_CTRL 0x10 +#define BUCK2_AD 0x08 +#define BUCK2_FPWM 0x04 +#define BUCK2_ENMODE_MASK 0x03 + +/* PCA9450_REG_BUCK3_CTRL bits */ +#define BUCK3_RAMP_MASK 0xC0 +#define BUCK3_RAMP_25MV 0x0 +#define BUCK3_RAMP_12P5MV 0x1 +#define BUCK3_RAMP_6P25MV 0x2 +#define BUCK3_RAMP_3P125MV 0x3 +#define BUCK3_DVS_CTRL 0x10 +#define BUCK3_AD 0x08 +#define BUCK3_FPWM 0x04 +#define BUCK3_ENMODE_MASK 0x03 + +/* PCA9450_REG_BUCK4_CTRL bits */ +#define BUCK4_AD 0x08 +#define BUCK4_FPWM 0x04 +#define BUCK4_ENMODE_MASK 0x03 + +/* PCA9450_REG_BUCK5_CTRL bits */ +#define BUCK5_AD 0x08 +#define BUCK5_FPWM 0x04 +#define BUCK5_ENMODE_MASK 0x03 + +/* PCA9450_REG_BUCK6_CTRL bits */ +#define BUCK6_AD 0x08 +#define BUCK6_FPWM 0x04 +#define BUCK6_ENMODE_MASK 0x03 + +/* PCA9450_BUCK1OUT_DVS0 bits */ +#define BUCK1OUT_DVS0_MASK 0x7F +#define BUCK1OUT_DVS0_DEFAULT 0x14 + +/* PCA9450_BUCK1OUT_DVS1 bits */ +#define BUCK1OUT_DVS1_MASK 0x7F +#define BUCK1OUT_DVS1_DEFAULT 0x14 + +/* PCA9450_BUCK2OUT_DVS0 bits */ +#define BUCK2OUT_DVS0_MASK 0x7F +#define BUCK2OUT_DVS0_DEFAULT 0x14 + +/* PCA9450_BUCK2OUT_DVS1 bits */ +#define BUCK2OUT_DVS1_MASK 0x7F +#define BUCK2OUT_DVS1_DEFAULT 0x14 + +/* PCA9450_BUCK3OUT_DVS0 bits */ +#define BUCK3OUT_DVS0_MASK 0x7F +#define BUCK3OUT_DVS0_DEFAULT 0x14 + +/* PCA9450_BUCK3OUT_DVS1 bits */ +#define BUCK3OUT_DVS1_MASK 0x7F +#define BUCK3OUT_DVS1_DEFAULT 0x14 + +/* PCA9450_REG_BUCK4OUT bits */ +#define BUCK4OUT_MASK 0x7F +#define BUCK4OUT_DEFAULT 0x6C + +/* PCA9450_REG_BUCK5OUT bits */ +#define BUCK5OUT_MASK 0x7F +#define BUCK5OUT_DEFAULT 0x30 + +/* PCA9450_REG_BUCK6OUT bits */ +#define BUCK6OUT_MASK 0x7F +#define BUCK6OUT_DEFAULT 0x14 + +/* PCA9450_REG_LDO1_VOLT bits */ +#define LDO1_EN_MASK 0xC0 +#define LDO1OUT_MASK 0x07 + +/* PCA9450_REG_LDO2_VOLT bits */ +#define LDO2_EN_MASK 0xC0 +#define LDO2OUT_MASK 0x07 + +/* PCA9450_REG_LDO3_VOLT bits */ +#define LDO3_EN_MASK 0xC0 +#define LDO3OUT_MASK 0x0F + +/* PCA9450_REG_LDO4_VOLT bits */ +#define LDO4_EN_MASK 0xC0 +#define LDO4OUT_MASK 0x0F + +/* PCA9450_REG_LDO5_VOLT bits */ +#define LDO5L_EN_MASK 0xC0 +#define LDO5LOUT_MASK 0x0F + +#define LDO5H_EN_MASK 0xC0 +#define LDO5HOUT_MASK 0x0F + +/* PCA9450_REG_IRQ bits */ +#define IRQ_PWRON 0x80 +#define IRQ_WDOGB 0x40 +#define IRQ_RSVD 0x20 +#define IRQ_VR_FLT1 0x10 +#define IRQ_VR_FLT2 0x08 +#define IRQ_LOWVSYS 0x04 +#define IRQ_THERM_105 0x02 +#define IRQ_THERM_125 0x01 + +#endif /* __LINUX_REG_PCA9450_H__ */ From 7ae9e3a6bf3fb1b5a35a15d8a6e78fc42bed0867 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Sat, 4 Jul 2020 00:19:36 +0800 Subject: [PATCH 48/67] dt-bindings: regulator: add pca9450 regulator yaml Add device binding doc for pca9450 pmic driver. Signed-off-by: Robin Gong Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1593793178-9737-3-git-send-email-yibin.gong@nxp.com Signed-off-by: Mark Brown --- .../regulator/nxp,pca9450-regulator.yaml | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml new file mode 100644 index 000000000000..c2b0a8b6da1e --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml @@ -0,0 +1,190 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/nxp,pca9450-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP PCA9450A/B/C Power Management Integrated Circuit regulators + +maintainers: + - Robin Gong + +description: | + Regulator nodes should be named to BUCK_ and LDO_. The + definition for each of these nodes is defined using the standard + binding for regulators at + Documentation/devicetree/bindings/regulator/regulator.txt. + Datasheet is available at + https://www.nxp.com/docs/en/data-sheet/PCA9450DS.pdf + +#The valid names for PCA9450 regulator nodes are: +#BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, +#LDO1, LDO2, LDO3, LDO4, LDO5 +#Note: Buck3 removed on PCA9450B and connect with Buck1 on PCA9450C. + +properties: + compatible: + enum: + - nxp,pca9450a + - nxp,pca9450b + - nxp,pca9450c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + regulators: + type: object + description: | + list of regulators provided by this controller + + patternProperties: + "^LDO[1-5]$": + type: object + $ref: regulator.yaml# + description: + Properties for single LDO regulator. + + properties: + regulator-name: + pattern: "^LDO[1-5]$" + description: + should be "LDO1", ..., "LDO5" + + unevaluatedProperties: false + + "^BUCK[1-6]$": + type: object + $ref: regulator.yaml# + description: + Properties for single BUCK regulator. + + properties: + regulator-name: + pattern: "^BUCK[1-6]$" + description: + should be "BUCK1", ..., "BUCK6" + + nxp,dvs-run-voltage: + $ref: "/schemas/types.yaml#/definitions/uint32" + minimum: 600000 + maximum: 2187500 + description: + PMIC default "RUN" state voltage in uV. Only Buck1~3 have such + dvs(dynamic voltage scaling) property. + + nxp,dvs-standby-voltage: + $ref: "/schemas/types.yaml#/definitions/uint32" + minimum: 600000 + maximum: 2187500 + description: + PMIC default "STANDBY" state voltage in uV. Only Buck1~3 have such + dvs(dynamic voltage scaling) property. + + unevaluatedProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - regulators + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + pmic: pmic@25 { + compatible = "nxp,pca9450b"; + reg = <0x25>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + + regulators { + buck1: BUCK1 { + regulator-name = "BUCK1"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <2187500>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + }; + buck2: BUCK2 { + regulator-name = "BUCK2"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <2187500>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <3125>; + nxp,dvs-run-voltage = <950000>; + nxp,dvs-standby-voltage = <850000>; + }; + buck4: BUCK4 { + regulator-name = "BUCK4"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + buck5: BUCK5 { + regulator-name = "BUCK5"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + buck6: BUCK6 { + regulator-name = "BUCK6"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1: LDO1 { + regulator-name = "LDO1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + ldo2: LDO2 { + regulator-name = "LDO2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + regulator-always-on; + }; + ldo3: LDO3 { + regulator-name = "LDO3"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + ldo4: LDO4 { + regulator-name = "LDO4"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + ldo5: LDO5 { + regulator-name = "LDO5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + }; From 6c814b676e8bab850b64ab76a035571773c65727 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 6 Jul 2020 16:09:44 +0800 Subject: [PATCH 49/67] regulator: fan53880: Add missing .owner field in regulator_desc Add missing .owner field in regulator_desc, which is used for refcounting. Signed-off-by: Axel Lin Link: https://lore.kernel.org/r/20200706080944.663750-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/fan53880.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c index 285acc705a55..575d289b8e04 100644 --- a/drivers/regulator/fan53880.c +++ b/drivers/regulator/fan53880.c @@ -45,6 +45,7 @@ static const struct regulator_ops fan53880_ops = { .of_match = of_match_ptr("LDO"#_num), \ .regulators_node = of_match_ptr("regulators"), \ .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ .linear_ranges = (struct linear_range[]) { \ REGULATOR_LINEAR_RANGE(_default, 0x0, 0x0, 0), \ REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \ @@ -69,6 +70,7 @@ static const struct regulator_desc fan53880_regulators[] = { .of_match = of_match_ptr("BUCK"), .regulators_node = of_match_ptr("regulators"), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500), @@ -87,6 +89,7 @@ static const struct regulator_desc fan53880_regulators[] = { .of_match = of_match_ptr("BOOST"), .regulators_node = of_match_ptr("regulators"), .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000), From 318b8a09f295cbf86fd504bcff3769b1fc4a936b Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Tue, 7 Jul 2020 12:57:31 +0200 Subject: [PATCH 50/67] regulator: fan53880: Add support for COMPILE_TEST This patch adds support for COMPILE_TEST while fixing a warning when no support for device tree is there. Reported-by: kernel test robot Signed-off-by: Christoph Fritz Link: https://lore.kernel.org/r/1c437154873ace65ff738a0ebca511308f1cecc1.camel@googlemail.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 2 +- drivers/regulator/fan53880.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 8f9bef574af2..64dc71c1e3d7 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -338,7 +338,7 @@ config REGULATOR_FAN53555 config REGULATOR_FAN53880 tristate "Fairchild FAN53880 Regulator" - depends on I2C + depends on I2C && (OF || COMPILE_TEST) select REGMAP_I2C help This driver supports Fairchild (ON Semiconductor) FAN53880 diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c index 575d289b8e04..e83eb4fb1876 100644 --- a/drivers/regulator/fan53880.c +++ b/drivers/regulator/fan53880.c @@ -155,11 +155,13 @@ static int fan53880_i2c_probe(struct i2c_client *i2c, return 0; } +#ifdef CONFIG_OF static const struct of_device_id fan53880_dt_ids[] = { { .compatible = "onnn,fan53880", }, {} }; MODULE_DEVICE_TABLE(of, fan53880_dt_ids); +#endif static const struct i2c_device_id fan53880_i2c_id[] = { { "fan53880", }, From 9565cccd64876dd1f8732fad3a04f8daa41fcef9 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 8 Jul 2020 13:48:30 +0100 Subject: [PATCH 51/67] regulator: devres: Fix issues with kerneldoc headers Provide descriptions for some missing function args and rename others to match the names used. Fixes the following W=1 warning(s): drivers/regulator/devres.c:187: warning: Function parameter or member 'dev' not described in 'devm_regulator_register' drivers/regulator/devres.c:226: warning: Function parameter or member 'dev' not described in 'devm_regulator_unregister' drivers/regulator/devres.c:226: warning: Function parameter or member 'rdev' not described in 'devm_regulator_unregister' drivers/regulator/devres.c:226: warning: Excess function parameter 'regulator' description in 'devm_regulator_unregister' Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200708124832.3441649-2-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/devres.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 3ea1c170f840..3f73ce859000 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -173,6 +173,7 @@ static void devm_rdev_release(struct device *dev, void *res) /** * devm_regulator_register - Resource managed regulator_register() + * @dev: device to supply * @regulator_desc: regulator to register * @config: runtime configuration for regulator * @@ -216,7 +217,8 @@ static int devm_rdev_match(struct device *dev, void *res, void *data) /** * devm_regulator_unregister - Resource managed regulator_unregister() - * @regulator: regulator to free + * @dev: device to supply + * @rdev: regulator to free * * Unregister a regulator registered with devm_regulator_register(). * Normally this function will not need to be called and the resource From 45e8446e7a153a011ae099bb8c5657bb853c0ad0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 8 Jul 2020 13:48:31 +0100 Subject: [PATCH 52/67] regulator: of_regulator: Add missing colon for rdev kerneldoc argument Kerneldoc validation gets confused if syntax isn't "@.*: ". Adding the missing colons squashes the following W=1 warnings: Signed-off-by: Lee Jones Cc: Rajendra Nayak Link: https://lore.kernel.org/r/20200708124832.3441649-3-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/of_regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 87637eb6bcbc..06c0b15fe4c0 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -532,7 +532,7 @@ static bool of_coupling_find_node(struct device_node *src, /** * of_check_coupling_data - Parse rdev's coupling properties and check data * consistency - * @rdev - pointer to regulator_dev whose data is checked + * @rdev: pointer to regulator_dev whose data is checked * * Function checks if all the following conditions are met: * - rdev's max_spread is greater than 0 From a7c15187b391d7fe9903903475a94e5cd5b796d6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 8 Jul 2020 13:48:32 +0100 Subject: [PATCH 53/67] regulator: devres: Standardise on function documentation headers Line up descriptions, start description with a lower-case character and omit old definitions such as quoting the old argument "consumer". Signed-off-by: Lee Jones Link: https://lore.kernel.org/r/20200708124832.3441649-4-lee.jones@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/devres.c | 52 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index 3f73ce859000..3091210889e3 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c @@ -41,8 +41,8 @@ static struct regulator *_devm_regulator_get(struct device *dev, const char *id, /** * devm_regulator_get - Resource managed regulator_get() - * @dev: device for regulator "consumer" - * @id: Supply name or regulator ID. + * @dev: device to supply + * @id: supply name or regulator ID. * * Managed regulator_get(). Regulators returned from this function are * automatically regulator_put() on driver detach. See regulator_get() for more @@ -56,8 +56,8 @@ EXPORT_SYMBOL_GPL(devm_regulator_get); /** * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive() - * @dev: device for regulator "consumer" - * @id: Supply name or regulator ID. + * @dev: device to supply + * @id: supply name or regulator ID. * * Managed regulator_get_exclusive(). Regulators returned from this function * are automatically regulator_put() on driver detach. See regulator_get() for @@ -72,8 +72,8 @@ EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive); /** * devm_regulator_get_optional - Resource managed regulator_get_optional() - * @dev: device for regulator "consumer" - * @id: Supply name or regulator ID. + * @dev: device to supply + * @id: supply name or regulator ID. * * Managed regulator_get_optional(). Regulators returned from this * function are automatically regulator_put() on driver detach. See @@ -130,9 +130,9 @@ static void devm_regulator_bulk_release(struct device *dev, void *res) /** * devm_regulator_bulk_get - managed get multiple regulator consumers * - * @dev: Device to supply - * @num_consumers: Number of consumers to register - * @consumers: Configuration of consumers; clients are stored here. + * @dev: device to supply + * @num_consumers: number of consumers to register + * @consumers: configuration of consumers; clients are stored here. * * @return 0 on success, an errno on failure. * @@ -173,9 +173,9 @@ static void devm_rdev_release(struct device *dev, void *res) /** * devm_regulator_register - Resource managed regulator_register() - * @dev: device to supply + * @dev: device to supply * @regulator_desc: regulator to register - * @config: runtime configuration for regulator + * @config: runtime configuration for regulator * * Called by regulator drivers to register a regulator. Returns a * valid pointer to struct regulator_dev on success or an ERR_PTR() on @@ -259,10 +259,10 @@ static void devm_regulator_destroy_supply_alias(struct device *dev, void *res) * devm_regulator_register_supply_alias - Resource managed * regulator_register_supply_alias() * - * @dev: device that will be given as the regulator "consumer" - * @id: Supply name or regulator ID + * @dev: device to supply + * @id: supply name or regulator ID * @alias_dev: device that should be used to lookup the supply - * @alias_id: Supply name or regulator ID that should be used to lookup the + * @alias_id: supply name or regulator ID that should be used to lookup the * supply * * The supply alias will automatically be unregistered when the source @@ -300,8 +300,8 @@ EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias); * devm_regulator_unregister_supply_alias - Resource managed * regulator_unregister_supply_alias() * - * @dev: device that will be given as the regulator "consumer" - * @id: Supply name or regulator ID + * @dev: device to supply + * @id: supply name or regulator ID * * Unregister an alias registered with * devm_regulator_register_supply_alias(). Normally this function @@ -327,12 +327,12 @@ EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias); * devm_regulator_bulk_register_supply_alias - Managed register * multiple aliases * - * @dev: device that will be given as the regulator "consumer" - * @id: List of supply names or regulator IDs + * @dev: device to supply + * @id: list of supply names or regulator IDs * @alias_dev: device that should be used to lookup the supply - * @alias_id: List of supply names or regulator IDs that should be used to - * lookup the supply - * @num_id: Number of aliases to register + * @alias_id: list of supply names or regulator IDs that should be used to + * lookup the supply + * @num_id: number of aliases to register * * @return 0 on success, an errno on failure. * @@ -377,9 +377,9 @@ EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias); * devm_regulator_bulk_unregister_supply_alias - Managed unregister * multiple aliases * - * @dev: device that will be given as the regulator "consumer" - * @id: List of supply names or regulator IDs - * @num_id: Number of aliases to unregister + * @dev: device to supply + * @id: list of supply names or regulator IDs + * @num_id: number of aliases to unregister * * Unregister aliases registered with * devm_regulator_bulk_register_supply_alias(). Normally this function @@ -423,7 +423,7 @@ static void devm_regulator_destroy_notifier(struct device *dev, void *res) * regulator_register_notifier * * @regulator: regulator source - * @nb: notifier block + * @nb: notifier block * * The notifier will be registers under the consumer device and be * automatically be unregistered when the source device is unbound. @@ -460,7 +460,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_register_notifier); * regulator_unregister_notifier() * * @regulator: regulator source - * @nb: notifier block + * @nb: notifier block * * Unregister a notifier registered with devm_regulator_register_notifier(). * Normally this function will not need to be called and the resource From 308e65ad060dca2f0187731a7916c71521ce6c25 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sat, 11 Jul 2020 13:44:09 +0200 Subject: [PATCH 54/67] regulator: cros-ec: Constify cros_ec_regulator_voltage_ops It is never modified, so make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Acked-by: Pi-Hsun Shih Link: https://lore.kernel.org/r/20200711114409.9911-1-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/cros-ec-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/cros-ec-regulator.c b/drivers/regulator/cros-ec-regulator.c index 35f97246bc48..eeed5aac3f32 100644 --- a/drivers/regulator/cros-ec-regulator.c +++ b/drivers/regulator/cros-ec-regulator.c @@ -142,7 +142,7 @@ static int cros_ec_regulator_set_voltage(struct regulator_dev *dev, int min_uV, sizeof(cmd), NULL, 0); } -static struct regulator_ops cros_ec_regulator_voltage_ops = { +static const struct regulator_ops cros_ec_regulator_voltage_ops = { .enable = cros_ec_regulator_enable, .disable = cros_ec_regulator_disable, .is_enabled = cros_ec_regulator_is_enabled, From f7d7ad42a9dc2d63cab6a79fe31e6732a30dacf5 Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Mon, 22 Jun 2020 18:11:07 +0530 Subject: [PATCH 55/67] regulator: Allow regulators to verify enabled during enable() Some regulators might need to verify that they have indeed been enabled after the enable() call is made and enable_time delay has passed. This is implemented by repeatedly checking is_enabled() upto poll_enabled_time, waiting for the already calculated enable delay in each iteration. Signed-off-by: Sumit Semwal Link: https://lore.kernel.org/r/20200622124110.20971-2-sumit.semwal@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/core.c | 63 +++++++++++++++++++++++++++++++- include/linux/regulator/driver.h | 5 +++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 03154f5b939f..538a2779986a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2347,6 +2347,37 @@ static void _regulator_enable_delay(unsigned int delay) udelay(us); } +/** + * _regulator_check_status_enabled + * + * A helper function to check if the regulator status can be interpreted + * as 'regulator is enabled'. + * @rdev: the regulator device to check + * + * Return: + * * 1 - if status shows regulator is in enabled state + * * 0 - if not enabled state + * * Error Value - as received from ops->get_status() + */ +static inline int _regulator_check_status_enabled(struct regulator_dev *rdev) +{ + int ret = rdev->desc->ops->get_status(rdev); + + if (ret < 0) { + rdev_info(rdev, "get_status returned error: %d\n", ret); + return ret; + } + + switch (ret) { + case REGULATOR_STATUS_OFF: + case REGULATOR_STATUS_ERROR: + case REGULATOR_STATUS_UNDEFINED: + return 0; + default: + return 1; + } +} + static int _regulator_do_enable(struct regulator_dev *rdev) { int ret, delay; @@ -2407,7 +2438,37 @@ static int _regulator_do_enable(struct regulator_dev *rdev) * together. */ trace_regulator_enable_delay(rdev_get_name(rdev)); - _regulator_enable_delay(delay); + /* If poll_enabled_time is set, poll upto the delay calculated + * above, delaying poll_enabled_time uS to check if the regulator + * actually got enabled. + * If the regulator isn't enabled after enable_delay has + * expired, return -ETIMEDOUT. + */ + if (rdev->desc->poll_enabled_time) { + unsigned int time_remaining = delay; + + while (time_remaining > 0) { + _regulator_enable_delay(rdev->desc->poll_enabled_time); + + if (rdev->desc->ops->get_status) { + ret = _regulator_check_status_enabled(rdev); + if (ret < 0) + return ret; + else if (ret) + break; + } else if (rdev->desc->ops->is_enabled(rdev)) + break; + + time_remaining -= rdev->desc->poll_enabled_time; + } + + if (time_remaining <= 0) { + rdev_err(rdev, "Enabled check timed out\n"); + return -ETIMEDOUT; + } + } else { + _regulator_enable_delay(delay); + } trace_regulator_enable_complete(rdev_get_name(rdev)); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 7eb9fea8e482..436df3ba0b2a 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -305,6 +305,9 @@ enum regulator_type { * @enable_time: Time taken for initial enable of regulator (in uS). * @off_on_delay: guard time (in uS), before re-enabling a regulator * + * @poll_enabled_time: The polling interval (in uS) to use while checking that + * the regulator was actually enabled. Max upto enable_time. + * * @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode */ struct regulator_desc { @@ -372,6 +375,8 @@ struct regulator_desc { unsigned int off_on_delay; + unsigned int poll_enabled_time; + unsigned int (*of_map_mode)(unsigned int mode); }; From 498ab2fdf8554690c9567c1eee436b858637e3ff Mon Sep 17 00:00:00 2001 From: Nisha Kumari Date: Mon, 22 Jun 2020 18:11:10 +0530 Subject: [PATCH 56/67] regulator: qcom: Add labibb driver Qualcomm platforms have LAB(LCD AMOLED Boost)/IBB(Inverting Buck Boost) regulators, labibb for short, which are used as power supply for LCD Mode displays. This patch adds labibb regulator driver for pmi8998 PMIC, found on SDM845 platforms. [sumits: reworked the driver design as per upstream review] Signed-off-by: Nisha Kumari Signed-off-by: Sumit Semwal Link: https://lore.kernel.org/r/20200622124110.20971-5-sumit.semwal@linaro.org Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 ++ drivers/regulator/Makefile | 1 + drivers/regulator/qcom-labibb-regulator.c | 175 ++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 drivers/regulator/qcom-labibb-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 64dc71c1e3d7..6e1cfaf01d28 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1223,5 +1223,15 @@ config REGULATOR_WM8994 This driver provides support for the voltage regulators on the WM8994 CODEC. +config REGULATOR_QCOM_LABIBB + tristate "QCOM LAB/IBB regulator support" + depends on SPMI || COMPILE_TEST + help + This driver supports Qualcomm's LAB/IBB regulators present on the + Qualcomm's PMIC chip pmi8998. QCOM LAB and IBB are SPMI + based PMIC implementations. LAB can be used as positive + boost regulator and IBB can be used as a negative boost regulator + for LCD display panel. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 6adfe769a47c..aa8a50424f4a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o +obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-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-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c new file mode 100644 index 000000000000..8c7dd1928380 --- /dev/null +++ b/drivers/regulator/qcom-labibb-regulator.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2020, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_PERPH_TYPE 0x04 + +#define QCOM_LAB_TYPE 0x24 +#define QCOM_IBB_TYPE 0x20 + +#define PMI8998_LAB_REG_BASE 0xde00 +#define PMI8998_IBB_REG_BASE 0xdc00 + +#define REG_LABIBB_STATUS1 0x08 +#define REG_LABIBB_ENABLE_CTL 0x46 +#define LABIBB_STATUS1_VREG_OK_BIT BIT(7) +#define LABIBB_CONTROL_ENABLE BIT(7) + +#define LAB_ENABLE_CTL_MASK BIT(7) +#define IBB_ENABLE_CTL_MASK (BIT(7) | BIT(6)) + +#define LABIBB_OFF_ON_DELAY 1000 +#define LAB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 2) +#define IBB_ENABLE_TIME (LABIBB_OFF_ON_DELAY * 10) +#define LABIBB_POLL_ENABLED_TIME 1000 + +struct labibb_regulator { + struct regulator_desc desc; + struct device *dev; + struct regmap *regmap; + struct regulator_dev *rdev; + u16 base; + u8 type; +}; + +struct labibb_regulator_data { + const char *name; + u8 type; + u16 base; + struct regulator_desc *desc; +}; + +static struct regulator_ops qcom_labibb_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static struct regulator_desc pmi8998_lab_desc = { + .enable_mask = LAB_ENABLE_CTL_MASK, + .enable_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL), + .enable_val = LABIBB_CONTROL_ENABLE, + .enable_time = LAB_ENABLE_TIME, + .poll_enabled_time = LABIBB_POLL_ENABLED_TIME, + .off_on_delay = LABIBB_OFF_ON_DELAY, + .owner = THIS_MODULE, + .type = REGULATOR_VOLTAGE, + .ops = &qcom_labibb_ops, +}; + +static struct regulator_desc pmi8998_ibb_desc = { + .enable_mask = IBB_ENABLE_CTL_MASK, + .enable_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL), + .enable_val = LABIBB_CONTROL_ENABLE, + .enable_time = IBB_ENABLE_TIME, + .poll_enabled_time = LABIBB_POLL_ENABLED_TIME, + .off_on_delay = LABIBB_OFF_ON_DELAY, + .owner = THIS_MODULE, + .type = REGULATOR_VOLTAGE, + .ops = &qcom_labibb_ops, +}; + +static const struct labibb_regulator_data pmi8998_labibb_data[] = { + {"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc}, + {"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc}, + { }, +}; + +static const struct of_device_id qcom_labibb_match[] = { + { .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data}, + { }, +}; +MODULE_DEVICE_TABLE(of, qcom_labibb_match); + +static int qcom_labibb_regulator_probe(struct platform_device *pdev) +{ + struct labibb_regulator *vreg; + struct device *dev = &pdev->dev; + struct regulator_config cfg = {}; + + const struct of_device_id *match; + const struct labibb_regulator_data *reg_data; + struct regmap *reg_regmap; + unsigned int type; + int ret; + + reg_regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!reg_regmap) { + dev_err(&pdev->dev, "Couldn't get parent's regmap\n"); + return -ENODEV; + } + + match = of_match_device(qcom_labibb_match, &pdev->dev); + if (!match) + return -ENODEV; + + for (reg_data = match->data; reg_data->name; reg_data++) { + + /* Validate if the type of regulator is indeed + * what's mentioned in DT. + */ + ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE, + &type); + if (ret < 0) { + dev_err(dev, + "Peripheral type read failed ret=%d\n", + ret); + return -EINVAL; + } + + if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) || + WARN_ON(type != reg_data->type)) + return -EINVAL; + + vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), + GFP_KERNEL); + if (!vreg) + return -ENOMEM; + + vreg->regmap = reg_regmap; + vreg->dev = dev; + vreg->base = reg_data->base; + vreg->type = reg_data->type; + + memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc)); + vreg->desc.of_match = reg_data->name; + vreg->desc.name = reg_data->name; + + cfg.dev = vreg->dev; + cfg.driver_data = vreg; + cfg.regmap = vreg->regmap; + + vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc, + &cfg); + + if (IS_ERR(vreg->rdev)) { + dev_err(dev, "qcom_labibb: error registering %s : %d\n", + reg_data->name, ret); + return PTR_ERR(vreg->rdev); + } + } + + return 0; +} + +static struct platform_driver qcom_labibb_regulator_driver = { + .driver = { + .name = "qcom-lab-ibb-regulator", + .of_match_table = qcom_labibb_match, + }, + .probe = qcom_labibb_regulator_probe, +}; +module_platform_driver(qcom_labibb_regulator_driver); + +MODULE_DESCRIPTION("Qualcomm labibb driver"); +MODULE_AUTHOR("Nisha Kumari "); +MODULE_AUTHOR("Sumit Semwal "); +MODULE_LICENSE("GPL v2"); From 88c14de2b6786ef503fd1bc2c952159e65fe45cc Mon Sep 17 00:00:00 2001 From: Nisha Kumari Date: Mon, 22 Jun 2020 18:11:08 +0530 Subject: [PATCH 57/67] regulator: Add labibb regulator binding Adding the devicetree binding for labibb regulator. [sumits: cleanup as per review comments and update to yaml] Signed-off-by: Nisha Kumari Signed-off-by: Sumit Semwal Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20200622124110.20971-3-sumit.semwal@linaro.org Signed-off-by: Mark Brown --- .../regulator/qcom-labibb-regulator.yaml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml new file mode 100644 index 000000000000..085cbd1ad8d0 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/qcom-labibb-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm's LAB(LCD AMOLED Boost)/IBB(Inverting Buck Boost) Regulator + +maintainers: + - Sumit Semwal + +description: + LAB can be used as a positive boost power supply and IBB can be used as a + negative boost power supply for display panels. Currently implemented for + pmi8998. + +properties: + compatible: + const: qcom,pmi8998-lab-ibb + + lab: + type: object + + properties: + + interrupts: + maxItems: 1 + description: + Short-circuit interrupt for lab. + + required: + - interrupts + + ibb: + type: object + + properties: + + interrupts: + maxItems: 1 + description: + Short-circuit interrupt for lab. + + required: + - interrupts + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + #include + + labibb { + compatible = "qcom,pmi8998-lab-ibb"; + + lab { + interrupts = <0x3 0x0 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "sc-err"; + }; + + ibb { + interrupts = <0x3 0x2 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "sc-err"; + }; + }; + +... From a98bcaa92d3d7a7753e23b3363d90ffdb82e8edb Mon Sep 17 00:00:00 2001 From: Colton Lewis Date: Wed, 15 Jul 2020 19:15:00 +0000 Subject: [PATCH 58/67] regulator: Correct kernel-doc inconsistency Silence documentation build warning by correcting kernel-doc comments. ./include/linux/regulator/machine.h:196: warning: Function parameter or member 'max_uV_step' not described in 'regulation_constraints' ./include/linux/regulator/driver.h:206: warning: Function parameter or member 'resume' not described in 'regulator_ops' Signed-off-by: Colton Lewis Link: https://lore.kernel.org/r/20200715191438.29312-1-colton.w.lewis@protonmail.com Signed-off-by: Mark Brown --- include/linux/regulator/driver.h | 2 +- include/linux/regulator/machine.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 436df3ba0b2a..8539f34ae42b 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -117,7 +117,7 @@ enum regulator_status { * suspended. * @set_suspend_mode: Set the operating mode for the regulator when the * system is suspended. - * + * @resume: Resume operation of suspended regulator. * @set_pull_down: Configure the regulator to pull down when the regulator * is disabled. * diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index a84cc8879c3e..8a56f033b6cd 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -101,6 +101,7 @@ struct regulator_state { * @system_load: Load that isn't captured by any consumer requests. * * @max_spread: Max possible spread between coupled regulators + * @max_uV_step: Max possible step change in voltage * @valid_modes_mask: Mask of modes which may be configured by consumers. * @valid_ops_mask: Operations which may be performed by consumers. * From e1794aa43f17bf2512c10370c6be6ea24a6f29d0 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Wed, 15 Jul 2020 21:20:51 -0700 Subject: [PATCH 59/67] regulator: core: Add destroy_regulator() Part of the regulator_get() code is already factored out into create_regulator(). This patch factors out some of the regulator_put() code into destroy_regulator() so that create_regulator() has a corresponding unwind function. Subsequent patches will use this function. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20200716042053.1927676-3-saravanak@google.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 538a2779986a..196e344a84d3 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -105,6 +105,7 @@ static int regulator_balance_voltage(struct regulator_dev *rdev, static struct regulator *create_regulator(struct regulator_dev *rdev, struct device *dev, const char *supply_name); +static void destroy_regulator(struct regulator *regulator); static void _regulator_put(struct regulator *regulator); const char *rdev_get_name(struct regulator_dev *rdev) @@ -2034,20 +2035,9 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_optional); -/* regulator_list_mutex lock held by regulator_put() */ -static void _regulator_put(struct regulator *regulator) +static void destroy_regulator(struct regulator *regulator) { - struct regulator_dev *rdev; - - if (IS_ERR_OR_NULL(regulator)) - return; - - lockdep_assert_held_once(®ulator_list_mutex); - - /* Docs say you must disable before calling regulator_put() */ - WARN_ON(regulator->enable_count); - - rdev = regulator->rdev; + struct regulator_dev *rdev = regulator->rdev; debugfs_remove_recursive(regulator->debugfs); @@ -2068,6 +2058,24 @@ static void _regulator_put(struct regulator *regulator) kfree_const(regulator->supply_name); kfree(regulator); +} + +/* regulator_list_mutex lock held by regulator_put() */ +static void _regulator_put(struct regulator *regulator) +{ + struct regulator_dev *rdev; + + if (IS_ERR_OR_NULL(regulator)) + return; + + lockdep_assert_held_once(®ulator_list_mutex); + + /* Docs say you must disable before calling regulator_put() */ + WARN_ON(regulator->enable_count); + + rdev = regulator->rdev; + + destroy_regulator(regulator); module_put(rdev->owner); put_device(&rdev->dev); From 3acff11cef1dece31cd29956f19181895996a7c5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 20 Jul 2020 21:28:09 +0800 Subject: [PATCH 60/67] regulator: gpio: Honor regulator-boot-on property When requesting the enable GPIO, the driver should do so with the correct output level matching some expected state. This is especially important if the regulator is a critical one, such as a supply for the boot CPU. This is currently done by checking for the enable-at-boot property, but this is not documented in the device tree binding, nor does it match the common regulator properties. Honor the common regulator-boot-on property by checking the boot_on constraint setting within the DT probe path. This is the same as what is done in the fixed regulator driver. Also add a comment stating that the enable-at-boot property should not be used. Fixes: 006694d099e8 ("regulator: gpio-regulator: Allow use of GPIO controlled regulators though DT") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20200720132809.26908-1-wens@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 181451f922f1..5927d4f3eabd 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -148,6 +148,13 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, config->supply_name = config->init_data->constraints.name; + if (config->init_data->constraints.boot_on) + config->enabled_at_boot = true; + + /* + * Do not use: undocumented device tree property. + * This is kept around solely for device tree ABI stability. + */ if (of_property_read_bool(np, "enable-at-boot")) config->enabled_at_boot = true; From 175a1d84154d4077da437b873319bd094b266ab8 Mon Sep 17 00:00:00 2001 From: Kathiravan T Date: Mon, 20 Jul 2020 11:42:23 +0530 Subject: [PATCH 61/67] regulator: convert QCOM SMD-RPM regulator document to YAML schema Convert qcom,smd-rpm-regulator.txt document to YAML schema Signed-off-by: Kathiravan T Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1595225543-12127-5-git-send-email-kathirav@codeaurora.org Signed-off-by: Mark Brown --- .../regulator/qcom,smd-rpm-regulator.txt | 321 ------------------ .../regulator/qcom,smd-rpm-regulator.yaml | 106 ++++++ 2 files changed, 106 insertions(+), 321 deletions(-) delete mode 100644 Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt create mode 100644 Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt deleted file mode 100644 index 728c0010a60a..000000000000 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ /dev/null @@ -1,321 +0,0 @@ -QCOM SMD RPM REGULATOR - -The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM. -Because SMD is used as the communication transport mechanism, the RPM resides as -a subnode of the SMD. As such, the SMD-RPM regulator requires that the SMD and -RPM nodes be present. - -Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for -information pertaining to the SMD node. - -Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.txt for -information regarding the RPM node. - -== Regulator - -Regulator nodes are identified by their compatible: - -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,rpm-mp5496-regulators" - "qcom,rpm-pm8841-regulators" - "qcom,rpm-pm8916-regulators" - "qcom,rpm-pm8941-regulators" - "qcom,rpm-pm8950-regulators" - "qcom,rpm-pm8994-regulators" - "qcom,rpm-pm8998-regulators" - "qcom,rpm-pma8084-regulators" - "qcom,rpm-pmi8994-regulators" - "qcom,rpm-pmi8998-regulators" - "qcom,rpm-pms405-regulators" - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_s6-supply: -- vdd_s7-supply: -- vdd_s8-supply: - Usage: optional (pm8841 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_l1_l2_l3-supply: -- vdd_l4_l5_l6-supply: -- vdd_l7-supply: -- vdd_l8_l9_l10_l11_l12_l13_l14_l15_l16_l17_l18-supply: - Usage: optional (pm8916 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_s6-supply: -- vdd_l1_l19-supply: -- vdd_l2_l23-supply: -- vdd_l3-supply: -- vdd_l4_l5_l6_l7_l16-supply: -- vdd_l8_l11_l12_l17_l22-supply: -- vdd_l9_l10_l13_l14_l15_l18-supply: -- vdd_l20-supply: -- vdd_l21-supply: - Usage: optional (pm8950 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_l1_l3-supply: -- vdd_l2_lvs1_2_3-supply: -- vdd_l4_l11-supply: -- vdd_l5_l7-supply: -- vdd_l6_l12_l14_l15-supply: -- vdd_l8_l16_l18_l19-supply: -- vdd_l9_l10_l17_l22-supply: -- vdd_l13_l20_l23_l24-supply: -- vdd_l21-supply: -- vin_5vs-supply: - Usage: optional (pm8941 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_s6-supply: -- vdd_s7-supply: -- vdd_s8-supply: -- vdd_s9-supply: -- vdd_s10-supply: -- vdd_s11-supply: -- vdd_s12-supply: -- vdd_l1-supply: -- vdd_l2_l26_l28-supply: -- vdd_l3_l11-supply: -- vdd_l4_l27_l31-supply: -- vdd_l5_l7-supply: -- vdd_l6_l12_l32-supply: -- vdd_l5_l7-supply: -- vdd_l8_l16_l30-supply: -- vdd_l9_l10_l18_l22-supply: -- vdd_l9_l10_l18_l22-supply: -- vdd_l3_l11-supply: -- vdd_l6_l12_l32-supply: -- vdd_l13_l19_l23_l24-supply: -- vdd_l14_l15-supply: -- vdd_l14_l15-supply: -- vdd_l8_l16_l30-supply: -- vdd_l17_l29-supply: -- vdd_l9_l10_l18_l22-supply: -- vdd_l13_l19_l23_l24-supply: -- vdd_l20_l21-supply: -- vdd_l20_l21-supply: -- vdd_l9_l10_l18_l22-supply: -- vdd_l13_l19_l23_l24-supply: -- vdd_l13_l19_l23_l24-supply: -- vdd_l25-supply: -- vdd_l2_l26_l28-supply: -- vdd_l4_l27_l31-supply: -- vdd_l2_l26_l28-supply: -- vdd_l17_l29-supply: -- vdd_l8_l16_l30-supply: -- vdd_l4_l27_l31-supply: -- vdd_l6_l12_l32-supply: -- vdd_lvs1_2-supply: - Usage: optional (pm8994 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_bst_byp-supply: - Usage: optional (pmi8994 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_s6-supply: -- vdd_s7-supply: -- vdd_s8-supply: -- vdd_s9-supply: -- vdd_s10-supply: -- vdd_s11-supply: -- vdd_s12-supply: -- vdd_s13-supply: -- vdd_l1_l27-supply: -- vdd_l20_l24-supply: -- vdd_l26-supply: -- vdd_l2_l8_l17-supply: -- vdd_l3_l11-supply: -- vdd_l4_l5-supply: -- vdd_l6-supply: -- vdd_l7_l12_l14_l15-supply: -- vdd_l9-supply: -- vdd_l10_l23_l25-supply: -- vdd_l13_l19_l21-supply: -- vdd_l16_l28-supply: -- vdd_l18_l22-supply: -- vdd_lvs1_lvs2-supply: - Usage: optional (pmi8998 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_s6-supply: -- vdd_s7-supply: -- vdd_s8-supply: -- vdd_s9-supply: -- vdd_s10-supply: -- vdd_s11-supply: -- vdd_s12-supply: -- vdd_l1_l11-supply: -- vdd_l2_l3_l4_l27-supply: -- vdd_l5_l7-supply: -- vdd_l6_l12_l14_l15_l26-supply: -- vdd_l8-supply: -- vdd_l9_l10_l13_l20_l23_l24-supply: -- vdd_l16_l25-supply: -- vdd_l17-supply: -- vdd_l18-supply: -- vdd_l19-supply: -- vdd_l21-supply: -- vdd_l22-supply: - Usage: optional (pma8084 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_bob-supply: - Usage: optional (pmi8998 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -- vdd_s1-supply: -- vdd_s2-supply: -- vdd_s3-supply: -- vdd_s4-supply: -- vdd_s5-supply: -- vdd_l1_l2-supply: -- vdd_l3_l8-supply: -- vdd_l4-supply: -- vdd_l5_l6-supply: -- vdd_l7-supply: -- vdd_l3_l8-supply: -- vdd_l9-supply: -- vdd_l10_l11_l12_l13-supply: - Usage: optional (pms405 only) - Value type: - Definition: reference to regulator supplying the input pin, as - described in the data sheet - -The regulator node houses sub-nodes for each regulator within the device. Each -sub-node is identified using the node's name, with valid values listed for each -of the pmics below. - -pm8841: - s1, s2, s3, s4, s5, s6, s7, s8 - -pm8916: - s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, - l14, l15, l16, l17, l18 - -pm8941: - s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, - l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, - lvs3, 5vs1, 5vs2 - -pm8994: - s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, - l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, - l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2 - -pm8998: - s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, l1, l2, l3, l4, - l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, - l20, l21, l22, l23, l24, l25, l26, l27, l28, lvs1, lvs2 - -pma8084: - s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, - l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, - l21, l22, l23, l24, l25, l26, l27, lvs1, lvs2, lvs3, lvs4, 5vs1 - -pmi8994: - s1, s2, s3, boost-bypass - -pmi8998: - bob - -pms405: - s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, - l13 - -The content of each sub-node is defined by the standard binding for regulators - -see regulator.txt. - -= EXAMPLE - - smd { - compatible = "qcom,smd"; - - rpm { - interrupts = <0 168 1>; - qcom,ipc = <&apcs 8 0>; - qcom,smd-edge = <15>; - - rpm_requests { - compatible = "qcom,rpm-msm8974"; - qcom,smd-channels = "rpm_requests"; - - pm8941-regulators { - compatible = "qcom,rpm-pm8941-regulators"; - vdd_l13_l20_l23_l24-supply = <&pm8941_boost>; - - pm8941_s3: s3 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - pm8941_boost: s4 { - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - - pm8941_l20: l20 { - regulator-min-microvolt = <2950000>; - regulator-max-microvolt = <2950000>; - }; - }; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml new file mode 100644 index 000000000000..8d212bdbee02 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml @@ -0,0 +1,106 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/qcom,smd-rpm-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: QCOM SMD RPM REGULATOR + +description: + The Qualcomm RPM over SMD regulator is modelled as a subdevice of the RPM. + Because SMD is used as the communication transport mechanism, the RPM + resides as a subnode of the SMD. As such, the SMD-RPM regulator requires + that the SMD and RPM nodes be present. + + Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for + information pertaining to the SMD node. + + Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml + for information regarding the RPM node. + + The regulator node houses sub-nodes for each regulator within the device. + Each sub-node is identified using the node's name, with valid values listed + for each of the pmics below. + + For pm8841, s1, s2, s3, s4, s5, s6, s7, s8 + + For pm8916, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, + l12, l13, l14, l15, l16, l17, l18 + + For pm8941, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, + l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, + lvs3, 5vs1, 5vs2 + + For pm8994, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, + l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, + l20, l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2 + + For pm8998, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, l1, l2, + l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, + l20, l21, l22, l23, l24, l25, l26, l27, l28, lvs1, lvs2 + + For pma8084, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, + l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, + l20, l21, l22, l23, l24, l25, l26, l27, lvs1, lvs2, lvs3, lvs4, 5vs1 + + For pmi8994, s1, s2, s3, boost-bypass + + For pmi8998, bob + + For pms405, s1, s2, s3, s4, s5, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, + l12, l13 + +maintainers: + - Kathiravan T + +properties: + compatible: + enum: + - qcom,rpm-mp5496-regulators + - qcom,rpm-pm8841-regulators + - qcom,rpm-pm8916-regulators + - qcom,rpm-pm8941-regulators + - qcom,rpm-pm8950-regulators + - qcom,rpm-pm8994-regulators + - qcom,rpm-pm8998-regulators + - qcom,rpm-pma8084-regulators + - qcom,rpm-pmi8994-regulators + - qcom,rpm-pmi8998-regulators + - qcom,rpm-pms405-regulators + +patternProperties: + ".*-supply$": + description: Input supply phandle(s) for this node + + "^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$": + description: List of regulators and its properties + allOf: + - $ref: regulator.yaml# + +additionalProperties: false + +required: + - compatible + +examples: + - | + pm8941-regulators { + compatible = "qcom,rpm-pm8941-regulators"; + vdd_l13_l20_l23_l24-supply = <&pm8941_boost>; + + pm8941_s3: s3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8941_boost: s4 { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + pm8941_l20: l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + }; + }; +... From 2ca76b3e4954ea6bbb365005edc8d5237b488cf1 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Sun, 19 Jul 2020 22:06:23 +0200 Subject: [PATCH 62/67] regulator: Replace HTTP links with HTTPS ones Rationale: Reduces attack surface on kernel devs opening the links for MITM as HTTPS traffic is much harder to manipulate. Deterministic algorithm: For each file: If not .svg: For each line: If doesn't contain `\bxmlns\b`: For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`: If neither `\bgnu\.org/license`, nor `\bmozilla\.org/MPL\b`: If both the HTTP and HTTPS versions return 200 OK and serve the same content: Replace HTTP with HTTPS. Signed-off-by: Alexander A. Klimov Acked-by: Rob Herring Link: https://lore.kernel.org/r/20200719200623.61524-1-grandmaster@al2klimov.de Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/lp872x.txt | 4 ++-- drivers/regulator/hi6421-regulator.c | 2 +- drivers/regulator/hi6421v530-regulator.c | 2 +- drivers/regulator/lp873x-regulator.c | 2 +- drivers/regulator/lp87565-regulator.c | 2 +- drivers/regulator/pbias-regulator.c | 2 +- drivers/regulator/tps65023-regulator.c | 2 +- drivers/regulator/tps6507x-regulator.c | 2 +- drivers/regulator/tps65086-regulator.c | 2 +- drivers/regulator/tps65217-regulator.c | 2 +- drivers/regulator/tps65218-regulator.c | 2 +- drivers/regulator/tps65912-regulator.c | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/lp872x.txt b/Documentation/devicetree/bindings/regulator/lp872x.txt index ca58a68ffdf1..ab895cd1cac1 100644 --- a/Documentation/devicetree/bindings/regulator/lp872x.txt +++ b/Documentation/devicetree/bindings/regulator/lp872x.txt @@ -37,8 +37,8 @@ Optional properties: (Documentation/devicetree/bindings/regulator/regulator.txt) Datasheet - - LP8720: http://www.ti.com/lit/ds/symlink/lp8720.pdf - - LP8725: http://www.ti.com/lit/ds/symlink/lp8725.pdf + - LP8720: https://www.ti.com/lit/ds/symlink/lp8720.pdf + - LP8725: https://www.ti.com/lit/ds/symlink/lp8725.pdf Example 1) LP8720 diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index 66219d8dfc1a..dc631c1a46b4 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -5,7 +5,7 @@ // Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. // http://www.hisilicon.com // Copyright (c) <2013-2014> Linaro Ltd. -// http://www.linaro.org +// https://www.linaro.org // // Author: Guodong Xu diff --git a/drivers/regulator/hi6421v530-regulator.c b/drivers/regulator/hi6421v530-regulator.c index 06ae65199afd..988115f9b594 100644 --- a/drivers/regulator/hi6421v530-regulator.c +++ b/drivers/regulator/hi6421v530-regulator.c @@ -5,7 +5,7 @@ // Copyright (c) <2017> HiSilicon Technologies Co., Ltd. // http://www.hisilicon.com // Copyright (c) <2017> Linaro Ltd. -// http://www.linaro.org +// https://www.linaro.org // // Author: Wang Xiaoyin // Guodong Xu diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c index fe049b67e7d5..c38387e0fbb2 100644 --- a/drivers/regulator/lp873x-regulator.c +++ b/drivers/regulator/lp873x-regulator.c @@ -1,7 +1,7 @@ /* * Regulator driver for LP873X PMIC * - * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 as diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index fbed6bc80c1a..eeab9d3c824b 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -2,7 +2,7 @@ /* * Regulator driver for LP87565 PMIC * - * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/ */ #include diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index bfc15dd3f730..4eccf12f39de 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -1,7 +1,7 @@ /* * pbias-regulator.c * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ * Author: Balaji T K * * This program is free software; you can redistribute it and/or diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 5ca6d2130593..795d459ff3cf 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -3,7 +3,7 @@ * * Supports TPS65023 Regulator * - * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/ + * Copyright (C) 2009 Texas Instrument Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index d2a8f69b2665..eafbc2bb4b57 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -3,7 +3,7 @@ * * Regulator driver for TPS65073 PMIC * - * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/ + * Copyright (C) 2009 Texas Instrument Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index 9910e949373c..23528475a962 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ * * Author: Andrew F. Davis * diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 3f5ea029e2e3..e88ed96f4744 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -3,7 +3,7 @@ * * Regulator driver for TPS65217 PMIC * - * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 9133d0af793a..fa263545a70e 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -3,7 +3,7 @@ * * Regulator driver for TPS65218 PMIC * - * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 as diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 15c79931ea89..63d6bbd4969b 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -1,7 +1,7 @@ /* * Regulator driver for TI TPS65912x PMICs * - * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ * Andrew F. Davis * * This program is free software; you can redistribute it and/or From 9177514ce34902b3adb2abd490b6ad05d1cfcb43 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 24 Jul 2020 03:50:13 +0300 Subject: [PATCH 63/67] regulator: fix memory leak on error path of regulator_register() The change corrects registration and deregistration on error path of a regulator, the problem was manifested by a reported memory leak on deferred probe: as3722-regulator as3722-regulator: regulator 13 register failed -517 # cat /sys/kernel/debug/kmemleak unreferenced object 0xecc43740 (size 64): comm "swapper/0", pid 1, jiffies 4294937640 (age 712.880s) hex dump (first 32 bytes): 72 65 67 75 6c 61 74 6f 72 2e 32 34 00 5a 5a 5a regulator.24.ZZZ 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ backtrace: [<0c4c3d1c>] __kmalloc_track_caller+0x15c/0x2c0 [<40c0ad48>] kvasprintf+0x64/0xd4 [<109abd29>] kvasprintf_const+0x70/0x84 [] kobject_set_name_vargs+0x34/0xa8 [<62282ea2>] dev_set_name+0x40/0x64 [] regulator_register+0x3a4/0x1344 [<16a9543f>] devm_regulator_register+0x4c/0x84 [<51a4c6a1>] as3722_regulator_probe+0x294/0x754 ... The memory leak problem was introduced as a side ef another fix in regulator_register() error path, I believe that the proper fix is to decouple device_register() function into its two compounds and initialize a struct device before assigning any values to its fields and then using it before actual registration of a device happens. This lets to call put_device() safely after initialization, and, since now a release callback is called, kfree(rdev->constraints) shall be removed to exclude a double free condition. Fixes: a3cde9534ebd ("regulator: core: fix regulator_register() error paths to properly release rdev") Signed-off-by: Vladimir Zapolskiy Cc: Wen Yang Link: https://lore.kernel.org/r/20200724005013.23278-1-vz@mleia.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 196e344a84d3..75ff7c563c5d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5092,7 +5092,6 @@ regulator_register(const struct regulator_desc *regulator_desc, struct regulator_dev *rdev; bool dangling_cfg_gpiod = false; bool dangling_of_gpiod = false; - bool reg_device_fail = false; struct device *dev; int ret, i; @@ -5221,10 +5220,12 @@ regulator_register(const struct regulator_desc *regulator_desc, } /* register with sysfs */ + device_initialize(&rdev->dev); rdev->dev.class = ®ulator_class; rdev->dev.parent = dev; dev_set_name(&rdev->dev, "regulator.%lu", (unsigned long) atomic_inc_return(®ulator_no)); + dev_set_drvdata(&rdev->dev, rdev); /* set regulator constraints */ if (init_data) @@ -5275,12 +5276,9 @@ regulator_register(const struct regulator_desc *regulator_desc, !rdev->desc->fixed_uV) rdev->is_switch = true; - dev_set_drvdata(&rdev->dev, rdev); - ret = device_register(&rdev->dev); - if (ret != 0) { - reg_device_fail = true; + ret = device_add(&rdev->dev); + if (ret != 0) goto unset_supplies; - } rdev_init_debugfs(rdev); @@ -5302,17 +5300,15 @@ unset_supplies: mutex_unlock(®ulator_list_mutex); wash: kfree(rdev->coupling_desc.coupled_rdevs); - kfree(rdev->constraints); mutex_lock(®ulator_list_mutex); regulator_ena_gpio_free(rdev); mutex_unlock(®ulator_list_mutex); + put_device(&rdev->dev); + rdev = NULL; clean: if (dangling_of_gpiod) gpiod_put(config->ena_gpiod); - if (reg_device_fail) - put_device(&rdev->dev); - else - kfree(rdev); + kfree(rdev); kfree(config); rinse: if (dangling_cfg_gpiod) From 3bda44ffd93bf91fb3326336acf7ff163b1ce97d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 25 Jul 2020 09:44:14 +0800 Subject: [PATCH 64/67] regulator: pca9450: Convert to use module_i2c_driver Use module_i2c_driver to simplify driver init boilerplate. Signed-off-by: Axel Lin Link: https://lore.kernel.org/r/20200725014414.1825183-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/pca9450-regulator.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index 02250459aa90..eb5822bf53e0 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -826,17 +826,7 @@ static struct i2c_driver pca9450_i2c_driver = { .probe = pca9450_i2c_probe, }; -static int __init pca9450_i2c_init(void) -{ - return i2c_add_driver(&pca9450_i2c_driver); -} -module_init(pca9450_i2c_init); - -static void __exit pca9450_i2c_exit(void) -{ - i2c_del_driver(&pca9450_i2c_driver); -} -module_exit(pca9450_i2c_exit); +module_i2c_driver(pca9450_i2c_driver); MODULE_AUTHOR("Robin Gong "); MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver"); From a233547660a3915973d41e2a9a0923d0cf317a62 Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Fri, 24 Jul 2020 16:03:55 +0800 Subject: [PATCH 65/67] platform/chrome: cros_ec: Fix host command for regulator control. Since the host command number 0x012B conflicts with other EC host command, add one to all regulator control related host command. Also fix a wrong alignment on struct and sync the comment with the one in ChromeOS EC codebase. Fixes: dff08caf35ec ("platform/chrome: cros_ec: Add command for regulator control.") Signed-off-by: Pi-Hsun Shih Acked-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20200724080358.619245-1-pihsun@chromium.org Signed-off-by: Mark Brown --- include/linux/platform_data/cros_ec_commands.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index a417b51b5764..91e77f53414d 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -5438,7 +5438,7 @@ struct ec_response_rollback_info { * * Returns the regulator name and supported voltage list in mV. */ -#define EC_CMD_REGULATOR_GET_INFO 0x012B +#define EC_CMD_REGULATOR_GET_INFO 0x012C /* Maximum length of regulator name */ #define EC_REGULATOR_NAME_MAX_LEN 16 @@ -5454,12 +5454,12 @@ struct ec_response_regulator_get_info { char name[EC_REGULATOR_NAME_MAX_LEN]; uint16_t num_voltages; uint16_t voltages_mv[EC_REGULATOR_VOLTAGE_MAX_COUNT]; -} __ec_align1; +} __ec_align2; /* * Configure the regulator as enabled / disabled. */ -#define EC_CMD_REGULATOR_ENABLE 0x012C +#define EC_CMD_REGULATOR_ENABLE 0x012D struct ec_params_regulator_enable { uint32_t index; @@ -5471,7 +5471,7 @@ struct ec_params_regulator_enable { * * Returns 1 if the regulator is enabled, 0 if not. */ -#define EC_CMD_REGULATOR_IS_ENABLED 0x012D +#define EC_CMD_REGULATOR_IS_ENABLED 0x012E struct ec_params_regulator_is_enabled { uint32_t index; @@ -5489,7 +5489,7 @@ struct ec_response_regulator_is_enabled { * Also note that this might be called before the regulator is enabled, and the * setting should be in effect after the regulator is enabled. */ -#define EC_CMD_REGULATOR_SET_VOLTAGE 0x012E +#define EC_CMD_REGULATOR_SET_VOLTAGE 0x012F struct ec_params_regulator_set_voltage { uint32_t index; @@ -5500,9 +5500,10 @@ struct ec_params_regulator_set_voltage { /* * Get the currently configured voltage for the voltage regulator. * - * Note that this might be called before the regulator is enabled. + * Note that this might be called before the regulator is enabled, and this + * should return the configured output voltage if the regulator is enabled. */ -#define EC_CMD_REGULATOR_GET_VOLTAGE 0x012F +#define EC_CMD_REGULATOR_GET_VOLTAGE 0x0130 struct ec_params_regulator_get_voltage { uint32_t index; From 176cf704425f3d22603d379ffa4a1033a24a779d Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Tue, 28 Jul 2020 17:19:09 +0800 Subject: [PATCH 66/67] regulator: cros-ec-regulator: Fix double free of desc->name. The desc->name field is allocated with devm_kstrdup, but is also kfreed on the error path, causing it to be double freed. Remove the kfree on the error path. Fixes: 8d9f8d57e023 ("regulator: Add driver for cros-ec-regulator") Signed-off-by: Pi-Hsun Shih Reviewed-by: Enric Balletbo i Serra Link: https://lore.kernel.org/r/20200728091909.2009771-1-pihsun@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/cros-ec-regulator.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/regulator/cros-ec-regulator.c b/drivers/regulator/cros-ec-regulator.c index eeed5aac3f32..3117bbd2826b 100644 --- a/drivers/regulator/cros-ec-regulator.c +++ b/drivers/regulator/cros-ec-regulator.c @@ -222,18 +222,13 @@ static int cros_ec_regulator_probe(struct platform_device *pdev) drvdata->dev = devm_regulator_register(dev, &drvdata->desc, &cfg); if (IS_ERR(drvdata->dev)) { - ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); - goto free_name; + return PTR_ERR(drvdata->dev); } platform_set_drvdata(pdev, drvdata); return 0; - -free_name: - kfree(desc->name); - return ret; } static const struct of_device_id regulator_cros_ec_of_match[] = { From bcb3b2a7639db2412875520cddc3abd179068793 Mon Sep 17 00:00:00 2001 From: Kathiravan T Date: Thu, 30 Jul 2020 14:19:23 +0530 Subject: [PATCH 67/67] regulator: add the sub node names for the MP5496 PMIC MP5496 PMIC is found on IPQ6018 SoC. SMPA2 regulator controls the APSS voltage scaling. Document the sub node name for the same. Signed-off-by: Kathiravan T Link: https://lore.kernel.org/r/1596098964-19878-3-git-send-email-kathirav@codeaurora.org Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml index 8d212bdbee02..d2022206081f 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml @@ -22,6 +22,8 @@ description: Each sub-node is identified using the node's name, with valid values listed for each of the pmics below. + For mp5496, s2 + For pm8841, s1, s2, s3, s4, s5, s6, s7, s8 For pm8916, s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,