aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mfd/bcm590xx.txt4
-rw-r--r--drivers/mfd/arizona-core.c41
-rw-r--r--drivers/mfd/bcm590xx.c60
-rw-r--r--drivers/mfd/tps65090.c41
-rw-r--r--drivers/power/tps65090-charger.c11
-rw-r--r--drivers/regulator/Kconfig7
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/arizona-ldo1.c58
-rw-r--r--drivers/regulator/arizona-micsupp.c38
-rw-r--r--drivers/regulator/axp20x-regulator.c286
-rw-r--r--drivers/regulator/bcm590xx-regulator.c92
-rw-r--r--include/linux/mfd/arizona/core.h3
-rw-r--r--include/linux/mfd/bcm590xx.h9
-rw-r--r--include/linux/mfd/tps65090.h14
14 files changed, 593 insertions, 72 deletions
diff --git a/Documentation/devicetree/bindings/mfd/bcm590xx.txt b/Documentation/devicetree/bindings/mfd/bcm590xx.txt
index 1fe30e2b10da..be51a15e05f9 100644
--- a/Documentation/devicetree/bindings/mfd/bcm590xx.txt
+++ b/Documentation/devicetree/bindings/mfd/bcm590xx.txt
@@ -19,7 +19,9 @@ Optional child nodes:
19 The valid regulator node names for BCM59056 are: 19 The valid regulator node names for BCM59056 are:
20 rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo, 20 rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo,
21 mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo, 21 mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo,
22 csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr 22 csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr,
23 gpldo1, gpldo2, gpldo3, gpldo4, gpldo5, gpldo6,
24 vbus
23 25
24Example: 26Example:
25 pmu: bcm59056@8 { 27 pmu: bcm59056@8 {
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1c3ae57082ed..07e6e27be23c 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -508,19 +508,31 @@ int arizona_of_get_type(struct device *dev)
508} 508}
509EXPORT_SYMBOL_GPL(arizona_of_get_type); 509EXPORT_SYMBOL_GPL(arizona_of_get_type);
510 510
511int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
512 bool mandatory)
513{
514 int gpio;
515
516 gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
517 if (gpio < 0) {
518 if (mandatory)
519 dev_err(arizona->dev,
520 "Mandatory DT gpio %s missing/malformed: %d\n",
521 prop, gpio);
522
523 gpio = 0;
524 }
525
526 return gpio;
527}
528EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
529
511static int arizona_of_get_core_pdata(struct arizona *arizona) 530static int arizona_of_get_core_pdata(struct arizona *arizona)
512{ 531{
532 struct arizona_pdata *pdata = &arizona->pdata;
513 int ret, i; 533 int ret, i;
514 534
515 arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node, 535 pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
516 "wlf,reset", 0);
517 if (arizona->pdata.reset < 0)
518 arizona->pdata.reset = 0;
519
520 arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
521 "wlf,ldoena", 0);
522 if (arizona->pdata.ldoena < 0)
523 arizona->pdata.ldoena = 0;
524 536
525 ret = of_property_read_u32_array(arizona->dev->of_node, 537 ret = of_property_read_u32_array(arizona->dev->of_node,
526 "wlf,gpio-defaults", 538 "wlf,gpio-defaults",
@@ -652,6 +664,9 @@ int arizona_dev_init(struct arizona *arizona)
652 return -EINVAL; 664 return -EINVAL;
653 } 665 }
654 666
667 /* Mark DCVDD as external, LDO1 driver will clear if internal */
668 arizona->external_dcvdd = true;
669
655 ret = mfd_add_devices(arizona->dev, -1, early_devs, 670 ret = mfd_add_devices(arizona->dev, -1, early_devs,
656 ARRAY_SIZE(early_devs), NULL, 0, NULL); 671 ARRAY_SIZE(early_devs), NULL, 0, NULL);
657 if (ret != 0) { 672 if (ret != 0) {
@@ -851,14 +866,6 @@ int arizona_dev_init(struct arizona *arizona)
851 arizona->pdata.gpio_defaults[i]); 866 arizona->pdata.gpio_defaults[i]);
852 } 867 }
853 868
854 /*
855 * LDO1 can only be used to supply DCVDD so if it has no
856 * consumers then DCVDD is supplied externally.
857 */
858 if (arizona->pdata.ldo1 &&
859 arizona->pdata.ldo1->num_consumer_supplies == 0)
860 arizona->external_dcvdd = true;
861
862 pm_runtime_set_autosuspend_delay(arizona->dev, 100); 869 pm_runtime_set_autosuspend_delay(arizona->dev, 100);
863 pm_runtime_use_autosuspend(arizona->dev); 870 pm_runtime_use_autosuspend(arizona->dev);
864 pm_runtime_enable(arizona->dev); 871 pm_runtime_enable(arizona->dev);
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
index e9a33c79431b..43cba1a1973c 100644
--- a/drivers/mfd/bcm590xx.c
+++ b/drivers/mfd/bcm590xx.c
@@ -28,39 +28,71 @@ static const struct mfd_cell bcm590xx_devs[] = {
28 }, 28 },
29}; 29};
30 30
31static const struct regmap_config bcm590xx_regmap_config = { 31static const struct regmap_config bcm590xx_regmap_config_pri = {
32 .reg_bits = 8, 32 .reg_bits = 8,
33 .val_bits = 8, 33 .val_bits = 8,
34 .max_register = BCM590XX_MAX_REGISTER, 34 .max_register = BCM590XX_MAX_REGISTER_PRI,
35 .cache_type = REGCACHE_RBTREE, 35 .cache_type = REGCACHE_RBTREE,
36}; 36};
37 37
38static int bcm590xx_i2c_probe(struct i2c_client *i2c, 38static const struct regmap_config bcm590xx_regmap_config_sec = {
39 .reg_bits = 8,
40 .val_bits = 8,
41 .max_register = BCM590XX_MAX_REGISTER_SEC,
42 .cache_type = REGCACHE_RBTREE,
43};
44
45static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
39 const struct i2c_device_id *id) 46 const struct i2c_device_id *id)
40{ 47{
41 struct bcm590xx *bcm590xx; 48 struct bcm590xx *bcm590xx;
42 int ret; 49 int ret;
43 50
44 bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL); 51 bcm590xx = devm_kzalloc(&i2c_pri->dev, sizeof(*bcm590xx), GFP_KERNEL);
45 if (!bcm590xx) 52 if (!bcm590xx)
46 return -ENOMEM; 53 return -ENOMEM;
47 54
48 i2c_set_clientdata(i2c, bcm590xx); 55 i2c_set_clientdata(i2c_pri, bcm590xx);
49 bcm590xx->dev = &i2c->dev; 56 bcm590xx->dev = &i2c_pri->dev;
50 bcm590xx->i2c_client = i2c; 57 bcm590xx->i2c_pri = i2c_pri;
51 58
52 bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config); 59 bcm590xx->regmap_pri = devm_regmap_init_i2c(i2c_pri,
53 if (IS_ERR(bcm590xx->regmap)) { 60 &bcm590xx_regmap_config_pri);
54 ret = PTR_ERR(bcm590xx->regmap); 61 if (IS_ERR(bcm590xx->regmap_pri)) {
55 dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); 62 ret = PTR_ERR(bcm590xx->regmap_pri);
63 dev_err(&i2c_pri->dev, "primary regmap init failed: %d\n", ret);
56 return ret; 64 return ret;
57 } 65 }
58 66
59 ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs, 67 /* Secondary I2C slave address is the base address with A(2) asserted */
68 bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter,
69 i2c_pri->addr | BIT(2));
70 if (IS_ERR_OR_NULL(bcm590xx->i2c_sec)) {
71 dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n");
72 return -ENODEV;
73 }
74 i2c_set_clientdata(bcm590xx->i2c_sec, bcm590xx);
75
76 bcm590xx->regmap_sec = devm_regmap_init_i2c(bcm590xx->i2c_sec,
77 &bcm590xx_regmap_config_sec);
78 if (IS_ERR(bcm590xx->regmap_sec)) {
79 ret = PTR_ERR(bcm590xx->regmap_sec);
80 dev_err(&bcm590xx->i2c_sec->dev,
81 "secondary regmap init failed: %d\n", ret);
82 goto err;
83 }
84
85 ret = mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
60 ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL); 86 ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
61 if (ret < 0) 87 if (ret < 0) {
62 dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret); 88 dev_err(&i2c_pri->dev, "failed to add sub-devices: %d\n", ret);
89 goto err;
90 }
91
92 return 0;
63 93
94err:
95 i2c_unregister_device(bcm590xx->i2c_sec);
64 return ret; 96 return ret;
65} 97}
66 98
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index ba1a25d758c1..1c3e6e2efe41 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -32,14 +32,6 @@
32#define NUM_INT_REG 2 32#define NUM_INT_REG 2
33#define TOTAL_NUM_REG 0x18 33#define TOTAL_NUM_REG 0x18
34 34
35/* interrupt status registers */
36#define TPS65090_INT_STS 0x0
37#define TPS65090_INT_STS2 0x1
38
39/* interrupt mask registers */
40#define TPS65090_INT_MSK 0x2
41#define TPS65090_INT_MSK2 0x3
42
43#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1 35#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1
44#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2 36#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2
45#define TPS65090_INT1_MASK_BAT_STATUS_CHANGE 3 37#define TPS65090_INT1_MASK_BAT_STATUS_CHANGE 3
@@ -64,11 +56,16 @@ static struct resource charger_resources[] = {
64 } 56 }
65}; 57};
66 58
67static const struct mfd_cell tps65090s[] = { 59enum tps65090_cells {
68 { 60 PMIC = 0,
61 CHARGER = 1,
62};
63
64static struct mfd_cell tps65090s[] = {
65 [PMIC] = {
69 .name = "tps65090-pmic", 66 .name = "tps65090-pmic",
70 }, 67 },
71 { 68 [CHARGER] = {
72 .name = "tps65090-charger", 69 .name = "tps65090-charger",
73 .num_resources = ARRAY_SIZE(charger_resources), 70 .num_resources = ARRAY_SIZE(charger_resources),
74 .resources = &charger_resources[0], 71 .resources = &charger_resources[0],
@@ -139,17 +136,26 @@ static struct regmap_irq_chip tps65090_irq_chip = {
139 .irqs = tps65090_irqs, 136 .irqs = tps65090_irqs,
140 .num_irqs = ARRAY_SIZE(tps65090_irqs), 137 .num_irqs = ARRAY_SIZE(tps65090_irqs),
141 .num_regs = NUM_INT_REG, 138 .num_regs = NUM_INT_REG,
142 .status_base = TPS65090_INT_STS, 139 .status_base = TPS65090_REG_INTR_STS,
143 .mask_base = TPS65090_INT_MSK, 140 .mask_base = TPS65090_REG_INTR_MASK,
144 .mask_invert = true, 141 .mask_invert = true,
145}; 142};
146 143
147static bool is_volatile_reg(struct device *dev, unsigned int reg) 144static bool is_volatile_reg(struct device *dev, unsigned int reg)
148{ 145{
149 if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS2)) 146 /* Nearly all registers have status bits mixed in, except a few */
150 return true; 147 switch (reg) {
151 else 148 case TPS65090_REG_INTR_MASK:
149 case TPS65090_REG_INTR_MASK2:
150 case TPS65090_REG_CG_CTRL0:
151 case TPS65090_REG_CG_CTRL1:
152 case TPS65090_REG_CG_CTRL2:
153 case TPS65090_REG_CG_CTRL3:
154 case TPS65090_REG_CG_CTRL4:
155 case TPS65090_REG_CG_CTRL5:
152 return false; 156 return false;
157 }
158 return true;
153} 159}
154 160
155static const struct regmap_config tps65090_regmap_config = { 161static const struct regmap_config tps65090_regmap_config = {
@@ -211,6 +217,9 @@ static int tps65090_i2c_probe(struct i2c_client *client,
211 "IRQ init failed with err: %d\n", ret); 217 "IRQ init failed with err: %d\n", ret);
212 return ret; 218 return ret;
213 } 219 }
220 } else {
221 /* Don't tell children they have an IRQ that'll never fire */
222 tps65090s[CHARGER].num_resources = 0;
214 } 223 }
215 224
216 ret = mfd_add_devices(tps65090->dev, -1, tps65090s, 225 ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c
index 8fc9d6df87f6..1685f63b9e5d 100644
--- a/drivers/power/tps65090-charger.c
+++ b/drivers/power/tps65090-charger.c
@@ -28,17 +28,6 @@
28 28
29#include <linux/mfd/tps65090.h> 29#include <linux/mfd/tps65090.h>
30 30
31#define TPS65090_REG_INTR_STS 0x00
32#define TPS65090_REG_INTR_MASK 0x02
33#define TPS65090_REG_CG_CTRL0 0x04
34#define TPS65090_REG_CG_CTRL1 0x05
35#define TPS65090_REG_CG_CTRL2 0x06
36#define TPS65090_REG_CG_CTRL3 0x07
37#define TPS65090_REG_CG_CTRL4 0x08
38#define TPS65090_REG_CG_CTRL5 0x09
39#define TPS65090_REG_CG_STATUS1 0x0a
40#define TPS65090_REG_CG_STATUS2 0x0b
41
42#define TPS65090_CHARGER_ENABLE BIT(0) 31#define TPS65090_CHARGER_ENABLE BIT(0)
43#define TPS65090_VACG BIT(1) 32#define TPS65090_VACG BIT(1)
44#define TPS65090_NOITERM BIT(5) 33#define TPS65090_NOITERM BIT(5)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 903eb37f047a..65e5d7d1b35a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -139,6 +139,13 @@ config REGULATOR_AS3722
139 AS3722 PMIC. This will enable support for all the software 139 AS3722 PMIC. This will enable support for all the software
140 controllable DCDC/LDO regulators. 140 controllable DCDC/LDO regulators.
141 141
142config REGULATOR_AXP20X
143 tristate "X-POWERS AXP20X PMIC Regulators"
144 depends on MFD_AXP20X
145 help
146 This driver provides support for the voltage regulators on the
147 AXP20X PMIC.
148
142config REGULATOR_BCM590XX 149config REGULATOR_BCM590XX
143 tristate "Broadcom BCM590xx PMU Regulators" 150 tristate "Broadcom BCM590xx PMU Regulators"
144 depends on MFD_BCM590XX 151 depends on MFD_BCM590XX
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 12ef277a48b4..c14696b290c0 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
20obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o 20obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
21obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o 21obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
22obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o 22obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
23obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
23obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o 24obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
24obj-$(CONFIG_REGULATOR_DA903X) += da903x.o 25obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
25obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o 26obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index b1033d30b504..04f262a836b2 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -16,9 +16,11 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/bitops.h> 17#include <linux/bitops.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/of.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/regulator/driver.h> 21#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h> 22#include <linux/regulator/machine.h>
23#include <linux/regulator/of_regulator.h>
22#include <linux/gpio.h> 24#include <linux/gpio.h>
23#include <linux/slab.h> 25#include <linux/slab.h>
24 26
@@ -178,6 +180,42 @@ static const struct regulator_init_data arizona_ldo1_default = {
178 .num_consumer_supplies = 1, 180 .num_consumer_supplies = 1,
179}; 181};
180 182
183static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
184 struct regulator_config *config)
185{
186 struct arizona_pdata *pdata = &arizona->pdata;
187 struct arizona_ldo1 *ldo1 = config->driver_data;
188 struct device_node *init_node, *dcvdd_node;
189 struct regulator_init_data *init_data;
190
191 pdata->ldoena = arizona_of_get_named_gpio(arizona, "wlf,ldoena", true);
192
193 init_node = of_get_child_by_name(arizona->dev->of_node, "ldo1");
194 dcvdd_node = of_parse_phandle(arizona->dev->of_node, "DCVDD-supply", 0);
195
196 if (init_node) {
197 config->of_node = init_node;
198
199 init_data = of_get_regulator_init_data(arizona->dev, init_node);
200
201 if (init_data) {
202 init_data->consumer_supplies = &ldo1->supply;
203 init_data->num_consumer_supplies = 1;
204
205 if (dcvdd_node && dcvdd_node != init_node)
206 arizona->external_dcvdd = true;
207
208 pdata->ldo1 = init_data;
209 }
210 } else if (dcvdd_node) {
211 arizona->external_dcvdd = true;
212 }
213
214 of_node_put(dcvdd_node);
215
216 return 0;
217}
218
181static int arizona_ldo1_probe(struct platform_device *pdev) 219static int arizona_ldo1_probe(struct platform_device *pdev)
182{ 220{
183 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 221 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
@@ -186,6 +224,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
186 struct arizona_ldo1 *ldo1; 224 struct arizona_ldo1 *ldo1;
187 int ret; 225 int ret;
188 226
227 arizona->external_dcvdd = false;
228
189 ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); 229 ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
190 if (!ldo1) 230 if (!ldo1)
191 return -ENOMEM; 231 return -ENOMEM;
@@ -216,6 +256,15 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
216 config.dev = arizona->dev; 256 config.dev = arizona->dev;
217 config.driver_data = ldo1; 257 config.driver_data = ldo1;
218 config.regmap = arizona->regmap; 258 config.regmap = arizona->regmap;
259
260 if (IS_ENABLED(CONFIG_OF)) {
261 if (!dev_get_platdata(arizona->dev)) {
262 ret = arizona_ldo1_of_get_pdata(arizona, &config);
263 if (ret < 0)
264 return ret;
265 }
266 }
267
219 config.ena_gpio = arizona->pdata.ldoena; 268 config.ena_gpio = arizona->pdata.ldoena;
220 269
221 if (arizona->pdata.ldo1) 270 if (arizona->pdata.ldo1)
@@ -223,6 +272,13 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
223 else 272 else
224 config.init_data = &ldo1->init_data; 273 config.init_data = &ldo1->init_data;
225 274
275 /*
276 * LDO1 can only be used to supply DCVDD so if it has no
277 * consumers then DCVDD is supplied externally.
278 */
279 if (config.init_data->num_consumer_supplies == 0)
280 arizona->external_dcvdd = true;
281
226 ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); 282 ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
227 if (IS_ERR(ldo1->regulator)) { 283 if (IS_ERR(ldo1->regulator)) {
228 ret = PTR_ERR(ldo1->regulator); 284 ret = PTR_ERR(ldo1->regulator);
@@ -231,6 +287,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
231 return ret; 287 return ret;
232 } 288 }
233 289
290 of_node_put(config.of_node);
291
234 platform_set_drvdata(pdev, ldo1); 292 platform_set_drvdata(pdev, ldo1);
235 293
236 return 0; 294 return 0;
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index 6fdd9bf6927f..ce9aca5f8ee7 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -16,9 +16,11 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/bitops.h> 17#include <linux/bitops.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/of.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/regulator/driver.h> 21#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h> 22#include <linux/regulator/machine.h>
23#include <linux/regulator/of_regulator.h>
22#include <linux/gpio.h> 24#include <linux/gpio.h>
23#include <linux/slab.h> 25#include <linux/slab.h>
24#include <linux/workqueue.h> 26#include <linux/workqueue.h>
@@ -195,6 +197,32 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
195 .num_consumer_supplies = 1, 197 .num_consumer_supplies = 1,
196}; 198};
197 199
200static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
201 struct regulator_config *config)
202{
203 struct arizona_pdata *pdata = &arizona->pdata;
204 struct arizona_micsupp *micsupp = config->driver_data;
205 struct device_node *np;
206 struct regulator_init_data *init_data;
207
208 np = of_get_child_by_name(arizona->dev->of_node, "micvdd");
209
210 if (np) {
211 config->of_node = np;
212
213 init_data = of_get_regulator_init_data(arizona->dev, np);
214
215 if (init_data) {
216 init_data->consumer_supplies = &micsupp->supply;
217 init_data->num_consumer_supplies = 1;
218
219 pdata->micvdd = init_data;
220 }
221 }
222
223 return 0;
224}
225
198static int arizona_micsupp_probe(struct platform_device *pdev) 226static int arizona_micsupp_probe(struct platform_device *pdev)
199{ 227{
200 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 228 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
@@ -234,6 +262,14 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
234 config.driver_data = micsupp; 262 config.driver_data = micsupp;
235 config.regmap = arizona->regmap; 263 config.regmap = arizona->regmap;
236 264
265 if (IS_ENABLED(CONFIG_OF)) {
266 if (!dev_get_platdata(arizona->dev)) {
267 ret = arizona_micsupp_of_get_pdata(arizona, &config);
268 if (ret < 0)
269 return ret;
270 }
271 }
272
237 if (arizona->pdata.micvdd) 273 if (arizona->pdata.micvdd)
238 config.init_data = arizona->pdata.micvdd; 274 config.init_data = arizona->pdata.micvdd;
239 else 275 else
@@ -253,6 +289,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
253 return ret; 289 return ret;
254 } 290 }
255 291
292 of_node_put(config.of_node);
293
256 platform_set_drvdata(pdev, micsupp); 294 platform_set_drvdata(pdev, micsupp);
257 295
258 return 0; 296 return 0;
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
new file mode 100644
index 000000000000..004aadb7bcc1
--- /dev/null
+++ b/drivers/regulator/axp20x-regulator.c
@@ -0,0 +1,286 @@
1/*
2 * AXP20x regulators driver.
3 *
4 * Copyright (C) 2013 Carlo Caione <carlo@caione.org>
5 *
6 * This file is subject to the terms and conditions of the GNU General
7 * Public License. See the file "COPYING" in the main directory of this
8 * archive for more details.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/err.h>
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23#include <linux/mfd/axp20x.h>
24#include <linux/regulator/driver.h>
25#include <linux/regulator/of_regulator.h>
26
27#define AXP20X_IO_ENABLED 0x03
28#define AXP20X_IO_DISABLED 0x07
29
30#define AXP20X_WORKMODE_DCDC2_MASK BIT(2)
31#define AXP20X_WORKMODE_DCDC3_MASK BIT(1)
32
33#define AXP20X_FREQ_DCDC_MASK 0x0f
34
35#define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
36 _emask, _enable_val, _disable_val) \
37 [AXP20X_##_id] = { \
38 .name = #_id, \
39 .supply_name = (_supply), \
40 .type = REGULATOR_VOLTAGE, \
41 .id = AXP20X_##_id, \
42 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
43 .owner = THIS_MODULE, \
44 .min_uV = (_min) * 1000, \
45 .uV_step = (_step) * 1000, \
46 .vsel_reg = (_vreg), \
47 .vsel_mask = (_vmask), \
48 .enable_reg = (_ereg), \
49 .enable_mask = (_emask), \
50 .enable_val = (_enable_val), \
51 .disable_val = (_disable_val), \
52 .ops = &axp20x_ops, \
53 }
54
55#define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
56 _emask) \
57 [AXP20X_##_id] = { \
58 .name = #_id, \
59 .supply_name = (_supply), \
60 .type = REGULATOR_VOLTAGE, \
61 .id = AXP20X_##_id, \
62 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
63 .owner = THIS_MODULE, \
64 .min_uV = (_min) * 1000, \
65 .uV_step = (_step) * 1000, \
66 .vsel_reg = (_vreg), \
67 .vsel_mask = (_vmask), \
68 .enable_reg = (_ereg), \
69 .enable_mask = (_emask), \
70 .ops = &axp20x_ops, \
71 }
72
73#define AXP20X_DESC_FIXED(_id, _supply, _volt) \
74 [AXP20X_##_id] = { \
75 .name = #_id, \
76 .supply_name = (_supply), \
77 .type = REGULATOR_VOLTAGE, \
78 .id = AXP20X_##_id, \
79 .n_voltages = 1, \
80 .owner = THIS_MODULE, \
81 .min_uV = (_volt) * 1000, \
82 .ops = &axp20x_ops_fixed \
83 }
84
85#define AXP20X_DESC_TABLE(_id, _supply, _table, _vreg, _vmask, _ereg, _emask) \
86 [AXP20X_##_id] = { \
87 .name = #_id, \
88 .supply_name = (_supply), \
89 .type = REGULATOR_VOLTAGE, \
90 .id = AXP20X_##_id, \
91 .n_voltages = ARRAY_SIZE(_table), \
92 .owner = THIS_MODULE, \
93 .vsel_reg = (_vreg), \
94 .vsel_mask = (_vmask), \
95 .enable_reg = (_ereg), \
96 .enable_mask = (_emask), \
97 .volt_table = (_table), \
98 .ops = &axp20x_ops_table, \
99 }
100
101static const int axp20x_ldo4_data[] = { 1250000, 1300000, 1400000, 1500000, 1600000,
102 1700000, 1800000, 1900000, 2000000, 2500000,
103 2700000, 2800000, 3000000, 3100000, 3200000,
104 3300000 };
105
106static struct regulator_ops axp20x_ops_fixed = {
107 .list_voltage = regulator_list_voltage_linear,
108};
109
110static struct regulator_ops axp20x_ops_table = {
111 .set_voltage_sel = regulator_set_voltage_sel_regmap,
112 .get_voltage_sel = regulator_get_voltage_sel_regmap,
113 .list_voltage = regulator_list_voltage_table,
114 .map_voltage = regulator_map_voltage_ascend,
115 .enable = regulator_enable_regmap,
116 .disable = regulator_disable_regmap,
117 .is_enabled = regulator_is_enabled_regmap,
118};
119
120static struct regulator_ops axp20x_ops = {
121 .set_voltage_sel = regulator_set_voltage_sel_regmap,
122 .get_voltage_sel = regulator_get_voltage_sel_regmap,
123 .list_voltage = regulator_list_voltage_linear,
124 .enable = regulator_enable_regmap,
125 .disable = regulator_disable_regmap,
126 .is_enabled = regulator_is_enabled_regmap,
127};
128
129static const struct regulator_desc axp20x_regulators[] = {
130 AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f,
131 AXP20X_PWR_OUT_CTRL, 0x10),
132 AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f,
133 AXP20X_PWR_OUT_CTRL, 0x02),
134 AXP20X_DESC_FIXED(LDO1, "acin", 1300),
135 AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0,
136 AXP20X_PWR_OUT_CTRL, 0x04),
137 AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f,
138 AXP20X_PWR_OUT_CTRL, 0x40),
139 AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f,
140 AXP20X_PWR_OUT_CTRL, 0x08),
141 AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0,
142 AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED,
143 AXP20X_IO_DISABLED),
144};
145
146#define AXP_MATCH(_name, _id) \
147 [AXP20X_##_id] = { \
148 .name = #_name, \
149 .driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \
150 }
151
152static struct of_regulator_match axp20x_matches[] = {
153 AXP_MATCH(dcdc2, DCDC2),
154 AXP_MATCH(dcdc3, DCDC3),
155 AXP_MATCH(ldo1, LDO1),
156 AXP_MATCH(ldo2, LDO2),
157 AXP_MATCH(ldo3, LDO3),
158 AXP_MATCH(ldo4, LDO4),
159 AXP_MATCH(ldo5, LDO5),
160};
161
162static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
163{
164 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
165
166 if (dcdcfreq < 750) {
167 dcdcfreq = 750;
168 dev_warn(&pdev->dev, "DCDC frequency too low. Set to 750kHz\n");
169 }
170
171 if (dcdcfreq > 1875) {
172 dcdcfreq = 1875;
173 dev_warn(&pdev->dev, "DCDC frequency too high. Set to 1875kHz\n");
174 }
175
176 dcdcfreq = (dcdcfreq - 750) / 75;
177
178 return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
179 AXP20X_FREQ_DCDC_MASK, dcdcfreq);
180}
181
182static int axp20x_regulator_parse_dt(struct platform_device *pdev)
183{
184 struct device_node *np, *regulators;
185 int ret;
186 u32 dcdcfreq;
187
188 np = of_node_get(pdev->dev.parent->of_node);
189 if (!np)
190 return 0;
191
192 regulators = of_get_child_by_name(np, "regulators");
193 if (!regulators) {
194 dev_warn(&pdev->dev, "regulators node not found\n");
195 } else {
196 ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches,
197 ARRAY_SIZE(axp20x_matches));
198 if (ret < 0) {
199 dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
200 return ret;
201 }
202
203 dcdcfreq = 1500;
204 of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
205 ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
206 if (ret < 0) {
207 dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
208 return ret;
209 }
210
211 of_node_put(regulators);
212 }
213
214 return 0;
215}
216
217static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
218{
219 unsigned int mask = AXP20X_WORKMODE_DCDC2_MASK;
220
221 if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
222 return -EINVAL;
223
224 if (id == AXP20X_DCDC3)
225 mask = AXP20X_WORKMODE_DCDC3_MASK;
226
227 workmode <<= ffs(mask) - 1;
228
229 return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
230}
231
232static int axp20x_regulator_probe(struct platform_device *pdev)
233{
234 struct regulator_dev *rdev;
235 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
236 struct regulator_config config = { };
237 struct regulator_init_data *init_data;
238 int ret, i;
239 u32 workmode;
240
241 ret = axp20x_regulator_parse_dt(pdev);
242 if (ret)
243 return ret;
244
245 for (i = 0; i < AXP20X_REG_ID_MAX; i++) {
246 init_data = axp20x_matches[i].init_data;
247
248 config.dev = &pdev->dev;
249 config.init_data = init_data;
250 config.regmap = axp20x->regmap;
251 config.of_node = axp20x_matches[i].of_node;
252
253 rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
254 &config);
255 if (IS_ERR(rdev)) {
256 dev_err(&pdev->dev, "Failed to register %s\n",
257 axp20x_regulators[i].name);
258
259 return PTR_ERR(rdev);
260 }
261
262 ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode",
263 &workmode);
264 if (!ret) {
265 if (axp20x_set_dcdc_workmode(rdev, i, workmode))
266 dev_err(&pdev->dev, "Failed to set workmode on %s\n",
267 axp20x_regulators[i].name);
268 }
269 }
270
271 return 0;
272}
273
274static struct platform_driver axp20x_regulator_driver = {
275 .probe = axp20x_regulator_probe,
276 .driver = {
277 .name = "axp20x-regulator",
278 .owner = THIS_MODULE,
279 },
280};
281
282module_platform_driver(axp20x_regulator_driver);
283
284MODULE_LICENSE("GPL v2");
285MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
286MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c
index c3750c5b382b..57544e254a78 100644
--- a/drivers/regulator/bcm590xx-regulator.c
+++ b/drivers/regulator/bcm590xx-regulator.c
@@ -22,7 +22,7 @@
22#include <linux/regulator/of_regulator.h> 22#include <linux/regulator/of_regulator.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24 24
25/* Register defs */ 25/* I2C slave 0 registers */
26#define BCM590XX_RFLDOPMCTRL1 0x60 26#define BCM590XX_RFLDOPMCTRL1 0x60
27#define BCM590XX_IOSR1PMCTRL1 0x7a 27#define BCM590XX_IOSR1PMCTRL1 0x7a
28#define BCM590XX_IOSR2PMCTRL1 0x7c 28#define BCM590XX_IOSR2PMCTRL1 0x7c
@@ -31,13 +31,34 @@
31#define BCM590XX_SDSR2PMCTRL1 0x86 31#define BCM590XX_SDSR2PMCTRL1 0x86
32#define BCM590XX_MSRPMCTRL1 0x8a 32#define BCM590XX_MSRPMCTRL1 0x8a
33#define BCM590XX_VSRPMCTRL1 0x8e 33#define BCM590XX_VSRPMCTRL1 0x8e
34#define BCM590XX_REG_ENABLE BIT(7)
35
36#define BCM590XX_RFLDOCTRL 0x96 34#define BCM590XX_RFLDOCTRL 0x96
37#define BCM590XX_CSRVOUT1 0xc0 35#define BCM590XX_CSRVOUT1 0xc0
36
37/* I2C slave 1 registers */
38#define BCM590XX_GPLDO5PMCTRL1 0x16
39#define BCM590XX_GPLDO6PMCTRL1 0x18
40#define BCM590XX_GPLDO1CTRL 0x1a
41#define BCM590XX_GPLDO2CTRL 0x1b
42#define BCM590XX_GPLDO3CTRL 0x1c
43#define BCM590XX_GPLDO4CTRL 0x1d
44#define BCM590XX_GPLDO5CTRL 0x1e
45#define BCM590XX_GPLDO6CTRL 0x1f
46#define BCM590XX_OTG_CTRL 0x40
47#define BCM590XX_GPLDO1PMCTRL1 0x57
48#define BCM590XX_GPLDO2PMCTRL1 0x59
49#define BCM590XX_GPLDO3PMCTRL1 0x5b
50#define BCM590XX_GPLDO4PMCTRL1 0x5d
51
52#define BCM590XX_REG_ENABLE BIT(7)
53#define BCM590XX_VBUS_ENABLE BIT(2)
38#define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3) 54#define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3)
39#define BCM590XX_SR_VSEL_MASK GENMASK(5, 0) 55#define BCM590XX_SR_VSEL_MASK GENMASK(5, 0)
40 56
57/*
58 * RFLDO to VSR regulators are
59 * accessed via I2C slave 0
60 */
61
41/* LDO regulator IDs */ 62/* LDO regulator IDs */
42#define BCM590XX_REG_RFLDO 0 63#define BCM590XX_REG_RFLDO 0
43#define BCM590XX_REG_CAMLDO1 1 64#define BCM590XX_REG_CAMLDO1 1
@@ -62,9 +83,25 @@
62#define BCM590XX_REG_SDSR2 18 83#define BCM590XX_REG_SDSR2 18
63#define BCM590XX_REG_VSR 19 84#define BCM590XX_REG_VSR 19
64 85
65#define BCM590XX_NUM_REGS 20 86/*
87 * GPLDO1 to VBUS regulators are
88 * accessed via I2C slave 1
89 */
90
91#define BCM590XX_REG_GPLDO1 20
92#define BCM590XX_REG_GPLDO2 21
93#define BCM590XX_REG_GPLDO3 22
94#define BCM590XX_REG_GPLDO4 23
95#define BCM590XX_REG_GPLDO5 24
96#define BCM590XX_REG_GPLDO6 25
97#define BCM590XX_REG_VBUS 26
98
99#define BCM590XX_NUM_REGS 27
66 100
67#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR) 101#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR)
102#define BCM590XX_REG_IS_GPLDO(n) \
103 ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
104#define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS)
68 105
69struct bcm590xx_board { 106struct bcm590xx_board {
70 struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS]; 107 struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS];
@@ -149,6 +186,12 @@ static struct bcm590xx_info bcm590xx_regs[] = {
149 BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges), 186 BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges),
150 BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges), 187 BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges),
151 BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges), 188 BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges),
189 BCM590XX_REG_TABLE(gpldo1, ldo_a_table),
190 BCM590XX_REG_TABLE(gpldo2, ldo_a_table),
191 BCM590XX_REG_TABLE(gpldo3, ldo_a_table),
192 BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
193 BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
194 BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
152}; 195};
153 196
154struct bcm590xx_reg { 197struct bcm590xx_reg {
@@ -161,6 +204,8 @@ static int bcm590xx_get_vsel_register(int id)
161{ 204{
162 if (BCM590XX_REG_IS_LDO(id)) 205 if (BCM590XX_REG_IS_LDO(id))
163 return BCM590XX_RFLDOCTRL + id; 206 return BCM590XX_RFLDOCTRL + id;
207 else if (BCM590XX_REG_IS_GPLDO(id))
208 return BCM590XX_GPLDO1CTRL + id;
164 else 209 else
165 return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3; 210 return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3;
166} 211}
@@ -171,6 +216,8 @@ static int bcm590xx_get_enable_register(int id)
171 216
172 if (BCM590XX_REG_IS_LDO(id)) 217 if (BCM590XX_REG_IS_LDO(id))
173 reg = BCM590XX_RFLDOPMCTRL1 + id * 2; 218 reg = BCM590XX_RFLDOPMCTRL1 + id * 2;
219 else if (BCM590XX_REG_IS_GPLDO(id))
220 reg = BCM590XX_GPLDO1PMCTRL1 + id * 2;
174 else 221 else
175 switch (id) { 222 switch (id) {
176 case BCM590XX_REG_CSR: 223 case BCM590XX_REG_CSR:
@@ -191,8 +238,11 @@ static int bcm590xx_get_enable_register(int id)
191 case BCM590XX_REG_SDSR2: 238 case BCM590XX_REG_SDSR2:
192 reg = BCM590XX_SDSR2PMCTRL1; 239 reg = BCM590XX_SDSR2PMCTRL1;
193 break; 240 break;
241 case BCM590XX_REG_VBUS:
242 reg = BCM590XX_OTG_CTRL;
194 }; 243 };
195 244
245
196 return reg; 246 return reg;
197} 247}
198 248
@@ -216,6 +266,12 @@ static struct regulator_ops bcm590xx_ops_dcdc = {
216 .map_voltage = regulator_map_voltage_linear_range, 266 .map_voltage = regulator_map_voltage_linear_range,
217}; 267};
218 268
269static struct regulator_ops bcm590xx_ops_vbus = {
270 .is_enabled = regulator_is_enabled_regmap,
271 .enable = regulator_enable_regmap,
272 .disable = regulator_disable_regmap,
273};
274
219#define BCM590XX_MATCH(_name, _id) \ 275#define BCM590XX_MATCH(_name, _id) \
220 { \ 276 { \
221 .name = #_name, \ 277 .name = #_name, \
@@ -243,6 +299,13 @@ static struct of_regulator_match bcm590xx_matches[] = {
243 BCM590XX_MATCH(sdsr1, SDSR1), 299 BCM590XX_MATCH(sdsr1, SDSR1),
244 BCM590XX_MATCH(sdsr2, SDSR2), 300 BCM590XX_MATCH(sdsr2, SDSR2),
245 BCM590XX_MATCH(vsr, VSR), 301 BCM590XX_MATCH(vsr, VSR),
302 BCM590XX_MATCH(gpldo1, GPLDO1),
303 BCM590XX_MATCH(gpldo2, GPLDO2),
304 BCM590XX_MATCH(gpldo3, GPLDO3),
305 BCM590XX_MATCH(gpldo4, GPLDO4),
306 BCM590XX_MATCH(gpldo5, GPLDO5),
307 BCM590XX_MATCH(gpldo6, GPLDO6),
308 BCM590XX_MATCH(vbus, VBUS),
246}; 309};
247 310
248static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( 311static struct bcm590xx_board *bcm590xx_parse_dt_reg_data(
@@ -353,17 +416,23 @@ static int bcm590xx_probe(struct platform_device *pdev)
353 pmu->desc[i].linear_ranges = info->linear_ranges; 416 pmu->desc[i].linear_ranges = info->linear_ranges;
354 pmu->desc[i].n_linear_ranges = info->n_linear_ranges; 417 pmu->desc[i].n_linear_ranges = info->n_linear_ranges;
355 418
356 if (BCM590XX_REG_IS_LDO(i)) { 419 if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) {
357 pmu->desc[i].ops = &bcm590xx_ops_ldo; 420 pmu->desc[i].ops = &bcm590xx_ops_ldo;
358 pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK; 421 pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK;
359 } else { 422 } else if (BCM590XX_REG_IS_VBUS(i))
423 pmu->desc[i].ops = &bcm590xx_ops_vbus;
424 else {
360 pmu->desc[i].ops = &bcm590xx_ops_dcdc; 425 pmu->desc[i].ops = &bcm590xx_ops_dcdc;
361 pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK; 426 pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK;
362 } 427 }
363 428
364 pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i); 429 if (BCM590XX_REG_IS_VBUS(i))
365 pmu->desc[i].enable_is_inverted = true; 430 pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE;
366 pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE; 431 else {
432 pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i);
433 pmu->desc[i].enable_is_inverted = true;
434 pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE;
435 }
367 pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i); 436 pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i);
368 pmu->desc[i].type = REGULATOR_VOLTAGE; 437 pmu->desc[i].type = REGULATOR_VOLTAGE;
369 pmu->desc[i].owner = THIS_MODULE; 438 pmu->desc[i].owner = THIS_MODULE;
@@ -371,7 +440,10 @@ static int bcm590xx_probe(struct platform_device *pdev)
371 config.dev = bcm590xx->dev; 440 config.dev = bcm590xx->dev;
372 config.init_data = reg_data; 441 config.init_data = reg_data;
373 config.driver_data = pmu; 442 config.driver_data = pmu;
374 config.regmap = bcm590xx->regmap; 443 if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
444 config.regmap = bcm590xx->regmap_sec;
445 else
446 config.regmap = bcm590xx->regmap_pri;
375 447
376 if (bcm590xx_reg_matches) 448 if (bcm590xx_reg_matches)
377 config.of_node = bcm590xx_reg_matches[i].of_node; 449 config.of_node = bcm590xx_reg_matches[i].of_node;
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index 5cf8b91ce996..6d9371f88875 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -124,4 +124,7 @@ int wm5102_patch(struct arizona *arizona);
124int wm5110_patch(struct arizona *arizona); 124int wm5110_patch(struct arizona *arizona);
125int wm8997_patch(struct arizona *arizona); 125int wm8997_patch(struct arizona *arizona);
126 126
127extern int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
128 bool mandatory);
129
127#endif 130#endif
diff --git a/include/linux/mfd/bcm590xx.h b/include/linux/mfd/bcm590xx.h
index 434df2d4e587..267aedee1c7a 100644
--- a/include/linux/mfd/bcm590xx.h
+++ b/include/linux/mfd/bcm590xx.h
@@ -19,12 +19,15 @@
19#include <linux/regmap.h> 19#include <linux/regmap.h>
20 20
21/* max register address */ 21/* max register address */
22#define BCM590XX_MAX_REGISTER 0xe7 22#define BCM590XX_MAX_REGISTER_PRI 0xe7
23#define BCM590XX_MAX_REGISTER_SEC 0xf0
23 24
24struct bcm590xx { 25struct bcm590xx {
25 struct device *dev; 26 struct device *dev;
26 struct i2c_client *i2c_client; 27 struct i2c_client *i2c_pri;
27 struct regmap *regmap; 28 struct i2c_client *i2c_sec;
29 struct regmap *regmap_pri;
30 struct regmap *regmap_sec;
28 unsigned int id; 31 unsigned int id;
29}; 32};
30 33
diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h
index 3f43069413e7..45f0f9d2ed25 100644
--- a/include/linux/mfd/tps65090.h
+++ b/include/linux/mfd/tps65090.h
@@ -64,6 +64,20 @@ enum {
64 TPS65090_REGULATOR_MAX, 64 TPS65090_REGULATOR_MAX,
65}; 65};
66 66
67/* Register addresses */
68#define TPS65090_REG_INTR_STS 0x00
69#define TPS65090_REG_INTR_STS2 0x01
70#define TPS65090_REG_INTR_MASK 0x02
71#define TPS65090_REG_INTR_MASK2 0x03
72#define TPS65090_REG_CG_CTRL0 0x04
73#define TPS65090_REG_CG_CTRL1 0x05
74#define TPS65090_REG_CG_CTRL2 0x06
75#define TPS65090_REG_CG_CTRL3 0x07
76#define TPS65090_REG_CG_CTRL4 0x08
77#define TPS65090_REG_CG_CTRL5 0x09
78#define TPS65090_REG_CG_STATUS1 0x0a
79#define TPS65090_REG_CG_STATUS2 0x0b
80
67struct tps65090 { 81struct tps65090 {
68 struct device *dev; 82 struct device *dev;
69 struct regmap *rmap; 83 struct regmap *rmap;