summaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-08-10 12:31:24 -0400
committerMark Brown <broonie@kernel.org>2018-08-10 12:31:24 -0400
commitd22d59362b7b2c749245f1269d447011c76ca41d (patch)
treeb3fc0673f62394dc5ed417eac6bad485a28baf25 /drivers/regulator
parenta8afa92ec0d9312b23fd291aa8db95da266f2d5f (diff)
parent46fc033eba42f5a4fb583b2ab53f0a9918468452 (diff)
Merge branch 'regulator-4.19' into regulator-next
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig25
-rw-r--r--drivers/regulator/Makefile4
-rw-r--r--drivers/regulator/bd71837-regulator.c44
-rw-r--r--drivers/regulator/bd9571mwv-regulator.c72
-rw-r--r--drivers/regulator/core.c44
-rw-r--r--drivers/regulator/cpcap-regulator.c103
-rw-r--r--drivers/regulator/max14577-regulator.c22
-rw-r--r--drivers/regulator/max77686-regulator.c32
-rw-r--r--drivers/regulator/max77693-regulator.c32
-rw-r--r--drivers/regulator/max77802-regulator.c34
-rw-r--r--drivers/regulator/max8997-regulator.c33
-rw-r--r--drivers/regulator/max8998.c28
-rw-r--r--drivers/regulator/pfuze100-regulator.c112
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c769
-rw-r--r--drivers/regulator/qcom_spmi-regulator.c38
-rw-r--r--drivers/regulator/s2mpa01.c14
-rw-r--r--drivers/regulator/s2mps11.c21
-rw-r--r--drivers/regulator/s5m8767.c16
-rw-r--r--drivers/regulator/tps65217-regulator.c2
-rw-r--r--drivers/regulator/uniphier-regulator.c213
20 files changed, 1411 insertions, 247 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5f3037..329cdd33ed62 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -180,9 +180,9 @@ config REGULATOR_BCM590XX
180 BCM590xx PMUs. This will enable support for the software 180 BCM590xx PMUs. This will enable support for the software
181 controllable LDO/Switching regulators. 181 controllable LDO/Switching regulators.
182 182
183config REGULATOR_BD71837 183config REGULATOR_BD718XX
184 tristate "ROHM BD71837 Power Regulator" 184 tristate "ROHM BD71837 Power Regulator"
185 depends on MFD_BD71837 185 depends on MFD_ROHM_BD718XX
186 help 186 help
187 This driver supports voltage regulators on ROHM BD71837 PMIC. 187 This driver supports voltage regulators on ROHM BD71837 PMIC.
188 This will enable support for the software controllable buck 188 This will enable support for the software controllable buck
@@ -633,12 +633,12 @@ config REGULATOR_PCF50633
633 on PCF50633 633 on PCF50633
634 634
635config REGULATOR_PFUZE100 635config REGULATOR_PFUZE100
636 tristate "Freescale PFUZE100/200/3000 regulator driver" 636 tristate "Freescale PFUZE100/200/3000/3001 regulator driver"
637 depends on I2C 637 depends on I2C
638 select REGMAP_I2C 638 select REGMAP_I2C
639 help 639 help
640 Say y here to support the regulators found on the Freescale 640 Say y here to support the regulators found on the Freescale
641 PFUZE100/200/3000 PMIC. 641 PFUZE100/200/3000/3001 PMIC.
642 642
643config REGULATOR_PV88060 643config REGULATOR_PV88060
644 tristate "Powerventure Semiconductor PV88060 regulator" 644 tristate "Powerventure Semiconductor PV88060 regulator"
@@ -682,6 +682,15 @@ config REGULATOR_QCOM_RPM
682 Qualcomm RPM as a module. The module will be named 682 Qualcomm RPM as a module. The module will be named
683 "qcom_rpm-regulator". 683 "qcom_rpm-regulator".
684 684
685config REGULATOR_QCOM_RPMH
686 tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
687 depends on QCOM_RPMH || COMPILE_TEST
688 help
689 This driver supports control of PMIC regulators via the RPMh hardware
690 block found on Qualcomm Technologies Inc. SoCs. RPMh regulator
691 control allows for voting on regulator state between multiple
692 processors within the SoC.
693
685config REGULATOR_QCOM_SMD_RPM 694config REGULATOR_QCOM_SMD_RPM
686 tristate "Qualcomm SMD based RPM regulator driver" 695 tristate "Qualcomm SMD based RPM regulator driver"
687 depends on QCOM_SMD_RPM 696 depends on QCOM_SMD_RPM
@@ -950,6 +959,14 @@ config REGULATOR_TWL4030
950 This driver supports the voltage regulators provided by 959 This driver supports the voltage regulators provided by
951 this family of companion chips. 960 this family of companion chips.
952 961
962config REGULATOR_UNIPHIER
963 tristate "UniPhier regulator driver"
964 depends on ARCH_UNIPHIER || COMPILE_TEST
965 depends on OF && MFD_SYSCON
966 default ARCH_UNIPHIER
967 help
968 Support for regulators implemented on Socionext UniPhier SoCs.
969
953config REGULATOR_VCTRL 970config REGULATOR_VCTRL
954 tristate "Voltage controlled regulators" 971 tristate "Voltage controlled regulators"
955 depends on OF 972 depends on OF
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bd818ceb7c72..801d9a34a203 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
27obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o 27obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
28obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o 28obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
29obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o 29obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
30obj-$(CONFIG_REGULATOR_BD71837) += bd71837-regulator.o 30obj-$(CONFIG_REGULATOR_BD718XX) += bd71837-regulator.o
31obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o 31obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
32obj-$(CONFIG_REGULATOR_DA903X) += da903x.o 32obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
33obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o 33obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
@@ -78,6 +78,7 @@ obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
78obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o 78obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
79obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o 79obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
80obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o 80obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
81obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
81obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o 82obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
82obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o 83obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
83obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o 84obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
@@ -118,6 +119,7 @@ obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
118obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o 119obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
119obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o 120obj-$(CONFIG_REGULATOR_TPS65132) += tps65132-regulator.o
120obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o 121obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
122obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o
121obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o 123obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
122obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o 124obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
123obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 125obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index 6eae4d0432a2..0f8ac8dec3e1 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -2,19 +2,18 @@
2// Copyright (C) 2018 ROHM Semiconductors 2// Copyright (C) 2018 ROHM Semiconductors
3// bd71837-regulator.c ROHM BD71837MWV regulator driver 3// bd71837-regulator.c ROHM BD71837MWV regulator driver
4 4
5#include <linux/kernel.h> 5#include <linux/delay.h>
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/err.h> 6#include <linux/err.h>
7#include <linux/gpio.h>
9#include <linux/interrupt.h> 8#include <linux/interrupt.h>
9#include <linux/kernel.h>
10#include <linux/mfd/rohm-bd718x7.h>
11#include <linux/module.h>
10#include <linux/platform_device.h> 12#include <linux/platform_device.h>
11#include <linux/regulator/driver.h> 13#include <linux/regulator/driver.h>
12#include <linux/regulator/machine.h> 14#include <linux/regulator/machine.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/gpio.h>
16#include <linux/mfd/bd71837.h>
17#include <linux/regulator/of_regulator.h> 15#include <linux/regulator/of_regulator.h>
16#include <linux/slab.h>
18 17
19struct bd71837_pmic { 18struct bd71837_pmic {
20 struct regulator_desc descs[BD71837_REGULATOR_CNT]; 19 struct regulator_desc descs[BD71837_REGULATOR_CNT];
@@ -39,7 +38,7 @@ static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
39 int id = rdev->desc->id; 38 int id = rdev->desc->id;
40 unsigned int ramp_value = BUCK_RAMPRATE_10P00MV; 39 unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
41 40
42 dev_dbg(&(pmic->pdev->dev), "Buck[%d] Set Ramp = %d\n", id + 1, 41 dev_dbg(&pmic->pdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1,
43 ramp_delay); 42 ramp_delay);
44 switch (ramp_delay) { 43 switch (ramp_delay) {
45 case 1 ... 1250: 44 case 1 ... 1250:
@@ -73,14 +72,10 @@ static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
73static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev, 72static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
74 unsigned int sel) 73 unsigned int sel)
75{ 74{
76 int ret; 75 if (regulator_is_enabled_regmap(rdev))
77 76 return -EBUSY;
78 ret = regulator_is_enabled_regmap(rdev); 77
79 if (!ret) 78 return regulator_set_voltage_sel_regmap(rdev, sel);
80 ret = regulator_set_voltage_sel_regmap(rdev, sel);
81 else if (ret == 1)
82 ret = -EBUSY;
83 return ret;
84} 79}
85 80
86static struct regulator_ops bd71837_ldo_regulator_ops = { 81static struct regulator_ops bd71837_ldo_regulator_ops = {
@@ -195,7 +190,7 @@ static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
195 * LDO2 190 * LDO2
196 * 0.8 or 0.9V 191 * 0.8 or 0.9V
197 */ 192 */
198const unsigned int ldo_2_volts[] = { 193static const unsigned int ldo_2_volts[] = {
199 900000, 800000 194 900000, 800000
200}; 195};
201 196
@@ -495,7 +490,6 @@ struct reg_init {
495static int bd71837_probe(struct platform_device *pdev) 490static int bd71837_probe(struct platform_device *pdev)
496{ 491{
497 struct bd71837_pmic *pmic; 492 struct bd71837_pmic *pmic;
498 struct bd71837_board *pdata;
499 struct regulator_config config = { 0 }; 493 struct regulator_config config = { 0 };
500 struct reg_init pmic_regulator_inits[] = { 494 struct reg_init pmic_regulator_inits[] = {
501 { 495 {
@@ -548,8 +542,7 @@ static int bd71837_probe(struct platform_device *pdev)
548 542
549 int i, err; 543 int i, err;
550 544
551 pmic = devm_kzalloc(&pdev->dev, sizeof(struct bd71837_pmic), 545 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
552 GFP_KERNEL);
553 if (!pmic) 546 if (!pmic)
554 return -ENOMEM; 547 return -ENOMEM;
555 548
@@ -564,7 +557,6 @@ static int bd71837_probe(struct platform_device *pdev)
564 goto err; 557 goto err;
565 } 558 }
566 platform_set_drvdata(pdev, pmic); 559 platform_set_drvdata(pdev, pmic);
567 pdata = dev_get_platdata(pmic->mfd->dev);
568 560
569 /* Register LOCK release */ 561 /* Register LOCK release */
570 err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK, 562 err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK,
@@ -573,8 +565,8 @@ static int bd71837_probe(struct platform_device *pdev)
573 dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err); 565 dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err);
574 goto err; 566 goto err;
575 } else { 567 } else {
576 dev_dbg(&pmic->pdev->dev, "%s: Unlocked lock register 0x%x\n", 568 dev_dbg(&pmic->pdev->dev, "Unlocked lock register 0x%x\n",
577 __func__, BD71837_REG_REGLOCK); 569 BD71837_REG_REGLOCK);
578 } 570 }
579 571
580 for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) { 572 for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
@@ -584,9 +576,6 @@ static int bd71837_probe(struct platform_device *pdev)
584 576
585 desc = &pmic->descs[i]; 577 desc = &pmic->descs[i];
586 578
587 if (pdata)
588 config.init_data = pdata->init_data[i];
589
590 config.dev = pdev->dev.parent; 579 config.dev = pdev->dev.parent;
591 config.driver_data = pmic; 580 config.driver_data = pmic;
592 config.regmap = pmic->mfd->regmap; 581 config.regmap = pmic->mfd->regmap;
@@ -619,8 +608,6 @@ static int bd71837_probe(struct platform_device *pdev)
619 pmic->rdev[i] = rdev; 608 pmic->rdev[i] = rdev;
620 } 609 }
621 610
622 return 0;
623
624err: 611err:
625 return err; 612 return err;
626} 613}
@@ -628,7 +615,6 @@ err:
628static struct platform_driver bd71837_regulator = { 615static struct platform_driver bd71837_regulator = {
629 .driver = { 616 .driver = {
630 .name = "bd71837-pmic", 617 .name = "bd71837-pmic",
631 .owner = THIS_MODULE,
632 }, 618 },
633 .probe = bd71837_probe, 619 .probe = bd71837_probe,
634}; 620};
diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c
index be574eb444eb..274c5ed7cd73 100644
--- a/drivers/regulator/bd9571mwv-regulator.c
+++ b/drivers/regulator/bd9571mwv-regulator.c
@@ -30,6 +30,7 @@ struct bd9571mwv_reg {
30 /* DDR Backup Power */ 30 /* DDR Backup Power */
31 u8 bkup_mode_cnt_keepon; /* from "rohm,ddr-backup-power" */ 31 u8 bkup_mode_cnt_keepon; /* from "rohm,ddr-backup-power" */
32 u8 bkup_mode_cnt_saved; 32 u8 bkup_mode_cnt_saved;
33 bool bkup_mode_enabled;
33 34
34 /* Power switch type */ 35 /* Power switch type */
35 bool rstbmode_level; 36 bool rstbmode_level;
@@ -171,13 +172,60 @@ static int bd9571mwv_bkup_mode_write(struct bd9571mwv *bd, unsigned int mode)
171 return 0; 172 return 0;
172} 173}
173 174
175static ssize_t backup_mode_show(struct device *dev,
176 struct device_attribute *attr, char *buf)
177{
178 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
179
180 return sprintf(buf, "%s\n", bdreg->bkup_mode_enabled ? "on" : "off");
181}
182
183static ssize_t backup_mode_store(struct device *dev,
184 struct device_attribute *attr,
185 const char *buf, size_t count)
186{
187 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
188 unsigned int mode;
189 int ret;
190
191 if (!count)
192 return 0;
193
194 ret = kstrtobool(buf, &bdreg->bkup_mode_enabled);
195 if (ret)
196 return ret;
197
198 if (!bdreg->rstbmode_level)
199 return count;
200
201 /*
202 * Configure DDR Backup Mode, to change the role of the accessory power
203 * switch from a power switch to a wake-up switch, or vice versa
204 */
205 ret = bd9571mwv_bkup_mode_read(bdreg->bd, &mode);
206 if (ret)
207 return ret;
208
209 mode &= ~BD9571MWV_BKUP_MODE_CNT_KEEPON_MASK;
210 if (bdreg->bkup_mode_enabled)
211 mode |= bdreg->bkup_mode_cnt_keepon;
212
213 ret = bd9571mwv_bkup_mode_write(bdreg->bd, mode);
214 if (ret)
215 return ret;
216
217 return count;
218}
219
220static DEVICE_ATTR_RW(backup_mode);
221
174static int bd9571mwv_suspend(struct device *dev) 222static int bd9571mwv_suspend(struct device *dev)
175{ 223{
176 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev); 224 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
177 unsigned int mode; 225 unsigned int mode;
178 int ret; 226 int ret;
179 227
180 if (!device_may_wakeup(dev)) 228 if (!bdreg->bkup_mode_enabled)
181 return 0; 229 return 0;
182 230
183 /* Save DDR Backup Mode */ 231 /* Save DDR Backup Mode */
@@ -204,7 +252,7 @@ static int bd9571mwv_resume(struct device *dev)
204{ 252{
205 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev); 253 struct bd9571mwv_reg *bdreg = dev_get_drvdata(dev);
206 254
207 if (!device_may_wakeup(dev)) 255 if (!bdreg->bkup_mode_enabled)
208 return 0; 256 return 0;
209 257
210 /* Restore DDR Backup Mode */ 258 /* Restore DDR Backup Mode */
@@ -215,9 +263,15 @@ static const struct dev_pm_ops bd9571mwv_pm = {
215 SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume) 263 SET_SYSTEM_SLEEP_PM_OPS(bd9571mwv_suspend, bd9571mwv_resume)
216}; 264};
217 265
266static int bd9571mwv_regulator_remove(struct platform_device *pdev)
267{
268 device_remove_file(&pdev->dev, &dev_attr_backup_mode);
269 return 0;
270}
218#define DEV_PM_OPS &bd9571mwv_pm 271#define DEV_PM_OPS &bd9571mwv_pm
219#else 272#else
220#define DEV_PM_OPS NULL 273#define DEV_PM_OPS NULL
274#define bd9571mwv_regulator_remove NULL
221#endif /* CONFIG_PM_SLEEP */ 275#endif /* CONFIG_PM_SLEEP */
222 276
223static int bd9571mwv_regulator_probe(struct platform_device *pdev) 277static int bd9571mwv_regulator_probe(struct platform_device *pdev)
@@ -270,14 +324,21 @@ static int bd9571mwv_regulator_probe(struct platform_device *pdev)
270 return -EINVAL; 324 return -EINVAL;
271 } 325 }
272 326
327#ifdef CONFIG_PM_SLEEP
273 if (bdreg->bkup_mode_cnt_keepon) { 328 if (bdreg->bkup_mode_cnt_keepon) {
274 device_set_wakeup_capable(&pdev->dev, true); 329 int ret;
330
275 /* 331 /*
276 * Wakeup is enabled by default in pulse mode, but needs 332 * Backup mode is enabled by default in pulse mode, but needs
277 * explicit user setup in level mode. 333 * explicit user setup in level mode.
278 */ 334 */
279 device_set_wakeup_enable(&pdev->dev, bdreg->rstbmode_pulse); 335 bdreg->bkup_mode_enabled = bdreg->rstbmode_pulse;
336
337 ret = device_create_file(&pdev->dev, &dev_attr_backup_mode);
338 if (ret)
339 return ret;
280 } 340 }
341#endif /* CONFIG_PM_SLEEP */
281 342
282 return 0; 343 return 0;
283} 344}
@@ -294,6 +355,7 @@ static struct platform_driver bd9571mwv_regulator_driver = {
294 .pm = DEV_PM_OPS, 355 .pm = DEV_PM_OPS,
295 }, 356 },
296 .probe = bd9571mwv_regulator_probe, 357 .probe = bd9571mwv_regulator_probe,
358 .remove = bd9571mwv_regulator_remove,
297 .id_table = bd9571mwv_regulator_id_table, 359 .id_table = bd9571mwv_regulator_id_table,
298}; 360};
299module_platform_driver(bd9571mwv_regulator_driver); 361module_platform_driver(bd9571mwv_regulator_driver);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6ed568b96c0e..bb1324f93143 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1740,6 +1740,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
1740 rdev->use_count = 0; 1740 rdev->use_count = 0;
1741 } 1741 }
1742 1742
1743 device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
1744
1743 return regulator; 1745 return regulator;
1744} 1746}
1745 1747
@@ -1829,9 +1831,21 @@ static void _regulator_put(struct regulator *regulator)
1829 1831
1830 debugfs_remove_recursive(regulator->debugfs); 1832 debugfs_remove_recursive(regulator->debugfs);
1831 1833
1832 /* remove any sysfs entries */ 1834 if (regulator->dev) {
1833 if (regulator->dev) 1835 int count = 0;
1836 struct regulator *r;
1837
1838 list_for_each_entry(r, &rdev->consumer_list, list)
1839 if (r->dev == regulator->dev)
1840 count++;
1841
1842 if (count == 1)
1843 device_link_remove(regulator->dev, &rdev->dev);
1844
1845 /* remove any sysfs entries */
1834 sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); 1846 sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
1847 }
1848
1835 regulator_lock(rdev); 1849 regulator_lock(rdev);
1836 list_del(&regulator->list); 1850 list_del(&regulator->list);
1837 1851
@@ -4441,7 +4455,7 @@ void regulator_unregister(struct regulator_dev *rdev)
4441EXPORT_SYMBOL_GPL(regulator_unregister); 4455EXPORT_SYMBOL_GPL(regulator_unregister);
4442 4456
4443#ifdef CONFIG_SUSPEND 4457#ifdef CONFIG_SUSPEND
4444static int _regulator_suspend_late(struct device *dev, void *data) 4458static int _regulator_suspend(struct device *dev, void *data)
4445{ 4459{
4446 struct regulator_dev *rdev = dev_to_rdev(dev); 4460 struct regulator_dev *rdev = dev_to_rdev(dev);
4447 suspend_state_t *state = data; 4461 suspend_state_t *state = data;
@@ -4455,20 +4469,20 @@ static int _regulator_suspend_late(struct device *dev, void *data)
4455} 4469}
4456 4470
4457/** 4471/**
4458 * regulator_suspend_late - prepare regulators for system wide suspend 4472 * regulator_suspend - prepare regulators for system wide suspend
4459 * @state: system suspend state 4473 * @state: system suspend state
4460 * 4474 *
4461 * Configure each regulator with it's suspend operating parameters for state. 4475 * Configure each regulator with it's suspend operating parameters for state.
4462 */ 4476 */
4463static int regulator_suspend_late(struct device *dev) 4477static int regulator_suspend(struct device *dev)
4464{ 4478{
4465 suspend_state_t state = pm_suspend_target_state; 4479 suspend_state_t state = pm_suspend_target_state;
4466 4480
4467 return class_for_each_device(&regulator_class, NULL, &state, 4481 return class_for_each_device(&regulator_class, NULL, &state,
4468 _regulator_suspend_late); 4482 _regulator_suspend);
4469} 4483}
4470 4484
4471static int _regulator_resume_early(struct device *dev, void *data) 4485static int _regulator_resume(struct device *dev, void *data)
4472{ 4486{
4473 int ret = 0; 4487 int ret = 0;
4474 struct regulator_dev *rdev = dev_to_rdev(dev); 4488 struct regulator_dev *rdev = dev_to_rdev(dev);
@@ -4481,35 +4495,35 @@ static int _regulator_resume_early(struct device *dev, void *data)
4481 4495
4482 regulator_lock(rdev); 4496 regulator_lock(rdev);
4483 4497
4484 if (rdev->desc->ops->resume_early && 4498 if (rdev->desc->ops->resume &&
4485 (rstate->enabled == ENABLE_IN_SUSPEND || 4499 (rstate->enabled == ENABLE_IN_SUSPEND ||
4486 rstate->enabled == DISABLE_IN_SUSPEND)) 4500 rstate->enabled == DISABLE_IN_SUSPEND))
4487 ret = rdev->desc->ops->resume_early(rdev); 4501 ret = rdev->desc->ops->resume(rdev);
4488 4502
4489 regulator_unlock(rdev); 4503 regulator_unlock(rdev);
4490 4504
4491 return ret; 4505 return ret;
4492} 4506}
4493 4507
4494static int regulator_resume_early(struct device *dev) 4508static int regulator_resume(struct device *dev)
4495{ 4509{
4496 suspend_state_t state = pm_suspend_target_state; 4510 suspend_state_t state = pm_suspend_target_state;
4497 4511
4498 return class_for_each_device(&regulator_class, NULL, &state, 4512 return class_for_each_device(&regulator_class, NULL, &state,
4499 _regulator_resume_early); 4513 _regulator_resume);
4500} 4514}
4501 4515
4502#else /* !CONFIG_SUSPEND */ 4516#else /* !CONFIG_SUSPEND */
4503 4517
4504#define regulator_suspend_late NULL 4518#define regulator_suspend NULL
4505#define regulator_resume_early NULL 4519#define regulator_resume NULL
4506 4520
4507#endif /* !CONFIG_SUSPEND */ 4521#endif /* !CONFIG_SUSPEND */
4508 4522
4509#ifdef CONFIG_PM 4523#ifdef CONFIG_PM
4510static const struct dev_pm_ops __maybe_unused regulator_pm_ops = { 4524static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
4511 .suspend_late = regulator_suspend_late, 4525 .suspend = regulator_suspend,
4512 .resume_early = regulator_resume_early, 4526 .resume = regulator_resume,
4513}; 4527};
4514#endif 4528#endif
4515 4529
diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c
index bd910fe123d9..2131457937b7 100644
--- a/drivers/regulator/cpcap-regulator.c
+++ b/drivers/regulator/cpcap-regulator.c
@@ -271,6 +271,29 @@ static struct regulator_ops cpcap_regulator_ops = {
271}; 271};
272 272
273static const unsigned int unknown_val_tbl[] = { 0, }; 273static const unsigned int unknown_val_tbl[] = { 0, };
274static const unsigned int sw2_sw4_val_tbl[] = { 612500, 625000, 637500,
275 650000, 662500, 675000,
276 687500, 700000, 712500,
277 725000, 737500, 750000,
278 762500, 775000, 787500,
279 800000, 812500, 825000,
280 837500, 850000, 862500,
281 875000, 887500, 900000,
282 912500, 925000, 937500,
283 950000, 962500, 975000,
284 987500, 1000000, 1012500,
285 1025000, 1037500, 1050000,
286 1062500, 1075000, 1087500,
287 1100000, 1112500, 1125000,
288 1137500, 1150000, 1162500,
289 1175000, 1187500, 1200000,
290 1212500, 1225000, 1237500,
291 1250000, 1262500, 1275000,
292 1287500, 1300000, 1312500,
293 1325000, 1337500, 1350000,
294 1362500, 1375000, 1387500,
295 1400000, 1412500, 1425000,
296 1437500, 1450000, 1462500, };
274static const unsigned int sw5_val_tbl[] = { 0, 5050000, }; 297static const unsigned int sw5_val_tbl[] = { 0, 5050000, };
275static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000, 298static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000,
276 2900000, }; 299 2900000, };
@@ -389,6 +412,82 @@ static struct cpcap_regulator omap4_regulators[] = {
389 { /* sentinel */ }, 412 { /* sentinel */ },
390}; 413};
391 414
415static struct cpcap_regulator xoom_regulators[] = {
416 CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
417 CPCAP_BIT_SW1_SEL, unknown_val_tbl,
418 0, 0, 0, 0, 0, 0),
419 CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
420 CPCAP_BIT_SW2_SEL, sw2_sw4_val_tbl,
421 0xf00, 0x7f, 0, 0x800, 0, 120),
422 CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
423 CPCAP_BIT_SW3_SEL, unknown_val_tbl,
424 0, 0, 0, 0, 0, 0),
425 CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
426 CPCAP_BIT_SW4_SEL, sw2_sw4_val_tbl,
427 0xf00, 0x7f, 0, 0x900, 0, 100),
428 CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
429 CPCAP_BIT_SW5_SEL, sw5_val_tbl,
430 0x2a, 0, 0, 0x22, 0, 0),
431 CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
432 CPCAP_BIT_SW6_SEL, unknown_val_tbl,
433 0, 0, 0, 0, 0, 0),
434 CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
435 CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
436 0x87, 0x30, 4, 0x7, 0, 420),
437 CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
438 CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
439 0x47, 0x10, 4, 0x7, 0, 350),
440 CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
441 CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
442 0x87, 0x30, 4, 0x3, 0, 420),
443 CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
444 CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
445 0x87, 0x30, 4, 0x5, 0, 420),
446 CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
447 CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
448 0x80, 0xf, 0, 0x80, 0, 420),
449 CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
450 CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
451 0x17, 0, 0, 0x2, 0, 0),
452 CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
453 CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
454 0x87, 0x38, 3, 0x2, 0, 420),
455 CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
456 CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
457 0x43, 0x18, 3, 0x1, 0, 420),
458 CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
459 CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
460 0xac, 0x2, 1, 0xc, 0, 10),
461 CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
462 CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
463 0x23, 0x8, 3, 0x3, 0, 10),
464 CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
465 CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
466 0x23, 0x8, 3, 0x3, 0, 420),
467 CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
468 CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
469 0x47, 0x10, 4, 0x5, 0, 420),
470 CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
471 CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
472 0x20c, 0xc0, 6, 0x8, 0, 420),
473 CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
474 0xffff, vsim_val_tbl,
475 0x23, 0x8, 3, 0x3, 0, 420),
476 CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
477 0xffff, vsimcard_val_tbl,
478 0x1e80, 0x8, 3, 0x1e00, 0, 420),
479 CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
480 CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
481 0x1, 0xc, 2, 0, 0x1, 500),
482 CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
483 CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
484 0x11c, 0x40, 6, 0xc, 0, 0),
485 CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
486 CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
487 0x16, 0x1, 0, 0x4, 0, 0),
488 { /* sentinel */ },
489};
490
392static const struct of_device_id cpcap_regulator_id_table[] = { 491static const struct of_device_id cpcap_regulator_id_table[] = {
393 { 492 {
394 .compatible = "motorola,cpcap-regulator", 493 .compatible = "motorola,cpcap-regulator",
@@ -397,6 +496,10 @@ static const struct of_device_id cpcap_regulator_id_table[] = {
397 .compatible = "motorola,mapphone-cpcap-regulator", 496 .compatible = "motorola,mapphone-cpcap-regulator",
398 .data = omap4_regulators, 497 .data = omap4_regulators,
399 }, 498 },
499 {
500 .compatible = "motorola,xoom-cpcap-regulator",
501 .data = xoom_regulators,
502 },
400 {}, 503 {},
401}; 504};
402MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table); 505MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table);
diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c
index 0db288ce319c..bc7f4751bf9c 100644
--- a/drivers/regulator/max14577-regulator.c
+++ b/drivers/regulator/max14577-regulator.c
@@ -1,19 +1,9 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max14577.c - Regulator driver for the Maxim 14577/77836 2//
3 * 3// max14577.c - Regulator driver for the Maxim 14577/77836
4 * Copyright (C) 2013,2014 Samsung Electronics 4//
5 * Krzysztof Kozlowski <krzk@kernel.org> 5// Copyright (C) 2013,2014 Samsung Electronics
6 * 6// Krzysztof Kozlowski <krzk@kernel.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17 7
18#include <linux/module.h> 8#include <linux/module.h>
19#include <linux/platform_device.h> 9#include <linux/platform_device.h>
diff --git a/drivers/regulator/max77686-regulator.c b/drivers/regulator/max77686-regulator.c
index c301f3733475..bee060937f56 100644
--- a/drivers/regulator/max77686-regulator.c
+++ b/drivers/regulator/max77686-regulator.c
@@ -1,26 +1,12 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77686.c - Regulator driver for the Maxim 77686 2//
3 * 3// max77686.c - Regulator driver for the Maxim 77686
4 * Copyright (C) 2012 Samsung Electronics 4//
5 * Chiwoong Byun <woong.byun@samsung.com> 5// Copyright (C) 2012 Samsung Electronics
6 * Jonghwa Lee <jonghwa3.lee@samsung.com> 6// Chiwoong Byun <woong.byun@samsung.com>
7 * 7// Jonghwa Lee <jonghwa3.lee@samsung.com>
8 * This program is free software; you can redistribute it and/or modify 8//
9 * it under the terms of the GNU General Public License as published by 9// This driver is based on max8997.c
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * This driver is based on max8997.c
23 */
24 10
25#include <linux/kernel.h> 11#include <linux/kernel.h>
26#include <linux/bug.h> 12#include <linux/bug.h>
diff --git a/drivers/regulator/max77693-regulator.c b/drivers/regulator/max77693-regulator.c
index e7000e777292..077ecbbfdf76 100644
--- a/drivers/regulator/max77693-regulator.c
+++ b/drivers/regulator/max77693-regulator.c
@@ -1,26 +1,12 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77693.c - Regulator driver for the Maxim 77693 and 77843 2//
3 * 3// max77693.c - Regulator driver for the Maxim 77693 and 77843
4 * Copyright (C) 2013-2015 Samsung Electronics 4//
5 * Jonghwa Lee <jonghwa3.lee@samsung.com> 5// Copyright (C) 2013-2015 Samsung Electronics
6 * Krzysztof Kozlowski <krzk@kernel.org> 6// Jonghwa Lee <jonghwa3.lee@samsung.com>
7 * 7// Krzysztof Kozlowski <krzk@kernel.org>
8 * This program is free software; you can redistribute it and/or modify 8//
9 * it under the terms of the GNU General Public License as published by 9// This driver is based on max77686.c
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * This driver is based on max77686.c
23 */
24 10
25#include <linux/err.h> 11#include <linux/err.h>
26#include <linux/slab.h> 12#include <linux/slab.h>
diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c
index b6261903818c..c30cf5c9f2de 100644
--- a/drivers/regulator/max77802-regulator.c
+++ b/drivers/regulator/max77802-regulator.c
@@ -1,25 +1,15 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max77802.c - Regulator driver for the Maxim 77802 2//
3 * 3// max77802.c - Regulator driver for the Maxim 77802
4 * Copyright (C) 2013-2014 Google, Inc 4//
5 * Simon Glass <sjg@chromium.org> 5// Copyright (C) 2013-2014 Google, Inc
6 * 6// Simon Glass <sjg@chromium.org>
7 * Copyright (C) 2012 Samsung Electronics 7//
8 * Chiwoong Byun <woong.byun@samsung.com> 8// Copyright (C) 2012 Samsung Electronics
9 * Jonghwa Lee <jonghwa3.lee@samsung.com> 9// Chiwoong Byun <woong.byun@samsung.com>
10 * 10// Jonghwa Lee <jonghwa3.lee@samsung.com>
11 * This program is free software; you can redistribute it and/or modify 11//
12 * it under the terms of the GNU General Public License as published by 12// This driver is based on max8997.c
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * This driver is based on max8997.c
22 */
23 13
24#include <linux/kernel.h> 14#include <linux/kernel.h>
25#include <linux/bug.h> 15#include <linux/bug.h>
diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c
index a8ea30ee18a6..ad0c806b0737 100644
--- a/drivers/regulator/max8997-regulator.c
+++ b/drivers/regulator/max8997-regulator.c
@@ -1,25 +1,11 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max8997.c - Regulator driver for the Maxim 8997/8966 2//
3 * 3// max8997.c - Regulator driver for the Maxim 8997/8966
4 * Copyright (C) 2011 Samsung Electronics 4//
5 * MyungJoo Ham <myungjoo.ham@samsung.com> 5// Copyright (C) 2011 Samsung Electronics
6 * 6// MyungJoo Ham <myungjoo.ham@samsung.com>
7 * This program is free software; you can redistribute it and/or modify 7//
8 * it under the terms of the GNU General Public License as published by 8// This driver is based on max8998.c
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This driver is based on max8998.c
22 */
23 9
24#include <linux/bug.h> 10#include <linux/bug.h>
25#include <linux/err.h> 11#include <linux/err.h>
@@ -165,8 +151,7 @@ static int max8997_list_voltage(struct regulator_dev *rdev,
165 int rid = rdev_get_id(rdev); 151 int rid = rdev_get_id(rdev);
166 int val; 152 int val;
167 153
168 if (rid >= ARRAY_SIZE(reg_voltage_map) || 154 if (rid < 0 || rid >= ARRAY_SIZE(reg_voltage_map))
169 rid < 0)
170 return -EINVAL; 155 return -EINVAL;
171 156
172 desc = reg_voltage_map[rid]; 157 desc = reg_voltage_map[rid];
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 6b9f262ebbb0..271bb736f3f5 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -1,24 +1,10 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * max8998.c - Voltage regulator driver for the Maxim 8998 2//
3 * 3// max8998.c - Voltage regulator driver for the Maxim 8998
4 * Copyright (C) 2009-2010 Samsung Electronics 4//
5 * Kyungmin Park <kyungmin.park@samsung.com> 5// Copyright (C) 2009-2010 Samsung Electronics
6 * Marek Szyprowski <m.szyprowski@samsung.com> 6// Kyungmin Park <kyungmin.park@samsung.com>
7 * 7// Marek Szyprowski <m.szyprowski@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 8
23#include <linux/module.h> 9#include <linux/module.h>
24#include <linux/init.h> 10#include <linux/init.h>
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 8d9dbcc775ea..31c3a236120a 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -17,6 +17,8 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/regmap.h> 18#include <linux/regmap.h>
19 19
20#define PFUZE_FLAG_DISABLE_SW BIT(1)
21
20#define PFUZE_NUMREGS 128 22#define PFUZE_NUMREGS 128
21#define PFUZE100_VOL_OFFSET 0 23#define PFUZE100_VOL_OFFSET 0
22#define PFUZE100_STANDBY_OFFSET 1 24#define PFUZE100_STANDBY_OFFSET 1
@@ -44,16 +46,18 @@
44#define PFUZE100_VGEN5VOL 0x70 46#define PFUZE100_VGEN5VOL 0x70
45#define PFUZE100_VGEN6VOL 0x71 47#define PFUZE100_VGEN6VOL 0x71
46 48
47enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 }; 49enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3, PFUZE3001 = 0x31, };
48 50
49struct pfuze_regulator { 51struct pfuze_regulator {
50 struct regulator_desc desc; 52 struct regulator_desc desc;
51 unsigned char stby_reg; 53 unsigned char stby_reg;
52 unsigned char stby_mask; 54 unsigned char stby_mask;
55 bool sw_reg;
53}; 56};
54 57
55struct pfuze_chip { 58struct pfuze_chip {
56 int chip_id; 59 int chip_id;
60 int flags;
57 struct regmap *regmap; 61 struct regmap *regmap;
58 struct device *dev; 62 struct device *dev;
59 struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; 63 struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
@@ -92,6 +96,7 @@ static const struct i2c_device_id pfuze_device_id[] = {
92 {.name = "pfuze100", .driver_data = PFUZE100}, 96 {.name = "pfuze100", .driver_data = PFUZE100},
93 {.name = "pfuze200", .driver_data = PFUZE200}, 97 {.name = "pfuze200", .driver_data = PFUZE200},
94 {.name = "pfuze3000", .driver_data = PFUZE3000}, 98 {.name = "pfuze3000", .driver_data = PFUZE3000},
99 {.name = "pfuze3001", .driver_data = PFUZE3001},
95 { } 100 { }
96}; 101};
97MODULE_DEVICE_TABLE(i2c, pfuze_device_id); 102MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
@@ -100,6 +105,7 @@ static const struct of_device_id pfuze_dt_ids[] = {
100 { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, 105 { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
101 { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, 106 { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
102 { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000}, 107 { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000},
108 { .compatible = "fsl,pfuze3001", .data = (void *)PFUZE3001},
103 { } 109 { }
104}; 110};
105MODULE_DEVICE_TABLE(of, pfuze_dt_ids); 111MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
@@ -108,10 +114,28 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
108{ 114{
109 struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); 115 struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev);
110 int id = rdev_get_id(rdev); 116 int id = rdev_get_id(rdev);
117 bool reg_has_ramp_delay;
111 unsigned int ramp_bits; 118 unsigned int ramp_bits;
112 int ret; 119 int ret;
113 120
114 if (id < PFUZE100_SWBST) { 121 switch (pfuze100->chip_id) {
122 case PFUZE3001:
123 /* no dynamic voltage scaling for PF3001 */
124 reg_has_ramp_delay = false;
125 break;
126 case PFUZE3000:
127 reg_has_ramp_delay = (id < PFUZE3000_SWBST);
128 break;
129 case PFUZE200:
130 reg_has_ramp_delay = (id < PFUZE200_SWBST);
131 break;
132 case PFUZE100:
133 default:
134 reg_has_ramp_delay = (id < PFUZE100_SWBST);
135 break;
136 }
137
138 if (reg_has_ramp_delay) {
115 ramp_delay = 12500 / ramp_delay; 139 ramp_delay = 12500 / ramp_delay;
116 ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); 140 ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3);
117 ret = regmap_update_bits(pfuze100->regmap, 141 ret = regmap_update_bits(pfuze100->regmap,
@@ -119,8 +143,9 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
119 0xc0, ramp_bits << 6); 143 0xc0, ramp_bits << 6);
120 if (ret < 0) 144 if (ret < 0)
121 dev_err(pfuze100->dev, "ramp failed, err %d\n", ret); 145 dev_err(pfuze100->dev, "ramp failed, err %d\n", ret);
122 } else 146 } else {
123 ret = -EACCES; 147 ret = -EACCES;
148 }
124 149
125 return ret; 150 return ret;
126} 151}
@@ -142,6 +167,14 @@ static const struct regulator_ops pfuze100_fixed_regulator_ops = {
142}; 167};
143 168
144static const struct regulator_ops pfuze100_sw_regulator_ops = { 169static const struct regulator_ops pfuze100_sw_regulator_ops = {
170 .list_voltage = regulator_list_voltage_linear,
171 .set_voltage_sel = regulator_set_voltage_sel_regmap,
172 .get_voltage_sel = regulator_get_voltage_sel_regmap,
173 .set_voltage_time_sel = regulator_set_voltage_time_sel,
174 .set_ramp_delay = pfuze100_set_ramp_delay,
175};
176
177static const struct regulator_ops pfuze100_sw_disable_regulator_ops = {
145 .enable = regulator_enable_regmap, 178 .enable = regulator_enable_regmap,
146 .disable = regulator_disable_regmap, 179 .disable = regulator_disable_regmap,
147 .is_enabled = regulator_is_enabled_regmap, 180 .is_enabled = regulator_is_enabled_regmap,
@@ -192,13 +225,11 @@ static const struct regulator_ops pfuze100_swb_regulator_ops = {
192 .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ 225 .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
193 .vsel_mask = 0x3f, \ 226 .vsel_mask = 0x3f, \
194 .enable_reg = (base) + PFUZE100_MODE_OFFSET, \ 227 .enable_reg = (base) + PFUZE100_MODE_OFFSET, \
195 .enable_val = 0xc, \
196 .disable_val = 0x0, \
197 .enable_mask = 0xf, \ 228 .enable_mask = 0xf, \
198 .enable_time = 500, \
199 }, \ 229 }, \
200 .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ 230 .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
201 .stby_mask = 0x3f, \ 231 .stby_mask = 0x3f, \
232 .sw_reg = true, \
202 } 233 }
203 234
204#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \ 235#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \
@@ -361,6 +392,19 @@ static struct pfuze_regulator pfuze3000_regulators[] = {
361 PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), 392 PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
362}; 393};
363 394
395static struct pfuze_regulator pfuze3001_regulators[] = {
396 PFUZE100_SWB_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a),
397 PFUZE100_SWB_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo),
398 PFUZE3000_SW3_REG(PFUZE3001, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000),
399 PFUZE100_SWB_REG(PFUZE3001, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
400 PFUZE100_VGEN_REG(PFUZE3001, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000),
401 PFUZE100_VGEN_REG(PFUZE3001, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
402 PFUZE3000_VCC_REG(PFUZE3001, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000),
403 PFUZE3000_VCC_REG(PFUZE3001, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000),
404 PFUZE100_VGEN_REG(PFUZE3001, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
405 PFUZE100_VGEN_REG(PFUZE3001, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
406};
407
364#ifdef CONFIG_OF 408#ifdef CONFIG_OF
365/* PFUZE100 */ 409/* PFUZE100 */
366static struct of_regulator_match pfuze100_matches[] = { 410static struct of_regulator_match pfuze100_matches[] = {
@@ -418,6 +462,21 @@ static struct of_regulator_match pfuze3000_matches[] = {
418 { .name = "vldo4", }, 462 { .name = "vldo4", },
419}; 463};
420 464
465/* PFUZE3001 */
466static struct of_regulator_match pfuze3001_matches[] = {
467
468 { .name = "sw1", },
469 { .name = "sw2", },
470 { .name = "sw3", },
471 { .name = "vsnvs", },
472 { .name = "vldo1", },
473 { .name = "vldo2", },
474 { .name = "vccsd", },
475 { .name = "v33", },
476 { .name = "vldo3", },
477 { .name = "vldo4", },
478};
479
421static struct of_regulator_match *pfuze_matches; 480static struct of_regulator_match *pfuze_matches;
422 481
423static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) 482static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
@@ -430,6 +489,9 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
430 if (!np) 489 if (!np)
431 return -EINVAL; 490 return -EINVAL;
432 491
492 if (of_property_read_bool(np, "fsl,pfuze-support-disable-sw"))
493 chip->flags |= PFUZE_FLAG_DISABLE_SW;
494
433 parent = of_get_child_by_name(np, "regulators"); 495 parent = of_get_child_by_name(np, "regulators");
434 if (!parent) { 496 if (!parent) {
435 dev_err(dev, "regulators node not found\n"); 497 dev_err(dev, "regulators node not found\n");
@@ -437,6 +499,11 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
437 } 499 }
438 500
439 switch (chip->chip_id) { 501 switch (chip->chip_id) {
502 case PFUZE3001:
503 pfuze_matches = pfuze3001_matches;
504 ret = of_regulator_match(dev, parent, pfuze3001_matches,
505 ARRAY_SIZE(pfuze3001_matches));
506 break;
440 case PFUZE3000: 507 case PFUZE3000:
441 pfuze_matches = pfuze3000_matches; 508 pfuze_matches = pfuze3000_matches;
442 ret = of_regulator_match(dev, parent, pfuze3000_matches, 509 ret = of_regulator_match(dev, parent, pfuze3000_matches,
@@ -508,7 +575,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
508 */ 575 */
509 dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); 576 dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
510 } else if ((value & 0x0f) != pfuze_chip->chip_id && 577 } else if ((value & 0x0f) != pfuze_chip->chip_id &&
511 (value & 0xf0) >> 4 != pfuze_chip->chip_id) { 578 (value & 0xf0) >> 4 != pfuze_chip->chip_id &&
579 (value != pfuze_chip->chip_id)) {
512 /* device id NOT match with your setting */ 580 /* device id NOT match with your setting */
513 dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); 581 dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
514 return -ENODEV; 582 return -ENODEV;
@@ -588,6 +656,13 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
588 656
589 /* use the right regulators after identify the right device */ 657 /* use the right regulators after identify the right device */
590 switch (pfuze_chip->chip_id) { 658 switch (pfuze_chip->chip_id) {
659 case PFUZE3001:
660 pfuze_chip->pfuze_regulators = pfuze3001_regulators;
661 regulator_num = ARRAY_SIZE(pfuze3001_regulators);
662 sw_check_start = PFUZE3001_SW2;
663 sw_check_end = PFUZE3001_SW2;
664 sw_hi = 1 << 3;
665 break;
591 case PFUZE3000: 666 case PFUZE3000:
592 pfuze_chip->pfuze_regulators = pfuze3000_regulators; 667 pfuze_chip->pfuze_regulators = pfuze3000_regulators;
593 regulator_num = ARRAY_SIZE(pfuze3000_regulators); 668 regulator_num = ARRAY_SIZE(pfuze3000_regulators);
@@ -611,7 +686,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
611 } 686 }
612 dev_info(&client->dev, "pfuze%s found.\n", 687 dev_info(&client->dev, "pfuze%s found.\n",
613 (pfuze_chip->chip_id == PFUZE100) ? "100" : 688 (pfuze_chip->chip_id == PFUZE100) ? "100" :
614 ((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000")); 689 (((pfuze_chip->chip_id == PFUZE200) ? "200" :
690 ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001"))));
615 691
616 memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, 692 memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators,
617 sizeof(pfuze_chip->regulator_descs)); 693 sizeof(pfuze_chip->regulator_descs));
@@ -636,7 +712,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
636 if (i >= sw_check_start && i <= sw_check_end) { 712 if (i >= sw_check_start && i <= sw_check_end) {
637 regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); 713 regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
638 if (val & sw_hi) { 714 if (val & sw_hi) {
639 if (pfuze_chip->chip_id == PFUZE3000) { 715 if (pfuze_chip->chip_id == PFUZE3000 ||
716 pfuze_chip->chip_id == PFUZE3001) {
640 desc->volt_table = pfuze3000_sw2hi; 717 desc->volt_table = pfuze3000_sw2hi;
641 desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi); 718 desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi);
642 } else { 719 } else {
@@ -647,6 +724,21 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
647 } 724 }
648 } 725 }
649 726
727 /*
728 * Allow SW regulators to turn off. Checking it trough a flag is
729 * a workaround to keep the backward compatibility with existing
730 * old dtb's which may relay on the fact that we didn't disable
731 * the switched regulator till yet.
732 */
733 if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) {
734 if (pfuze_chip->regulator_descs[i].sw_reg) {
735 desc->ops = &pfuze100_sw_disable_regulator_ops;
736 desc->enable_val = 0x8;
737 desc->disable_val = 0x0;
738 desc->enable_time = 500;
739 }
740 }
741
650 config.dev = &client->dev; 742 config.dev = &client->dev;
651 config.init_data = init_data; 743 config.init_data = init_data;
652 config.driver_data = pfuze_chip; 744 config.driver_data = pfuze_chip;
@@ -675,5 +767,5 @@ static struct i2c_driver pfuze_driver = {
675module_i2c_driver(pfuze_driver); 767module_i2c_driver(pfuze_driver);
676 768
677MODULE_AUTHOR("Robin Gong <b38343@freescale.com>"); 769MODULE_AUTHOR("Robin Gong <b38343@freescale.com>");
678MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/200/3000 PMIC"); 770MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/200/3000/3001 PMIC");
679MODULE_LICENSE("GPL v2"); 771MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
new file mode 100644
index 000000000000..9f27daebd8c8
--- /dev/null
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -0,0 +1,769 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2018, The Linux Foundation. All rights reserved.
3
4#define pr_fmt(fmt) "%s: " fmt, __func__
5
6#include <linux/err.h>
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
11#include <linux/platform_device.h>
12#include <linux/slab.h>
13#include <linux/string.h>
14#include <linux/regulator/driver.h>
15#include <linux/regulator/machine.h>
16#include <linux/regulator/of_regulator.h>
17
18#include <soc/qcom/cmd-db.h>
19#include <soc/qcom/rpmh.h>
20
21#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
22
23/**
24 * enum rpmh_regulator_type - supported RPMh accelerator types
25 * %VRM: RPMh VRM accelerator which supports voting on enable, voltage,
26 * and mode of LDO, SMPS, and BOB type PMIC regulators.
27 * %XOB: RPMh XOB accelerator which supports voting on the enable state
28 * of PMIC regulators.
29 */
30enum rpmh_regulator_type {
31 VRM,
32 XOB,
33};
34
35#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0
36#define RPMH_REGULATOR_REG_ENABLE 0x4
37#define RPMH_REGULATOR_REG_VRM_MODE 0x8
38
39#define PMIC4_LDO_MODE_RETENTION 4
40#define PMIC4_LDO_MODE_LPM 5
41#define PMIC4_LDO_MODE_HPM 7
42
43#define PMIC4_SMPS_MODE_RETENTION 4
44#define PMIC4_SMPS_MODE_PFM 5
45#define PMIC4_SMPS_MODE_AUTO 6
46#define PMIC4_SMPS_MODE_PWM 7
47
48#define PMIC4_BOB_MODE_PASS 0
49#define PMIC4_BOB_MODE_PFM 1
50#define PMIC4_BOB_MODE_AUTO 2
51#define PMIC4_BOB_MODE_PWM 3
52
53/**
54 * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
55 * @regulator_type: RPMh accelerator type used to manage this
56 * regulator
57 * @ops: Pointer to regulator ops callback structure
58 * @voltage_range: The single range of voltages supported by this
59 * PMIC regulator type
60 * @n_voltages: The number of unique voltage set points defined
61 * by voltage_range
62 * @hpm_min_load_uA: Minimum load current in microamps that requires
63 * high power mode (HPM) operation. This is used
64 * for LDO hardware type regulators only.
65 * @pmic_mode_map: Array indexed by regulator framework mode
66 * containing PMIC hardware modes. Must be large
67 * enough to index all framework modes supported
68 * by this regulator hardware type.
69 * @of_map_mode: Maps an RPMH_REGULATOR_MODE_* mode value defined
70 * in device tree to a regulator framework mode
71 */
72struct rpmh_vreg_hw_data {
73 enum rpmh_regulator_type regulator_type;
74 const struct regulator_ops *ops;
75 const struct regulator_linear_range voltage_range;
76 int n_voltages;
77 int hpm_min_load_uA;
78 const int *pmic_mode_map;
79 unsigned int (*of_map_mode)(unsigned int mode);
80};
81
82/**
83 * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
84 * single regulator device
85 * @dev: Device pointer for the top-level PMIC RPMh
86 * regulator parent device. This is used as a
87 * handle in RPMh write requests.
88 * @addr: Base address of the regulator resource within
89 * an RPMh accelerator
90 * @rdesc: Regulator descriptor
91 * @hw_data: PMIC regulator configuration data for this RPMh
92 * regulator
93 * @always_wait_for_ack: Boolean flag indicating if a request must always
94 * wait for an ACK from RPMh before continuing even
95 * if it corresponds to a strictly lower power
96 * state (e.g. enabled --> disabled).
97 * @enabled: Flag indicating if the regulator is enabled or
98 * not
99 * @bypassed: Boolean indicating if the regulator is in
100 * bypass (pass-through) mode or not. This is
101 * only used by BOB rpmh-regulator resources.
102 * @voltage_selector: Selector used for get_voltage_sel() and
103 * set_voltage_sel() callbacks
104 * @mode: RPMh VRM regulator current framework mode
105 */
106struct rpmh_vreg {
107 struct device *dev;
108 u32 addr;
109 struct regulator_desc rdesc;
110 const struct rpmh_vreg_hw_data *hw_data;
111 bool always_wait_for_ack;
112
113 int enabled;
114 bool bypassed;
115 int voltage_selector;
116 unsigned int mode;
117};
118
119/**
120 * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
121 * @name: Name for the regulator which also corresponds
122 * to the device tree subnode name of the regulator
123 * @resource_name: RPMh regulator resource name format string.
124 * This must include exactly one field: '%s' which
125 * is filled at run-time with the PMIC ID provided
126 * by device tree property qcom,pmic-id. Example:
127 * "ldo%s1" for RPMh resource "ldoa1".
128 * @supply_name: Parent supply regulator name
129 * @hw_data: Configuration data for this PMIC regulator type
130 */
131struct rpmh_vreg_init_data {
132 const char *name;
133 const char *resource_name;
134 const char *supply_name;
135 const struct rpmh_vreg_hw_data *hw_data;
136};
137
138/**
139 * rpmh_regulator_send_request() - send the request to RPMh
140 * @vreg: Pointer to the RPMh regulator
141 * @cmd: Pointer to the RPMh command to send
142 * @wait_for_ack: Boolean indicating if execution must wait until the
143 * request has been acknowledged as complete
144 *
145 * Return: 0 on success, errno on failure
146 */
147static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
148 struct tcs_cmd *cmd, bool wait_for_ack)
149{
150 int ret;
151
152 if (wait_for_ack || vreg->always_wait_for_ack)
153 ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, 1);
154 else
155 ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
156 1);
157
158 return ret;
159}
160
161static int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
162 unsigned int selector, bool wait_for_ack)
163{
164 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
165 struct tcs_cmd cmd = {
166 .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
167 };
168 int ret;
169
170 /* VRM voltage control register is set with voltage in millivolts. */
171 cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
172 selector), 1000);
173
174 ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack);
175 if (!ret)
176 vreg->voltage_selector = selector;
177
178 return ret;
179}
180
181static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
182 unsigned int selector)
183{
184 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
185
186 if (vreg->enabled == -EINVAL) {
187 /*
188 * Cache the voltage and send it later when the regulator is
189 * enabled or disabled.
190 */
191 vreg->voltage_selector = selector;
192 return 0;
193 }
194
195 return _rpmh_regulator_vrm_set_voltage_sel(rdev, selector,
196 selector > vreg->voltage_selector);
197}
198
199static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
200{
201 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
202
203 return vreg->voltage_selector;
204}
205
206static int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
207{
208 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
209
210 return vreg->enabled;
211}
212
213static int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
214 bool enable)
215{
216 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
217 struct tcs_cmd cmd = {
218 .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
219 .data = enable,
220 };
221 int ret;
222
223 if (vreg->enabled == -EINVAL &&
224 vreg->voltage_selector != -ENOTRECOVERABLE) {
225 ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
226 vreg->voltage_selector, true);
227 if (ret < 0)
228 return ret;
229 }
230
231 ret = rpmh_regulator_send_request(vreg, &cmd, enable);
232 if (!ret)
233 vreg->enabled = enable;
234
235 return ret;
236}
237
238static int rpmh_regulator_enable(struct regulator_dev *rdev)
239{
240 return rpmh_regulator_set_enable_state(rdev, true);
241}
242
243static int rpmh_regulator_disable(struct regulator_dev *rdev)
244{
245 return rpmh_regulator_set_enable_state(rdev, false);
246}
247
248static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
249 unsigned int mode, bool bypassed)
250{
251 struct tcs_cmd cmd = {
252 .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
253 };
254 int pmic_mode;
255
256 if (mode > REGULATOR_MODE_STANDBY)
257 return -EINVAL;
258
259 pmic_mode = vreg->hw_data->pmic_mode_map[mode];
260 if (pmic_mode < 0)
261 return pmic_mode;
262
263 if (bypassed)
264 cmd.data = PMIC4_BOB_MODE_PASS;
265 else
266 cmd.data = pmic_mode;
267
268 return rpmh_regulator_send_request(vreg, &cmd, true);
269}
270
271static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
272 unsigned int mode)
273{
274 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
275 int ret;
276
277 if (mode == vreg->mode)
278 return 0;
279
280 ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
281 if (!ret)
282 vreg->mode = mode;
283
284 return ret;
285}
286
287static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
288{
289 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
290
291 return vreg->mode;
292}
293
294/**
295 * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
296 * current requested
297 * @rdev: Regulator device pointer for the rpmh-regulator
298 * @load_uA: Aggregated load current in microamps
299 *
300 * This function is used in the regulator_ops for VRM type RPMh regulator
301 * devices.
302 *
303 * Return: 0 on success, errno on failure
304 */
305static int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
306{
307 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
308 unsigned int mode;
309
310 if (load_uA >= vreg->hw_data->hpm_min_load_uA)
311 mode = REGULATOR_MODE_NORMAL;
312 else
313 mode = REGULATOR_MODE_IDLE;
314
315 return rpmh_regulator_vrm_set_mode(rdev, mode);
316}
317
318static int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
319 bool enable)
320{
321 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
322 int ret;
323
324 if (vreg->bypassed == enable)
325 return 0;
326
327 ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
328 if (!ret)
329 vreg->bypassed = enable;
330
331 return ret;
332}
333
334static int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
335 bool *enable)
336{
337 struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
338
339 *enable = vreg->bypassed;
340
341 return 0;
342}
343
344static const struct regulator_ops rpmh_regulator_vrm_ops = {
345 .enable = rpmh_regulator_enable,
346 .disable = rpmh_regulator_disable,
347 .is_enabled = rpmh_regulator_is_enabled,
348 .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
349 .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
350 .list_voltage = regulator_list_voltage_linear_range,
351 .set_mode = rpmh_regulator_vrm_set_mode,
352 .get_mode = rpmh_regulator_vrm_get_mode,
353};
354
355static const struct regulator_ops rpmh_regulator_vrm_drms_ops = {
356 .enable = rpmh_regulator_enable,
357 .disable = rpmh_regulator_disable,
358 .is_enabled = rpmh_regulator_is_enabled,
359 .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
360 .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
361 .list_voltage = regulator_list_voltage_linear_range,
362 .set_mode = rpmh_regulator_vrm_set_mode,
363 .get_mode = rpmh_regulator_vrm_get_mode,
364 .set_load = rpmh_regulator_vrm_set_load,
365};
366
367static const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
368 .enable = rpmh_regulator_enable,
369 .disable = rpmh_regulator_disable,
370 .is_enabled = rpmh_regulator_is_enabled,
371 .set_voltage_sel = rpmh_regulator_vrm_set_voltage_sel,
372 .get_voltage_sel = rpmh_regulator_vrm_get_voltage_sel,
373 .list_voltage = regulator_list_voltage_linear_range,
374 .set_mode = rpmh_regulator_vrm_set_mode,
375 .get_mode = rpmh_regulator_vrm_get_mode,
376 .set_bypass = rpmh_regulator_vrm_set_bypass,
377 .get_bypass = rpmh_regulator_vrm_get_bypass,
378};
379
380static const struct regulator_ops rpmh_regulator_xob_ops = {
381 .enable = rpmh_regulator_enable,
382 .disable = rpmh_regulator_disable,
383 .is_enabled = rpmh_regulator_is_enabled,
384};
385
386/**
387 * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
388 * vreg: Pointer to the individual rpmh-regulator resource
389 * dev: Pointer to the top level rpmh-regulator PMIC device
390 * node: Pointer to the individual rpmh-regulator resource
391 * device node
392 * pmic_id: String used to identify the top level rpmh-regulator
393 * PMIC device on the board
394 * pmic_rpmh_data: Pointer to a null-terminated array of rpmh-regulator
395 * resources defined for the top level PMIC device
396 *
397 * Return: 0 on success, errno on failure
398 */
399static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
400 struct device_node *node, const char *pmic_id,
401 const struct rpmh_vreg_init_data *pmic_rpmh_data)
402{
403 struct regulator_config reg_config = {};
404 char rpmh_resource_name[20] = "";
405 const struct rpmh_vreg_init_data *rpmh_data;
406 struct regulator_init_data *init_data;
407 struct regulator_dev *rdev;
408 int ret;
409
410 vreg->dev = dev;
411
412 for (rpmh_data = pmic_rpmh_data; rpmh_data->name; rpmh_data++)
413 if (!strcmp(rpmh_data->name, node->name))
414 break;
415
416 if (!rpmh_data->name) {
417 dev_err(dev, "Unknown regulator %s\n", node->name);
418 return -EINVAL;
419 }
420
421 scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
422 rpmh_data->resource_name, pmic_id);
423
424 vreg->addr = cmd_db_read_addr(rpmh_resource_name);
425 if (!vreg->addr) {
426 dev_err(dev, "%s: could not find RPMh address for resource %s\n",
427 node->name, rpmh_resource_name);
428 return -ENODEV;
429 }
430
431 vreg->rdesc.name = rpmh_data->name;
432 vreg->rdesc.supply_name = rpmh_data->supply_name;
433 vreg->hw_data = rpmh_data->hw_data;
434
435 vreg->enabled = -EINVAL;
436 vreg->voltage_selector = -ENOTRECOVERABLE;
437 vreg->mode = REGULATOR_MODE_INVALID;
438
439 if (rpmh_data->hw_data->n_voltages) {
440 vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
441 vreg->rdesc.n_linear_ranges = 1;
442 vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
443 }
444
445 vreg->always_wait_for_ack = of_property_read_bool(node,
446 "qcom,always-wait-for-ack");
447
448 vreg->rdesc.owner = THIS_MODULE;
449 vreg->rdesc.type = REGULATOR_VOLTAGE;
450 vreg->rdesc.ops = vreg->hw_data->ops;
451 vreg->rdesc.of_map_mode = vreg->hw_data->of_map_mode;
452
453 init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
454 if (!init_data)
455 return -ENOMEM;
456
457 if (rpmh_data->hw_data->regulator_type == XOB &&
458 init_data->constraints.min_uV &&
459 init_data->constraints.min_uV == init_data->constraints.max_uV) {
460 vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
461 vreg->rdesc.n_voltages = 1;
462 }
463
464 reg_config.dev = dev;
465 reg_config.init_data = init_data;
466 reg_config.of_node = node;
467 reg_config.driver_data = vreg;
468
469 rdev = devm_regulator_register(dev, &vreg->rdesc, &reg_config);
470 if (IS_ERR(rdev)) {
471 ret = PTR_ERR(rdev);
472 dev_err(dev, "%s: devm_regulator_register() failed, ret=%d\n",
473 node->name, ret);
474 return ret;
475 }
476
477 dev_dbg(dev, "%s regulator registered for RPMh resource %s @ 0x%05X\n",
478 node->name, rpmh_resource_name, vreg->addr);
479
480 return 0;
481}
482
483static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
484 [REGULATOR_MODE_INVALID] = -EINVAL,
485 [REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
486 [REGULATOR_MODE_IDLE] = PMIC4_LDO_MODE_LPM,
487 [REGULATOR_MODE_NORMAL] = PMIC4_LDO_MODE_HPM,
488 [REGULATOR_MODE_FAST] = -EINVAL,
489};
490
491static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
492{
493 unsigned int mode;
494
495 switch (rpmh_mode) {
496 case RPMH_REGULATOR_MODE_HPM:
497 mode = REGULATOR_MODE_NORMAL;
498 break;
499 case RPMH_REGULATOR_MODE_LPM:
500 mode = REGULATOR_MODE_IDLE;
501 break;
502 case RPMH_REGULATOR_MODE_RET:
503 mode = REGULATOR_MODE_STANDBY;
504 break;
505 default:
506 mode = REGULATOR_MODE_INVALID;
507 }
508
509 return mode;
510}
511
512static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
513 [REGULATOR_MODE_INVALID] = -EINVAL,
514 [REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
515 [REGULATOR_MODE_IDLE] = PMIC4_SMPS_MODE_PFM,
516 [REGULATOR_MODE_NORMAL] = PMIC4_SMPS_MODE_AUTO,
517 [REGULATOR_MODE_FAST] = PMIC4_SMPS_MODE_PWM,
518};
519
520static unsigned int
521rpmh_regulator_pmic4_smps_of_map_mode(unsigned int rpmh_mode)
522{
523 unsigned int mode;
524
525 switch (rpmh_mode) {
526 case RPMH_REGULATOR_MODE_HPM:
527 mode = REGULATOR_MODE_FAST;
528 break;
529 case RPMH_REGULATOR_MODE_AUTO:
530 mode = REGULATOR_MODE_NORMAL;
531 break;
532 case RPMH_REGULATOR_MODE_LPM:
533 mode = REGULATOR_MODE_IDLE;
534 break;
535 case RPMH_REGULATOR_MODE_RET:
536 mode = REGULATOR_MODE_STANDBY;
537 break;
538 default:
539 mode = REGULATOR_MODE_INVALID;
540 }
541
542 return mode;
543}
544
545static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
546 [REGULATOR_MODE_INVALID] = -EINVAL,
547 [REGULATOR_MODE_STANDBY] = -EINVAL,
548 [REGULATOR_MODE_IDLE] = PMIC4_BOB_MODE_PFM,
549 [REGULATOR_MODE_NORMAL] = PMIC4_BOB_MODE_AUTO,
550 [REGULATOR_MODE_FAST] = PMIC4_BOB_MODE_PWM,
551};
552
553static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
554{
555 unsigned int mode;
556
557 switch (rpmh_mode) {
558 case RPMH_REGULATOR_MODE_HPM:
559 mode = REGULATOR_MODE_FAST;
560 break;
561 case RPMH_REGULATOR_MODE_AUTO:
562 mode = REGULATOR_MODE_NORMAL;
563 break;
564 case RPMH_REGULATOR_MODE_LPM:
565 mode = REGULATOR_MODE_IDLE;
566 break;
567 default:
568 mode = REGULATOR_MODE_INVALID;
569 }
570
571 return mode;
572}
573
574static const struct rpmh_vreg_hw_data pmic4_pldo = {
575 .regulator_type = VRM,
576 .ops = &rpmh_regulator_vrm_drms_ops,
577 .voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
578 .n_voltages = 256,
579 .hpm_min_load_uA = 10000,
580 .pmic_mode_map = pmic_mode_map_pmic4_ldo,
581 .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
582};
583
584static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
585 .regulator_type = VRM,
586 .ops = &rpmh_regulator_vrm_drms_ops,
587 .voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
588 .n_voltages = 128,
589 .hpm_min_load_uA = 10000,
590 .pmic_mode_map = pmic_mode_map_pmic4_ldo,
591 .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
592};
593
594static const struct rpmh_vreg_hw_data pmic4_nldo = {
595 .regulator_type = VRM,
596 .ops = &rpmh_regulator_vrm_drms_ops,
597 .voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
598 .n_voltages = 128,
599 .hpm_min_load_uA = 30000,
600 .pmic_mode_map = pmic_mode_map_pmic4_ldo,
601 .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
602};
603
604static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
605 .regulator_type = VRM,
606 .ops = &rpmh_regulator_vrm_ops,
607 .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
608 .n_voltages = 216,
609 .pmic_mode_map = pmic_mode_map_pmic4_smps,
610 .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
611};
612
613static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
614 .regulator_type = VRM,
615 .ops = &rpmh_regulator_vrm_ops,
616 .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
617 .n_voltages = 259,
618 .pmic_mode_map = pmic_mode_map_pmic4_smps,
619 .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
620};
621
622static const struct rpmh_vreg_hw_data pmic4_bob = {
623 .regulator_type = VRM,
624 .ops = &rpmh_regulator_vrm_bypass_ops,
625 .voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
626 .n_voltages = 84,
627 .pmic_mode_map = pmic_mode_map_pmic4_bob,
628 .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
629};
630
631static const struct rpmh_vreg_hw_data pmic4_lvs = {
632 .regulator_type = XOB,
633 .ops = &rpmh_regulator_xob_ops,
634 /* LVS hardware does not support voltage or mode configuration. */
635};
636
637#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
638{ \
639 .name = _name, \
640 .resource_name = _resource_name, \
641 .hw_data = _hw_data, \
642 .supply_name = _supply_name, \
643}
644
645static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
646 RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"),
647 RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
648 RPMH_VREG("smps3", "smp%s3", &pmic4_hfsmps3, "vdd-s3"),
649 RPMH_VREG("smps4", "smp%s4", &pmic4_hfsmps3, "vdd-s4"),
650 RPMH_VREG("smps5", "smp%s5", &pmic4_hfsmps3, "vdd-s5"),
651 RPMH_VREG("smps6", "smp%s6", &pmic4_ftsmps426, "vdd-s6"),
652 RPMH_VREG("smps7", "smp%s7", &pmic4_ftsmps426, "vdd-s7"),
653 RPMH_VREG("smps8", "smp%s8", &pmic4_ftsmps426, "vdd-s8"),
654 RPMH_VREG("smps9", "smp%s9", &pmic4_ftsmps426, "vdd-s9"),
655 RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
656 RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
657 RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
658 RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
659 RPMH_VREG("ldo1", "ldo%s1", &pmic4_nldo, "vdd-l1-l27"),
660 RPMH_VREG("ldo2", "ldo%s2", &pmic4_nldo, "vdd-l2-l8-l17"),
661 RPMH_VREG("ldo3", "ldo%s3", &pmic4_nldo, "vdd-l3-l11"),
662 RPMH_VREG("ldo4", "ldo%s4", &pmic4_nldo, "vdd-l4-l5"),
663 RPMH_VREG("ldo5", "ldo%s5", &pmic4_nldo, "vdd-l4-l5"),
664 RPMH_VREG("ldo6", "ldo%s6", &pmic4_pldo, "vdd-l6"),
665 RPMH_VREG("ldo7", "ldo%s7", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
666 RPMH_VREG("ldo8", "ldo%s8", &pmic4_nldo, "vdd-l2-l8-l17"),
667 RPMH_VREG("ldo9", "ldo%s9", &pmic4_pldo, "vdd-l9"),
668 RPMH_VREG("ldo10", "ldo%s10", &pmic4_pldo, "vdd-l10-l23-l25"),
669 RPMH_VREG("ldo11", "ldo%s11", &pmic4_nldo, "vdd-l3-l11"),
670 RPMH_VREG("ldo12", "ldo%s12", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
671 RPMH_VREG("ldo13", "ldo%s13", &pmic4_pldo, "vdd-l13-l19-l21"),
672 RPMH_VREG("ldo14", "ldo%s14", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
673 RPMH_VREG("ldo15", "ldo%s15", &pmic4_pldo_lv, "vdd-l7-l12-l14-l15"),
674 RPMH_VREG("ldo16", "ldo%s16", &pmic4_pldo, "vdd-l16-l28"),
675 RPMH_VREG("ldo17", "ldo%s17", &pmic4_nldo, "vdd-l2-l8-l17"),
676 RPMH_VREG("ldo18", "ldo%s18", &pmic4_pldo, "vdd-l18-l22"),
677 RPMH_VREG("ldo19", "ldo%s19", &pmic4_pldo, "vdd-l13-l19-l21"),
678 RPMH_VREG("ldo20", "ldo%s20", &pmic4_pldo, "vdd-l20-l24"),
679 RPMH_VREG("ldo21", "ldo%s21", &pmic4_pldo, "vdd-l13-l19-l21"),
680 RPMH_VREG("ldo22", "ldo%s22", &pmic4_pldo, "vdd-l18-l22"),
681 RPMH_VREG("ldo23", "ldo%s23", &pmic4_pldo, "vdd-l10-l23-l25"),
682 RPMH_VREG("ldo24", "ldo%s24", &pmic4_pldo, "vdd-l20-l24"),
683 RPMH_VREG("ldo25", "ldo%s25", &pmic4_pldo, "vdd-l10-l23-l25"),
684 RPMH_VREG("ldo26", "ldo%s26", &pmic4_nldo, "vdd-l26"),
685 RPMH_VREG("ldo27", "ldo%s27", &pmic4_nldo, "vdd-l1-l27"),
686 RPMH_VREG("ldo28", "ldo%s28", &pmic4_pldo, "vdd-l16-l28"),
687 RPMH_VREG("lvs1", "vs%s1", &pmic4_lvs, "vin-lvs-1-2"),
688 RPMH_VREG("lvs2", "vs%s2", &pmic4_lvs, "vin-lvs-1-2"),
689 {},
690};
691
692static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
693 RPMH_VREG("bob", "bob%s1", &pmic4_bob, "vdd-bob"),
694 {},
695};
696
697static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
698 RPMH_VREG("smps1", "smp%s1", &pmic4_ftsmps426, "vdd-s1"),
699 RPMH_VREG("smps2", "smp%s2", &pmic4_ftsmps426, "vdd-s2"),
700 RPMH_VREG("smps3", "smp%s3", &pmic4_ftsmps426, "vdd-s3"),
701 RPMH_VREG("smps4", "smp%s4", &pmic4_ftsmps426, "vdd-s4"),
702 {},
703};
704
705static int rpmh_regulator_probe(struct platform_device *pdev)
706{
707 struct device *dev = &pdev->dev;
708 const struct rpmh_vreg_init_data *vreg_data;
709 struct device_node *node;
710 struct rpmh_vreg *vreg;
711 const char *pmic_id;
712 int ret;
713
714 vreg_data = of_device_get_match_data(dev);
715 if (!vreg_data)
716 return -ENODEV;
717
718 ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
719 if (ret < 0) {
720 dev_err(dev, "qcom,pmic-id missing in DT node\n");
721 return ret;
722 }
723
724 for_each_available_child_of_node(dev->of_node, node) {
725 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
726 if (!vreg) {
727 of_node_put(node);
728 return -ENOMEM;
729 }
730
731 ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
732 vreg_data);
733 if (ret < 0) {
734 of_node_put(node);
735 return ret;
736 }
737 }
738
739 return 0;
740}
741
742static const struct of_device_id rpmh_regulator_match_table[] = {
743 {
744 .compatible = "qcom,pm8998-rpmh-regulators",
745 .data = pm8998_vreg_data,
746 },
747 {
748 .compatible = "qcom,pmi8998-rpmh-regulators",
749 .data = pmi8998_vreg_data,
750 },
751 {
752 .compatible = "qcom,pm8005-rpmh-regulators",
753 .data = pm8005_vreg_data,
754 },
755 {}
756};
757MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
758
759static struct platform_driver rpmh_regulator_driver = {
760 .driver = {
761 .name = "qcom-rpmh-regulator",
762 .of_match_table = of_match_ptr(rpmh_regulator_match_table),
763 },
764 .probe = rpmh_regulator_probe,
765};
766module_platform_driver(rpmh_regulator_driver);
767
768MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
769MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c
index 9817f1a75342..53a61fb65642 100644
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -1060,7 +1060,7 @@ static irqreturn_t spmi_regulator_vs_ocp_isr(int irq, void *data)
1060#define SAW3_AVS_CTL_TGGL_MASK 0x8000000 1060#define SAW3_AVS_CTL_TGGL_MASK 0x8000000
1061#define SAW3_AVS_CTL_CLEAR_MASK 0x7efc00 1061#define SAW3_AVS_CTL_CLEAR_MASK 0x7efc00
1062 1062
1063static struct regmap *saw_regmap = NULL; 1063static struct regmap *saw_regmap;
1064 1064
1065static void spmi_saw_set_vdd(void *data) 1065static void spmi_saw_set_vdd(void *data)
1066{ 1066{
@@ -1728,7 +1728,7 @@ static const struct spmi_regulator_data pmi8994_regulators[] = {
1728 { "s2", 0x1700, "vdd_s2", }, 1728 { "s2", 0x1700, "vdd_s2", },
1729 { "s3", 0x1a00, "vdd_s3", }, 1729 { "s3", 0x1a00, "vdd_s3", },
1730 { "l1", 0x4000, "vdd_l1", }, 1730 { "l1", 0x4000, "vdd_l1", },
1731 { } 1731 { }
1732}; 1732};
1733 1733
1734static const struct of_device_id qcom_spmi_regulator_match[] = { 1734static const struct of_device_id qcom_spmi_regulator_match[] = {
@@ -1752,7 +1752,8 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
1752 const char *name; 1752 const char *name;
1753 struct device *dev = &pdev->dev; 1753 struct device *dev = &pdev->dev;
1754 struct device_node *node = pdev->dev.of_node; 1754 struct device_node *node = pdev->dev.of_node;
1755 struct device_node *syscon; 1755 struct device_node *syscon, *reg_node;
1756 struct property *reg_prop;
1756 int ret, lenp; 1757 int ret, lenp;
1757 struct list_head *vreg_list; 1758 struct list_head *vreg_list;
1758 1759
@@ -1774,16 +1775,19 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
1774 syscon = of_parse_phandle(node, "qcom,saw-reg", 0); 1775 syscon = of_parse_phandle(node, "qcom,saw-reg", 0);
1775 saw_regmap = syscon_node_to_regmap(syscon); 1776 saw_regmap = syscon_node_to_regmap(syscon);
1776 of_node_put(syscon); 1777 of_node_put(syscon);
1777 if (IS_ERR(regmap)) 1778 if (IS_ERR(saw_regmap))
1778 dev_err(dev, "ERROR reading SAW regmap\n"); 1779 dev_err(dev, "ERROR reading SAW regmap\n");
1779 } 1780 }
1780 1781
1781 for (reg = match->data; reg->name; reg++) { 1782 for (reg = match->data; reg->name; reg++) {
1782 1783
1783 if (saw_regmap && \ 1784 if (saw_regmap) {
1784 of_find_property(of_find_node_by_name(node, reg->name), \ 1785 reg_node = of_get_child_by_name(node, reg->name);
1785 "qcom,saw-slave", &lenp)) { 1786 reg_prop = of_find_property(reg_node, "qcom,saw-slave",
1786 continue; 1787 &lenp);
1788 of_node_put(reg_node);
1789 if (reg_prop)
1790 continue;
1787 } 1791 }
1788 1792
1789 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); 1793 vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
@@ -1816,13 +1820,17 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)
1816 if (ret) 1820 if (ret)
1817 continue; 1821 continue;
1818 1822
1819 if (saw_regmap && \ 1823 if (saw_regmap) {
1820 of_find_property(of_find_node_by_name(node, reg->name), \ 1824 reg_node = of_get_child_by_name(node, reg->name);
1821 "qcom,saw-leader", &lenp)) { 1825 reg_prop = of_find_property(reg_node, "qcom,saw-leader",
1822 spmi_saw_ops = *(vreg->desc.ops); 1826 &lenp);
1823 spmi_saw_ops.set_voltage_sel = \ 1827 of_node_put(reg_node);
1824 spmi_regulator_saw_set_voltage; 1828 if (reg_prop) {
1825 vreg->desc.ops = &spmi_saw_ops; 1829 spmi_saw_ops = *(vreg->desc.ops);
1830 spmi_saw_ops.set_voltage_sel =
1831 spmi_regulator_saw_set_voltage;
1832 vreg->desc.ops = &spmi_saw_ops;
1833 }
1826 } 1834 }
1827 1835
1828 config.dev = dev; 1836 config.dev = dev;
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c
index 48f0ca90743c..095d25f3d2ea 100644
--- a/drivers/regulator/s2mpa01.c
+++ b/drivers/regulator/s2mpa01.c
@@ -1,13 +1,7 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * Copyright (c) 2013 Samsung Electronics Co., Ltd 2//
3 * http://www.samsung.com 3// Copyright (c) 2013 Samsung Electronics Co., Ltd
4 * 4// http://www.samsung.com
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11 5
12#include <linux/bug.h> 6#include <linux/bug.h>
13#include <linux/err.h> 7#include <linux/err.h>
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index d1207ec683db..5bb6f4ca48db 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -1,20 +1,7 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * s2mps11.c 2//
3 * 3// Copyright (c) 2012-2014 Samsung Electronics Co., Ltd
4 * Copyright (c) 2012-2014 Samsung Electronics Co., Ltd 4// http://www.samsung.com
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18 5
19#include <linux/bug.h> 6#include <linux/bug.h>
20#include <linux/err.h> 7#include <linux/err.h>
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index 0cbc980753c2..667d16dc83ce 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -1,15 +1,7 @@
1/* 1// SPDX-License-Identifier: GPL-2.0+
2 * s5m8767.c 2//
3 * 3// Copyright (c) 2011 Samsung Electronics Co., Ltd
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd 4// http://www.samsung.com
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13 5
14#include <linux/err.h> 6#include <linux/err.h>
15#include <linux/of_gpio.h> 7#include <linux/of_gpio.h>
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c
index fc12badf3805..d84fab616abf 100644
--- a/drivers/regulator/tps65217-regulator.c
+++ b/drivers/regulator/tps65217-regulator.c
@@ -232,6 +232,8 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
232 tps->strobes = devm_kcalloc(&pdev->dev, 232 tps->strobes = devm_kcalloc(&pdev->dev,
233 TPS65217_NUM_REGULATOR, sizeof(u8), 233 TPS65217_NUM_REGULATOR, sizeof(u8),
234 GFP_KERNEL); 234 GFP_KERNEL);
235 if (!tps->strobes)
236 return -ENOMEM;
235 237
236 platform_set_drvdata(pdev, tps); 238 platform_set_drvdata(pdev, tps);
237 239
diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c
new file mode 100644
index 000000000000..abf22acbd13e
--- /dev/null
+++ b/drivers/regulator/uniphier-regulator.c
@@ -0,0 +1,213 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// Regulator controller driver for UniPhier SoC
4// Copyright 2018 Socionext Inc.
5// Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
6
7#include <linux/clk.h>
8#include <linux/io.h>
9#include <linux/module.h>
10#include <linux/of_device.h>
11#include <linux/platform_device.h>
12#include <linux/regmap.h>
13#include <linux/regulator/driver.h>
14#include <linux/regulator/of_regulator.h>
15#include <linux/reset.h>
16
17#define MAX_CLKS 2
18#define MAX_RSTS 2
19
20struct uniphier_regulator_soc_data {
21 int nclks;
22 const char * const *clock_names;
23 int nrsts;
24 const char * const *reset_names;
25 const struct regulator_desc *desc;
26 const struct regmap_config *regconf;
27};
28
29struct uniphier_regulator_priv {
30 struct clk_bulk_data clk[MAX_CLKS];
31 struct reset_control *rst[MAX_RSTS];
32 const struct uniphier_regulator_soc_data *data;
33};
34
35static struct regulator_ops uniphier_regulator_ops = {
36 .enable = regulator_enable_regmap,
37 .disable = regulator_disable_regmap,
38 .is_enabled = regulator_is_enabled_regmap,
39};
40
41static int uniphier_regulator_probe(struct platform_device *pdev)
42{
43 struct device *dev = &pdev->dev;
44 struct uniphier_regulator_priv *priv;
45 struct regulator_config config = { };
46 struct regulator_dev *rdev;
47 struct regmap *regmap;
48 struct resource *res;
49 void __iomem *base;
50 const char *name;
51 int i, ret, nr;
52
53 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
54 if (!priv)
55 return -ENOMEM;
56
57 priv->data = of_device_get_match_data(dev);
58 if (WARN_ON(!priv->data))
59 return -EINVAL;
60
61 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
62 base = devm_ioremap_resource(dev, res);
63 if (IS_ERR(base))
64 return PTR_ERR(base);
65
66 for (i = 0; i < priv->data->nclks; i++)
67 priv->clk[i].id = priv->data->clock_names[i];
68 ret = devm_clk_bulk_get(dev, priv->data->nclks, priv->clk);
69 if (ret)
70 return ret;
71
72 for (i = 0; i < priv->data->nrsts; i++) {
73 name = priv->data->reset_names[i];
74 priv->rst[i] = devm_reset_control_get_shared(dev, name);
75 if (IS_ERR(priv->rst[i]))
76 return PTR_ERR(priv->rst[i]);
77 }
78
79 ret = clk_bulk_prepare_enable(priv->data->nclks, priv->clk);
80 if (ret)
81 return ret;
82
83 for (nr = 0; nr < priv->data->nrsts; nr++) {
84 ret = reset_control_deassert(priv->rst[nr]);
85 if (ret)
86 goto out_rst_assert;
87 }
88
89 regmap = devm_regmap_init_mmio(dev, base, priv->data->regconf);
90 if (IS_ERR(regmap))
91 return PTR_ERR(regmap);
92
93 config.dev = dev;
94 config.driver_data = priv;
95 config.of_node = dev->of_node;
96 config.regmap = regmap;
97 config.init_data = of_get_regulator_init_data(dev, dev->of_node,
98 priv->data->desc);
99 rdev = devm_regulator_register(dev, priv->data->desc, &config);
100 if (IS_ERR(rdev)) {
101 ret = PTR_ERR(rdev);
102 goto out_rst_assert;
103 }
104
105 platform_set_drvdata(pdev, priv);
106
107 return 0;
108
109out_rst_assert:
110 while (nr--)
111 reset_control_assert(priv->rst[nr]);
112
113 clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
114
115 return ret;
116}
117
118static int uniphier_regulator_remove(struct platform_device *pdev)
119{
120 struct uniphier_regulator_priv *priv = platform_get_drvdata(pdev);
121 int i;
122
123 for (i = 0; i < priv->data->nrsts; i++)
124 reset_control_assert(priv->rst[i]);
125
126 clk_bulk_disable_unprepare(priv->data->nclks, priv->clk);
127
128 return 0;
129}
130
131/* USB3 controller data */
132#define USB3VBUS_OFFSET 0x0
133#define USB3VBUS_REG BIT(4)
134#define USB3VBUS_REG_EN BIT(3)
135static const struct regulator_desc uniphier_usb3_regulator_desc = {
136 .name = "vbus",
137 .of_match = of_match_ptr("vbus"),
138 .ops = &uniphier_regulator_ops,
139 .type = REGULATOR_VOLTAGE,
140 .owner = THIS_MODULE,
141 .enable_reg = USB3VBUS_OFFSET,
142 .enable_mask = USB3VBUS_REG_EN | USB3VBUS_REG,
143 .enable_val = USB3VBUS_REG_EN | USB3VBUS_REG,
144 .disable_val = USB3VBUS_REG_EN,
145};
146
147static const struct regmap_config uniphier_usb3_regulator_regconf = {
148 .reg_bits = 32,
149 .val_bits = 32,
150 .reg_stride = 4,
151 .max_register = 1,
152};
153
154static const char * const uniphier_pro4_clock_reset_names[] = {
155 "gio", "link",
156};
157
158static const struct uniphier_regulator_soc_data uniphier_pro4_usb3_data = {
159 .nclks = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
160 .clock_names = uniphier_pro4_clock_reset_names,
161 .nrsts = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
162 .reset_names = uniphier_pro4_clock_reset_names,
163 .desc = &uniphier_usb3_regulator_desc,
164 .regconf = &uniphier_usb3_regulator_regconf,
165};
166
167static const char * const uniphier_pxs2_clock_reset_names[] = {
168 "link",
169};
170
171static const struct uniphier_regulator_soc_data uniphier_pxs2_usb3_data = {
172 .nclks = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
173 .clock_names = uniphier_pxs2_clock_reset_names,
174 .nrsts = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
175 .reset_names = uniphier_pxs2_clock_reset_names,
176 .desc = &uniphier_usb3_regulator_desc,
177 .regconf = &uniphier_usb3_regulator_regconf,
178};
179
180static const struct of_device_id uniphier_regulator_match[] = {
181 /* USB VBUS */
182 {
183 .compatible = "socionext,uniphier-pro4-usb3-regulator",
184 .data = &uniphier_pro4_usb3_data,
185 },
186 {
187 .compatible = "socionext,uniphier-pxs2-usb3-regulator",
188 .data = &uniphier_pxs2_usb3_data,
189 },
190 {
191 .compatible = "socionext,uniphier-ld20-usb3-regulator",
192 .data = &uniphier_pxs2_usb3_data,
193 },
194 {
195 .compatible = "socionext,uniphier-pxs3-usb3-regulator",
196 .data = &uniphier_pxs2_usb3_data,
197 },
198 { /* Sentinel */ },
199};
200
201static struct platform_driver uniphier_regulator_driver = {
202 .probe = uniphier_regulator_probe,
203 .remove = uniphier_regulator_remove,
204 .driver = {
205 .name = "uniphier-regulator",
206 .of_match_table = uniphier_regulator_match,
207 },
208};
209module_platform_driver(uniphier_regulator_driver);
210
211MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
212MODULE_DESCRIPTION("UniPhier Regulator Controller Driver");
213MODULE_LICENSE("GPL");