diff options
-rw-r--r-- | Documentation/devicetree/bindings/regulator/anatop-regulator.txt | 1 | ||||
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | arch/arm/mach-s3c64xx/mach-crag6410-module.c | 8 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 25 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 4 | ||||
-rw-r--r-- | drivers/regulator/anatop-regulator.c | 19 | ||||
-rw-r--r-- | drivers/regulator/arizona-ldo1.c | 140 | ||||
-rw-r--r-- | drivers/regulator/arizona-micsupp.c | 119 | ||||
-rw-r--r-- | drivers/regulator/bd9571mwv-regulator.c | 178 | ||||
-rw-r--r-- | drivers/regulator/max1586.c | 4 | ||||
-rw-r--r-- | drivers/regulator/max77693-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/max8660.c | 4 | ||||
-rw-r--r-- | drivers/regulator/s2mpa01.c | 14 | ||||
-rw-r--r-- | drivers/regulator/s2mps11.c | 16 | ||||
-rw-r--r-- | drivers/regulator/s5m8767.c | 4 | ||||
-rw-r--r-- | include/linux/mfd/arizona/pdata.h | 7 | ||||
-rw-r--r-- | include/linux/regulator/arizona-ldo1.h | 24 | ||||
-rw-r--r-- | include/linux/regulator/arizona-micsupp.h | 21 |
18 files changed, 448 insertions, 144 deletions
diff --git a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt index 1d58c8cfdbc0..a3106c72fbea 100644 --- a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt @@ -2,6 +2,7 @@ Anatop Voltage regulators Required properties: - compatible: Must be "fsl,anatop-regulator" +- regulator-name: A string used as a descriptive name for regulator outputs - anatop-reg-offset: Anatop MFD register offset - anatop-vol-bit-shift: Bit shift for the register - anatop-vol-bit-width: Number of bits used in the register diff --git a/MAINTAINERS b/MAINTAINERS index 38d3e4ed7208..785343129ca0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13631,12 +13631,14 @@ F: drivers/mfd/cs47l24* F: drivers/power/supply/wm83*.c F: drivers/rtc/rtc-wm83*.c F: drivers/regulator/wm8*.c +F: drivers/regulator/arizona* F: drivers/video/backlight/wm83*_bl.c F: drivers/watchdog/wm83*_wdt.c F: include/linux/mfd/arizona/ F: include/linux/mfd/wm831x/ F: include/linux/mfd/wm8350/ F: include/linux/mfd/wm8400* +F: include/linux/regulator/arizona* F: include/linux/wm97xx.h F: include/sound/wm????.h F: sound/soc/codecs/arizona.? diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c index ccc3ab8d58e7..ea5f2169c850 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c @@ -209,7 +209,9 @@ static const struct i2c_board_info wm1277_devs[] = { }; static struct arizona_pdata wm5102_reva_pdata = { - .ldoena = S3C64XX_GPN(7), + .ldo1 = { + .ldoena = S3C64XX_GPN(7), + }, .gpio_base = CODEC_GPIO_BASE, .irq_flags = IRQF_TRIGGER_HIGH, .micd_pol_gpio = CODEC_GPIO_BASE + 4, @@ -239,7 +241,9 @@ static struct spi_board_info wm5102_reva_spi_devs[] = { }; static struct arizona_pdata wm5102_pdata = { - .ldoena = S3C64XX_GPN(7), + .ldo1 = { + .ldoena = S3C64XX_GPN(7), + }, .gpio_base = CODEC_GPIO_BASE, .irq_flags = IRQF_TRIGGER_HIGH, .micd_pol_gpio = CODEC_GPIO_BASE + 2, diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index be06eb29c681..9ecd70373f0b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -125,12 +125,20 @@ config REGULATOR_AB8500 This driver supports the regulators found on the ST-Ericsson mixed signal AB8500 PMIC -config REGULATOR_ARIZONA - tristate "Wolfson Arizona class devices" +config REGULATOR_ARIZONA_LDO1 + tristate "Wolfson Arizona class devices LDO1" depends on MFD_ARIZONA depends on SND_SOC help - Support for the regulators found on Wolfson Arizona class + Support for the LDO1 regulators found on Wolfson Arizona class + devices. + +config REGULATOR_ARIZONA_MICSUPP + tristate "Wolfson Arizona class devices MICSUPP" + depends on MFD_ARIZONA + depends on SND_SOC + help + Support for the MICSUPP regulators found on Wolfson Arizona class devices. config REGULATOR_AS3711 @@ -163,6 +171,17 @@ config REGULATOR_BCM590XX BCM590xx PMUs. This will enable support for the software controllable LDO/Switching regulators. +config REGULATOR_BD9571MWV + tristate "ROHM BD9571MWV Regulators" + depends on MFD_BD9571MWV + help + This driver provides support for the voltage regulators on the + ROHM BD9571MWV PMIC. This will enable support for the software + controllable regulator and voltage sampling units. + + This driver can also be built as a module. If so, the module + will be called bd9571mwv-regulator. + config REGULATOR_CPCAP tristate "Motorola CPCAP regulator" depends on MFD_CPCAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index ef7725e2592a..ddbde708385d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -19,11 +19,13 @@ obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o obj-$(CONFIG_REGULATOR_ACT8945A) += act8945a-regulator.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o -obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o +obj-$(CONFIG_REGULATOR_ARIZONA_LDO1) += arizona-ldo1.o +obj-$(CONFIG_REGULATOR_ARIZONA_MICSUPP) += arizona-micsupp.o obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o +obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index b041f277a38b..7d6478e6a503 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -39,7 +39,6 @@ #define LDO_FET_FULL_ON 0x1f struct anatop_regulator { - const char *name; u32 control_reg; struct regmap *anatop; int vol_bit_shift; @@ -193,13 +192,21 @@ static int anatop_regulator_probe(struct platform_device *pdev) sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); if (!sreg) return -ENOMEM; - sreg->name = of_get_property(np, "regulator-name", NULL); + rdesc = &sreg->rdesc; - rdesc->name = sreg->name; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; + of_property_read_string(np, "regulator-name", &rdesc->name); + if (!rdesc->name) { + dev_err(dev, "failed to get a regulator-name\n"); + return -EINVAL; + } + initdata = of_get_regulator_init_data(dev, np, rdesc); + if (!initdata) + return -ENOMEM; + initdata->supply_regulator = "vin"; sreg->initdata = initdata; @@ -293,9 +300,13 @@ static int anatop_regulator_probe(struct platform_device *pdev) * a sane default until imx6-cpufreq was probed and changes the * voltage to the correct value. In this case we set 1.25V. */ - if (!sreg->sel && !strcmp(sreg->name, "vddpu")) + if (!sreg->sel && !strcmp(rdesc->name, "vddpu")) sreg->sel = 22; + /* set the default voltage of the pcie phy to be 1.100v */ + if (!sreg->sel && !strcmp(rdesc->name, "vddpcie")) + sreg->sel = 0x10; + if (!sreg->bypass && !sreg->sel) { dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n"); return -EINVAL; diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index e76d094591e7..96fddfff5dc4 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -25,13 +25,15 @@ #include <linux/gpio.h> #include <linux/slab.h> +#include <linux/regulator/arizona-ldo1.h> + #include <linux/mfd/arizona/core.h> #include <linux/mfd/arizona/pdata.h> #include <linux/mfd/arizona/registers.h> struct arizona_ldo1 { struct regulator_dev *regulator; - struct arizona *arizona; + struct regmap *regmap; struct regulator_consumer_supply supply; struct regulator_init_data init_data; @@ -65,7 +67,7 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) { struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); - struct regmap *regmap = ldo->arizona->regmap; + struct regmap *regmap = ldo->regmap; unsigned int val; int ret; @@ -91,7 +93,7 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) { struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); - struct regmap *regmap = ldo->arizona->regmap; + struct regmap *regmap = ldo->regmap; unsigned int val; int ret; @@ -186,19 +188,19 @@ static const struct regulator_init_data arizona_ldo1_wm5110 = { .num_consumer_supplies = 1, }; -static int arizona_ldo1_of_get_pdata(struct arizona *arizona, +static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata, struct regulator_config *config, - const struct regulator_desc *desc) + const struct regulator_desc *desc, + bool *external_dcvdd) { - struct arizona_pdata *pdata = &arizona->pdata; struct arizona_ldo1 *ldo1 = config->driver_data; - struct device_node *np = arizona->dev->of_node; + struct device_node *np = config->dev->of_node; struct device_node *init_node, *dcvdd_node; struct regulator_init_data *init_data; pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0); if (pdata->ldoena < 0) { - dev_warn(arizona->dev, + dev_warn(config->dev, "LDOENA GPIO property missing/malformed: %d\n", pdata->ldoena); pdata->ldoena = 0; @@ -212,20 +214,19 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona, if (init_node) { config->of_node = init_node; - init_data = of_get_regulator_init_data(arizona->dev, init_node, + init_data = of_get_regulator_init_data(config->dev, init_node, desc); - if (init_data) { init_data->consumer_supplies = &ldo1->supply; init_data->num_consumer_supplies = 1; if (dcvdd_node && dcvdd_node != init_node) - arizona->external_dcvdd = true; + *external_dcvdd = true; - pdata->ldo1 = init_data; + pdata->init_data = init_data; } } else if (dcvdd_node) { - arizona->external_dcvdd = true; + *external_dcvdd = true; } of_node_put(dcvdd_node); @@ -233,66 +234,40 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona, return 0; } -static int arizona_ldo1_probe(struct platform_device *pdev) +static int arizona_ldo1_common_init(struct platform_device *pdev, + struct arizona_ldo1 *ldo1, + const struct regulator_desc *desc, + struct arizona_ldo1_pdata *pdata, + bool *external_dcvdd) { - struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); - const struct regulator_desc *desc; + struct device *parent_dev = pdev->dev.parent; struct regulator_config config = { }; - struct arizona_ldo1 *ldo1; int ret; - arizona->external_dcvdd = false; - - ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); - if (!ldo1) - return -ENOMEM; - - ldo1->arizona = arizona; - - /* - * Since the chip usually supplies itself we provide some - * default init_data for it. This will be overridden with - * platform data if provided. - */ - switch (arizona->type) { - case WM5102: - case WM8997: - case WM8998: - case WM1814: - desc = &arizona_ldo1_hc; - ldo1->init_data = arizona_ldo1_dvfs; - break; - case WM5110: - case WM8280: - desc = &arizona_ldo1; - ldo1->init_data = arizona_ldo1_wm5110; - break; - default: - desc = &arizona_ldo1; - ldo1->init_data = arizona_ldo1_default; - break; - } + *external_dcvdd = false; - ldo1->init_data.consumer_supplies = &ldo1->supply; ldo1->supply.supply = "DCVDD"; - ldo1->supply.dev_name = dev_name(arizona->dev); + ldo1->init_data.consumer_supplies = &ldo1->supply; + ldo1->supply.dev_name = dev_name(parent_dev); - config.dev = arizona->dev; + config.dev = parent_dev; config.driver_data = ldo1; - config.regmap = arizona->regmap; + config.regmap = ldo1->regmap; if (IS_ENABLED(CONFIG_OF)) { - if (!dev_get_platdata(arizona->dev)) { - ret = arizona_ldo1_of_get_pdata(arizona, &config, desc); + if (!dev_get_platdata(parent_dev)) { + ret = arizona_ldo1_of_get_pdata(pdata, + &config, desc, + external_dcvdd); if (ret < 0) return ret; } } - config.ena_gpio = arizona->pdata.ldoena; + config.ena_gpio = pdata->ldoena; - if (arizona->pdata.ldo1) - config.init_data = arizona->pdata.ldo1; + if (pdata->init_data) + config.init_data = pdata->init_data; else config.init_data = &ldo1->init_data; @@ -301,7 +276,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) * consumers then DCVDD is supplied externally. */ if (config.init_data->num_consumer_supplies == 0) - arizona->external_dcvdd = true; + *external_dcvdd = true; ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); @@ -309,7 +284,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) if (IS_ERR(ldo1->regulator)) { ret = PTR_ERR(ldo1->regulator); - dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", + dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n", ret); return ret; } @@ -319,6 +294,53 @@ static int arizona_ldo1_probe(struct platform_device *pdev) return 0; } +static int arizona_ldo1_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + struct arizona_ldo1 *ldo1; + const struct regulator_desc *desc; + bool external_dcvdd; + int ret; + + ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); + if (!ldo1) + return -ENOMEM; + + ldo1->regmap = arizona->regmap; + + /* + * Since the chip usually supplies itself we provide some + * default init_data for it. This will be overridden with + * platform data if provided. + */ + switch (arizona->type) { + case WM5102: + case WM8997: + case WM8998: + case WM1814: + desc = &arizona_ldo1_hc; + ldo1->init_data = arizona_ldo1_dvfs; + break; + case WM5110: + case WM8280: + desc = &arizona_ldo1; + ldo1->init_data = arizona_ldo1_wm5110; + break; + default: + desc = &arizona_ldo1; + ldo1->init_data = arizona_ldo1_default; + break; + } + + ret = arizona_ldo1_common_init(pdev, ldo1, desc, + &arizona->pdata.ldo1, + &external_dcvdd); + if (ret == 0) + arizona->external_dcvdd = external_dcvdd; + + return ret; +} + static struct platform_driver arizona_ldo1_driver = { .probe = arizona_ldo1_probe, .driver = { diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 22bd71407622..120de94caf02 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -30,9 +30,14 @@ #include <linux/mfd/arizona/pdata.h> #include <linux/mfd/arizona/registers.h> +#include <linux/regulator/arizona-micsupp.h> + struct arizona_micsupp { struct regulator_dev *regulator; - struct arizona *arizona; + struct regmap *regmap; + struct snd_soc_dapm_context **dapm; + unsigned int enable_reg; + struct device *dev; struct regulator_consumer_supply supply; struct regulator_init_data init_data; @@ -44,21 +49,22 @@ static void arizona_micsupp_check_cp(struct work_struct *work) { struct arizona_micsupp *micsupp = container_of(work, struct arizona_micsupp, check_cp_work); - struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm; - struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); - struct arizona *arizona = micsupp->arizona; - struct regmap *regmap = arizona->regmap; - unsigned int reg; + struct snd_soc_dapm_context *dapm = *micsupp->dapm; + struct snd_soc_component *component; + unsigned int val; int ret; - ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, ®); + ret = regmap_read(micsupp->regmap, micsupp->enable_reg, &val); if (ret != 0) { - dev_err(arizona->dev, "Failed to read CP state: %d\n", ret); + dev_err(micsupp->dev, + "Failed to read CP state: %d\n", ret); return; } if (dapm) { - if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) == + component = snd_soc_dapm_to_component(dapm); + + if ((val & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) == ARIZONA_CPMIC_ENA) snd_soc_component_force_enable_pin(component, "MICSUPP"); @@ -199,89 +205,67 @@ static const struct regulator_init_data arizona_micsupp_ext_default = { .num_consumer_supplies = 1, }; -static int arizona_micsupp_of_get_pdata(struct arizona *arizona, +static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata, struct regulator_config *config, const struct regulator_desc *desc) { - struct arizona_pdata *pdata = &arizona->pdata; struct arizona_micsupp *micsupp = config->driver_data; struct device_node *np; struct regulator_init_data *init_data; - np = of_get_child_by_name(arizona->dev->of_node, "micvdd"); + np = of_get_child_by_name(config->dev->of_node, "micvdd"); if (np) { config->of_node = np; - init_data = of_get_regulator_init_data(arizona->dev, np, desc); + init_data = of_get_regulator_init_data(config->dev, np, desc); if (init_data) { init_data->consumer_supplies = &micsupp->supply; init_data->num_consumer_supplies = 1; - pdata->micvdd = init_data; + pdata->init_data = init_data; } } return 0; } -static int arizona_micsupp_probe(struct platform_device *pdev) +static int arizona_micsupp_common_init(struct platform_device *pdev, + struct arizona_micsupp *micsupp, + const struct regulator_desc *desc, + struct arizona_micsupp_pdata *pdata) { - struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); - const struct regulator_desc *desc; struct regulator_config config = { }; - struct arizona_micsupp *micsupp; int ret; - micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); - if (!micsupp) - return -ENOMEM; - - micsupp->arizona = arizona; INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); - /* - * Since the chip usually supplies itself we provide some - * default init_data for it. This will be overridden with - * platform data if provided. - */ - switch (arizona->type) { - case WM5110: - case WM8280: - desc = &arizona_micsupp_ext; - micsupp->init_data = arizona_micsupp_ext_default; - break; - default: - desc = &arizona_micsupp; - micsupp->init_data = arizona_micsupp_default; - break; - } - micsupp->init_data.consumer_supplies = &micsupp->supply; micsupp->supply.supply = "MICVDD"; - micsupp->supply.dev_name = dev_name(arizona->dev); + micsupp->supply.dev_name = dev_name(micsupp->dev); + micsupp->enable_reg = desc->enable_reg; - config.dev = arizona->dev; + config.dev = micsupp->dev; config.driver_data = micsupp; - config.regmap = arizona->regmap; + config.regmap = micsupp->regmap; if (IS_ENABLED(CONFIG_OF)) { - if (!dev_get_platdata(arizona->dev)) { - ret = arizona_micsupp_of_get_pdata(arizona, &config, + if (!dev_get_platdata(micsupp->dev)) { + ret = arizona_micsupp_of_get_pdata(pdata, &config, desc); if (ret < 0) return ret; } } - if (arizona->pdata.micvdd) - config.init_data = arizona->pdata.micvdd; + if (pdata->init_data) + config.init_data = pdata->init_data; else config.init_data = &micsupp->init_data; - /* Default to regulated mode until the API supports bypass */ - regmap_update_bits(arizona->regmap, ARIZONA_MIC_CHARGE_PUMP_1, + /* Default to regulated mode */ + regmap_update_bits(micsupp->regmap, micsupp->enable_reg, ARIZONA_CPMIC_BYPASS, 0); micsupp->regulator = devm_regulator_register(&pdev->dev, @@ -292,7 +276,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev) if (IS_ERR(micsupp->regulator)) { ret = PTR_ERR(micsupp->regulator); - dev_err(arizona->dev, "Failed to register mic supply: %d\n", + dev_err(micsupp->dev, "Failed to register mic supply: %d\n", ret); return ret; } @@ -302,6 +286,41 @@ static int arizona_micsupp_probe(struct platform_device *pdev) return 0; } +static int arizona_micsupp_probe(struct platform_device *pdev) +{ + struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); + const struct regulator_desc *desc; + struct arizona_micsupp *micsupp; + + micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); + if (!micsupp) + return -ENOMEM; + + micsupp->regmap = arizona->regmap; + micsupp->dapm = &arizona->dapm; + micsupp->dev = arizona->dev; + + /* + * Since the chip usually supplies itself we provide some + * default init_data for it. This will be overridden with + * platform data if provided. + */ + switch (arizona->type) { + case WM5110: + case WM8280: + desc = &arizona_micsupp_ext; + micsupp->init_data = arizona_micsupp_ext_default; + break; + default: + desc = &arizona_micsupp; + micsupp->init_data = arizona_micsupp_default; + break; + } + + return arizona_micsupp_common_init(pdev, micsupp, desc, + &arizona->pdata.micvdd); +} + static struct platform_driver arizona_micsupp_driver = { .probe = arizona_micsupp_probe, .driver = { diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c new file mode 100644 index 000000000000..8ba206fec31e --- /dev/null +++ b/drivers/regulator/bd9571mwv-regulator.c @@ -0,0 +1,178 @@ +/* + * ROHM BD9571MWV-M regulator driver + * + * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + * + * Based on the TPS65086 driver + * + * NOTE: VD09 is missing + */ + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> + +#include <linux/mfd/bd9571mwv.h> + +enum bd9571mwv_regulators { VD09, VD18, VD25, VD33, DVFS }; + +#define BD9571MWV_REG(_name, _of, _id, _ops, _vr, _vm, _nv, _min, _step, _lmin)\ + { \ + .name = _name, \ + .of_match = of_match_ptr(_of), \ + .regulators_node = "regulators", \ + .id = _id, \ + .ops = &_ops, \ + .n_voltages = _nv, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = _vr, \ + .vsel_mask = _vm, \ + .min_uV = _min, \ + .uV_step = _step, \ + .linear_min_sel = _lmin, \ + } + +int bd9571mwv_avs_get_moni_state(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, BD9571MWV_AVS_SET_MONI, &val); + if (ret != 0) + return ret; + + return val & BD9571MWV_AVS_SET_MONI_MASK; +} + +int bd9571mwv_avs_set_voltage_sel_regmap(struct regulator_dev *rdev, + unsigned int sel) +{ + int ret; + + ret = bd9571mwv_avs_get_moni_state(rdev); + if (ret < 0) + return ret; + + return regmap_write_bits(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), + rdev->desc->vsel_mask, sel); +} + +int bd9571mwv_avs_get_voltage_sel_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = bd9571mwv_avs_get_moni_state(rdev); + if (ret < 0) + return ret; + + ret = regmap_read(rdev->regmap, BD9571MWV_AVS_VD09_VID(ret), &val); + if (ret != 0) + return ret; + + val &= rdev->desc->vsel_mask; + val >>= ffs(rdev->desc->vsel_mask) - 1; + + return val; +} + +int bd9571mwv_reg_set_voltage_sel_regmap(struct regulator_dev *rdev, + unsigned int sel) +{ + return regmap_write_bits(rdev->regmap, BD9571MWV_DVFS_SETVID, + rdev->desc->vsel_mask, sel); +} + +/* Operations permitted on AVS voltage regulator */ +static struct regulator_ops avs_ops = { + .set_voltage_sel = bd9571mwv_avs_set_voltage_sel_regmap, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = bd9571mwv_avs_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +/* Operations permitted on voltage regulators */ +static struct regulator_ops reg_ops = { + .set_voltage_sel = bd9571mwv_reg_set_voltage_sel_regmap, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +/* Operations permitted on voltage monitors */ +static struct regulator_ops vid_ops = { + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, +}; + +static struct regulator_desc regulators[] = { + BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f, + 0x80, 600000, 10000, 0x3c), + BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf, + 16, 1625000, 25000, 0), + BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf, + 16, 2150000, 50000, 0), + BD9571MWV_REG("VD33", "vd33", VD33, vid_ops, BD9571MWV_VD33_VID, 0xf, + 11, 2800000, 100000, 0), + BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops, + BD9571MWV_DVFS_MONIVDAC, 0x7f, + 0x80, 600000, 10000, 0x3c), +}; + +static int bd9571mwv_regulator_probe(struct platform_device *pdev) +{ + struct bd9571mwv *bd = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; + + platform_set_drvdata(pdev, bd); + + config.dev = &pdev->dev; + config.dev->of_node = bd->dev->of_node; + config.driver_data = bd; + config.regmap = bd->regmap; + + for (i = 0; i < ARRAY_SIZE(regulators); i++) { + rdev = devm_regulator_register(&pdev->dev, ®ulators[i], + &config); + if (IS_ERR(rdev)) { + dev_err(bd->dev, "failed to register %s regulator\n", + pdev->name); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct platform_device_id bd9571mwv_regulator_id_table[] = { + { "bd9571mwv-regulator", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table); + +static struct platform_driver bd9571mwv_regulator_driver = { + .driver = { + .name = "bd9571mwv-regulator", + }, + .probe = bd9571mwv_regulator_probe, + .id_table = bd9571mwv_regulator_id_table, +}; +module_platform_driver(bd9571mwv_regulator_driver); + +MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>"); +MODULE_DESCRIPTION("BD9571MWV Regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 2c1228d5796a..6779c2b53674 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -126,14 +126,14 @@ static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev, * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back * the set up value. */ -static struct regulator_ops max1586_v3_ops = { +static const struct regulator_ops max1586_v3_ops = { .get_voltage_sel = max1586_v3_get_voltage_sel, .set_voltage_sel = max1586_v3_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; -static struct regulator_ops max1586_v6_ops = { +static const struct regulator_ops max1586_v6_ops = { .get_voltage_sel = max1586_v6_get_voltage_sel, .set_voltage_sel = max1586_v6_set_voltage_sel, .list_voltage = regulator_list_voltage_table, diff --git a/drivers/regulator/max77693-regulator.c b/drivers/regulator/max77693-regulator.c index 3fce67982682..e7000e777292 100644 --- a/drivers/regulator/max77693-regulator.c +++ b/drivers/regulator/max77693-regulator.c @@ -150,7 +150,7 @@ static const struct regulator_ops max77693_safeout_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static struct regulator_ops max77693_charger_ops = { +static const struct regulator_ops max77693_charger_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index b87f62dd484e..a6183425f27d 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -194,7 +194,7 @@ static int max8660_ldo5_set_voltage_sel(struct regulator_dev *rdev, return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0); } -static struct regulator_ops max8660_ldo5_ops = { +static const struct regulator_ops max8660_ldo5_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .set_voltage_sel = max8660_ldo5_set_voltage_sel, @@ -252,7 +252,7 @@ static int max8660_ldo67_set_voltage_sel(struct regulator_dev *rdev, selector << 4); } -static struct regulator_ops max8660_ldo67_ops = { +static const struct regulator_ops max8660_ldo67_ops = { .is_enabled = max8660_ldo67_is_enabled, .enable = max8660_ldo67_enable, .disable = max8660_ldo67_disable, diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 38ee97a085f9..48f0ca90743c 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -213,7 +213,7 @@ ramp_disable: 1 << enable_shift, 0); } -static struct regulator_ops s2mpa01_ldo_ops = { +static const struct regulator_ops s2mpa01_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -224,7 +224,7 @@ static struct regulator_ops s2mpa01_ldo_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops s2mpa01_buck_ops = { +static const struct regulator_ops s2mpa01_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -359,11 +359,11 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev) if (iodev->dev->of_node) { reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); - if (!reg_np) { - dev_err(&pdev->dev, - "could not find regulators sub-node\n"); - return -EINVAL; - } + if (!reg_np) { + dev_err(&pdev->dev, + "could not find regulators sub-node\n"); + return -EINVAL; + } of_regulator_match(&pdev->dev, reg_np, rdata, S2MPA01_REGULATOR_MAX); diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d838e77dd947..7726b874e539 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -238,7 +238,7 @@ ramp_disable: 1 << enable_shift, 0); } -static struct regulator_ops s2mps11_ldo_ops = { +static const struct regulator_ops s2mps11_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -249,7 +249,7 @@ static struct regulator_ops s2mps11_ldo_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops s2mps11_buck_ops = { +static const struct regulator_ops s2mps11_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -392,7 +392,7 @@ static const struct regulator_desc s2mps11_regulators[] = { regulator_desc_s2mps11_buck67810(10, MIN_750_MV, STEP_12_5_MV), }; -static struct regulator_ops s2mps14_reg_ops; +static const struct regulator_ops s2mps14_reg_ops; #define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \ .name = "LDO"#num, \ @@ -599,7 +599,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) rdev->desc->enable_mask, state); } -static struct regulator_ops s2mps14_reg_ops = { +static const struct regulator_ops s2mps14_reg_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -681,7 +681,7 @@ static const struct regulator_desc s2mps14_regulators[] = { S2MPS14_BUCK1235_START_SEL), }; -static struct regulator_ops s2mps15_reg_ldo_ops = { +static const struct regulator_ops s2mps15_reg_ldo_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .is_enabled = regulator_is_enabled_regmap, @@ -691,7 +691,7 @@ static struct regulator_ops s2mps15_reg_ldo_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static struct regulator_ops s2mps15_reg_buck_ops = { +static const struct regulator_ops s2mps15_reg_buck_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .is_enabled = regulator_is_enabled_regmap, @@ -886,7 +886,7 @@ static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) ramp_val << ramp_shift); } -static struct regulator_ops s2mpu02_ldo_ops = { +static const struct regulator_ops s2mpu02_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, @@ -898,7 +898,7 @@ static struct regulator_ops s2mpu02_ldo_ops = { .set_suspend_disable = s2mps14_regulator_set_suspend_disable, }; -static struct regulator_ops s2mpu02_buck_ops = { +static const struct regulator_ops s2mpu02_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 27343e1c43ef..383cd7533721 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -357,7 +357,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, return 0; } -static struct regulator_ops s5m8767_ops = { +static const struct regulator_ops s5m8767_ops = { .list_voltage = regulator_list_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, @@ -367,7 +367,7 @@ static struct regulator_ops s5m8767_ops = { .set_voltage_time_sel = s5m8767_set_voltage_time_sel, }; -static struct regulator_ops s5m8767_buck78_ops = { +static const struct regulator_ops s5m8767_buck78_ops = { .list_voltage = regulator_list_voltage_linear, .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 64faeeff698c..bfeecf179895 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -12,6 +12,8 @@ #define _ARIZONA_PDATA_H #include <dt-bindings/mfd/arizona.h> +#include <linux/regulator/arizona-ldo1.h> +#include <linux/regulator/arizona-micsupp.h> #define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */ #define ARIZONA_GPN_DIR_SHIFT 15 /* GPN_DIR */ @@ -76,13 +78,12 @@ struct arizona_micd_range { struct arizona_pdata { int reset; /** GPIO controlling /RESET, if any */ - int ldoena; /** GPIO controlling LODENA, if any */ /** Regulator configuration for MICVDD */ - struct regulator_init_data *micvdd; + struct arizona_micsupp_pdata micvdd; /** Regulator configuration for LDO1 */ - struct regulator_init_data *ldo1; + struct arizona_ldo1_pdata ldo1; /** If a direct 32kHz clock is provided on an MCLK specify it here */ int clk32k_src; diff --git a/include/linux/regulator/arizona-ldo1.h b/include/linux/regulator/arizona-ldo1.h new file mode 100644 index 000000000000..c685f1277c63 --- /dev/null +++ b/include/linux/regulator/arizona-ldo1.h @@ -0,0 +1,24 @@ +/* + * Platform data for Arizona LDO1 regulator + * + * Copyright 2017 Cirrus Logic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ARIZONA_LDO1_H +#define ARIZONA_LDO1_H + +struct regulator_init_data; + +struct arizona_ldo1_pdata { + /** GPIO controlling LDOENA, if any */ + int ldoena; + + /** Regulator configuration for LDO1 */ + const struct regulator_init_data *init_data; +}; + +#endif diff --git a/include/linux/regulator/arizona-micsupp.h b/include/linux/regulator/arizona-micsupp.h new file mode 100644 index 000000000000..616842619c00 --- /dev/null +++ b/include/linux/regulator/arizona-micsupp.h @@ -0,0 +1,21 @@ +/* + * Platform data for Arizona micsupp regulator + * + * Copyright 2017 Cirrus Logic + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef ARIZONA_MICSUPP_H +#define ARIZONA_MICSUPP_H + +struct regulator_init_data; + +struct arizona_micsupp_pdata { + /** Regulator configuration for micsupp */ + const struct regulator_init_data *init_data; +}; + +#endif |