diff options
Diffstat (limited to 'drivers/regulator')
25 files changed, 1509 insertions, 378 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 903eb37f047a..c2fa0b4367b1 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 | ||
142 | config 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 | |||
142 | config REGULATOR_BCM590XX | 149 | config REGULATOR_BCM590XX |
143 | tristate "Broadcom BCM590xx PMU Regulators" | 150 | tristate "Broadcom BCM590xx PMU Regulators" |
144 | depends on MFD_BCM590XX | 151 | depends on MFD_BCM590XX |
@@ -265,6 +272,14 @@ config REGULATOR_LP8788 | |||
265 | help | 272 | help |
266 | This driver supports LP8788 voltage regulator chip. | 273 | This driver supports LP8788 voltage regulator chip. |
267 | 274 | ||
275 | config REGULATOR_LTC3589 | ||
276 | tristate "LTC3589 8-output voltage regulator" | ||
277 | depends on I2C | ||
278 | select REGMAP_I2C | ||
279 | help | ||
280 | This enables support for the LTC3589, LTC3589-1, and LTC3589-2 | ||
281 | 8-output regulators controlled via I2C. | ||
282 | |||
268 | config REGULATOR_MAX14577 | 283 | config REGULATOR_MAX14577 |
269 | tristate "Maxim 14577 regulator" | 284 | tristate "Maxim 14577 regulator" |
270 | depends on MFD_MAX14577 | 285 | depends on MFD_MAX14577 |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 12ef277a48b4..d461110f4463 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o | |||
20 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o | 20 | obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o |
21 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o | 21 | obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o |
22 | obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o | 22 | obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o |
23 | obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o | ||
23 | obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o | 24 | obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o |
24 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | 25 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o |
25 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o | 26 | obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o |
@@ -37,6 +38,7 @@ obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o | |||
37 | obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o | 38 | obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o |
38 | obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o | 39 | obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o |
39 | obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o | 40 | obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o |
41 | obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o | ||
40 | obj-$(CONFIG_REGULATOR_MAX14577) += max14577.o | 42 | obj-$(CONFIG_REGULATOR_MAX14577) += max14577.o |
41 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o | 43 | obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o |
42 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o | 44 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 7c397bb81e01..4f730af70e7c 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -300,7 +300,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
300 | return 0; | 300 | return 0; |
301 | } | 301 | } |
302 | 302 | ||
303 | static struct of_device_id of_anatop_regulator_match_tbl[] = { | 303 | static const struct of_device_id of_anatop_regulator_match_tbl[] = { |
304 | { .compatible = "fsl,anatop-regulator", }, | 304 | { .compatible = "fsl,anatop-regulator", }, |
305 | { /* end */ } | 305 | { /* end */ } |
306 | }; | 306 | }; |
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 | ||
183 | static 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 | |||
181 | static int arizona_ldo1_probe(struct platform_device *pdev) | 219 | static 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 | ||
200 | static 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 | |||
198 | static int arizona_micsupp_probe(struct platform_device *pdev) | 226 | static 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 | |||
101 | static 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 | |||
106 | static struct regulator_ops axp20x_ops_fixed = { | ||
107 | .list_voltage = regulator_list_voltage_linear, | ||
108 | }; | ||
109 | |||
110 | static 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 | |||
120 | static 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 | |||
129 | static 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 | |||
152 | static 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 | |||
162 | static 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 | |||
182 | static 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 | |||
217 | static 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 | |||
232 | static 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 | |||
274 | static struct platform_driver axp20x_regulator_driver = { | ||
275 | .probe = axp20x_regulator_probe, | ||
276 | .driver = { | ||
277 | .name = "axp20x-regulator", | ||
278 | .owner = THIS_MODULE, | ||
279 | }, | ||
280 | }; | ||
281 | |||
282 | module_platform_driver(axp20x_regulator_driver); | ||
283 | |||
284 | MODULE_LICENSE("GPL v2"); | ||
285 | MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); | ||
286 | MODULE_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 | ||
69 | struct bcm590xx_board { | 106 | struct 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 | ||
154 | struct bcm590xx_reg { | 197 | struct 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 | ||
269 | static 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 | ||
248 | static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( | 311 | static 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/drivers/regulator/core.c b/drivers/regulator/core.c index 9a09f3cdbabb..4c1f999041dd 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -844,13 +844,22 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, | |||
844 | /* do we need to apply the constraint voltage */ | 844 | /* do we need to apply the constraint voltage */ |
845 | if (rdev->constraints->apply_uV && | 845 | if (rdev->constraints->apply_uV && |
846 | rdev->constraints->min_uV == rdev->constraints->max_uV) { | 846 | rdev->constraints->min_uV == rdev->constraints->max_uV) { |
847 | ret = _regulator_do_set_voltage(rdev, | 847 | int current_uV = _regulator_get_voltage(rdev); |
848 | rdev->constraints->min_uV, | 848 | if (current_uV < 0) { |
849 | rdev->constraints->max_uV); | 849 | rdev_err(rdev, "failed to get the current voltage\n"); |
850 | if (ret < 0) { | 850 | return current_uV; |
851 | rdev_err(rdev, "failed to apply %duV constraint\n", | 851 | } |
852 | rdev->constraints->min_uV); | 852 | if (current_uV < rdev->constraints->min_uV || |
853 | return ret; | 853 | current_uV > rdev->constraints->max_uV) { |
854 | ret = _regulator_do_set_voltage( | ||
855 | rdev, rdev->constraints->min_uV, | ||
856 | rdev->constraints->max_uV); | ||
857 | if (ret < 0) { | ||
858 | rdev_err(rdev, | ||
859 | "failed to apply %duV constraint\n", | ||
860 | rdev->constraints->min_uV); | ||
861 | return ret; | ||
862 | } | ||
854 | } | 863 | } |
855 | } | 864 | } |
856 | 865 | ||
@@ -1430,9 +1439,9 @@ EXPORT_SYMBOL_GPL(regulator_get); | |||
1430 | * | 1439 | * |
1431 | * Returns a struct regulator corresponding to the regulator producer, | 1440 | * Returns a struct regulator corresponding to the regulator producer, |
1432 | * or IS_ERR() condition containing errno. Other consumers will be | 1441 | * or IS_ERR() condition containing errno. Other consumers will be |
1433 | * unable to obtain this reference is held and the use count for the | 1442 | * unable to obtain this regulator while this reference is held and the |
1434 | * regulator will be initialised to reflect the current state of the | 1443 | * use count for the regulator will be initialised to reflect the current |
1435 | * regulator. | 1444 | * state of the regulator. |
1436 | * | 1445 | * |
1437 | * This is intended for use by consumers which cannot tolerate shared | 1446 | * This is intended for use by consumers which cannot tolerate shared |
1438 | * use of the regulator such as those which need to force the | 1447 | * use of the regulator such as those which need to force the |
@@ -1456,10 +1465,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive); | |||
1456 | * @id: Supply name or regulator ID. | 1465 | * @id: Supply name or regulator ID. |
1457 | * | 1466 | * |
1458 | * Returns a struct regulator corresponding to the regulator producer, | 1467 | * Returns a struct regulator corresponding to the regulator producer, |
1459 | * or IS_ERR() condition containing errno. Other consumers will be | 1468 | * or IS_ERR() condition containing errno. |
1460 | * unable to obtain this reference is held and the use count for the | ||
1461 | * regulator will be initialised to reflect the current state of the | ||
1462 | * regulator. | ||
1463 | * | 1469 | * |
1464 | * This is intended for use by consumers for devices which can have | 1470 | * This is intended for use by consumers for devices which can have |
1465 | * some supplies unconnected in normal use, such as some MMC devices. | 1471 | * some supplies unconnected in normal use, such as some MMC devices. |
@@ -1597,9 +1603,10 @@ EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); | |||
1597 | * registered any aliases that were registered will be removed | 1603 | * registered any aliases that were registered will be removed |
1598 | * before returning to the caller. | 1604 | * before returning to the caller. |
1599 | */ | 1605 | */ |
1600 | int regulator_bulk_register_supply_alias(struct device *dev, const char **id, | 1606 | int regulator_bulk_register_supply_alias(struct device *dev, |
1607 | const char *const *id, | ||
1601 | struct device *alias_dev, | 1608 | struct device *alias_dev, |
1602 | const char **alias_id, | 1609 | const char *const *alias_id, |
1603 | int num_id) | 1610 | int num_id) |
1604 | { | 1611 | { |
1605 | int i; | 1612 | int i; |
@@ -1637,7 +1644,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_register_supply_alias); | |||
1637 | * aliases in one operation. | 1644 | * aliases in one operation. |
1638 | */ | 1645 | */ |
1639 | void regulator_bulk_unregister_supply_alias(struct device *dev, | 1646 | void regulator_bulk_unregister_supply_alias(struct device *dev, |
1640 | const char **id, | 1647 | const char *const *id, |
1641 | int num_id) | 1648 | int num_id) |
1642 | { | 1649 | { |
1643 | int i; | 1650 | int i; |
@@ -2321,6 +2328,10 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
2321 | regulator_list_voltage_linear) | 2328 | regulator_list_voltage_linear) |
2322 | ret = regulator_map_voltage_linear(rdev, | 2329 | ret = regulator_map_voltage_linear(rdev, |
2323 | min_uV, max_uV); | 2330 | min_uV, max_uV); |
2331 | else if (rdev->desc->ops->list_voltage == | ||
2332 | regulator_list_voltage_linear_range) | ||
2333 | ret = regulator_map_voltage_linear_range(rdev, | ||
2334 | min_uV, max_uV); | ||
2324 | else | 2335 | else |
2325 | ret = regulator_map_voltage_iterate(rdev, | 2336 | ret = regulator_map_voltage_iterate(rdev, |
2326 | min_uV, max_uV); | 2337 | min_uV, max_uV); |
@@ -3447,7 +3458,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3447 | 3458 | ||
3448 | /* register with sysfs */ | 3459 | /* register with sysfs */ |
3449 | rdev->dev.class = ®ulator_class; | 3460 | rdev->dev.class = ®ulator_class; |
3450 | rdev->dev.of_node = config->of_node; | 3461 | rdev->dev.of_node = of_node_get(config->of_node); |
3451 | rdev->dev.parent = dev; | 3462 | rdev->dev.parent = dev; |
3452 | dev_set_name(&rdev->dev, "regulator.%d", | 3463 | dev_set_name(&rdev->dev, "regulator.%d", |
3453 | atomic_inc_return(®ulator_no) - 1); | 3464 | atomic_inc_return(®ulator_no) - 1); |
@@ -3589,6 +3600,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
3589 | list_del(&rdev->list); | 3600 | list_del(&rdev->list); |
3590 | kfree(rdev->constraints); | 3601 | kfree(rdev->constraints); |
3591 | regulator_ena_gpio_free(rdev); | 3602 | regulator_ena_gpio_free(rdev); |
3603 | of_node_put(rdev->dev.of_node); | ||
3592 | device_unregister(&rdev->dev); | 3604 | device_unregister(&rdev->dev); |
3593 | mutex_unlock(®ulator_list_mutex); | 3605 | mutex_unlock(®ulator_list_mutex); |
3594 | } | 3606 | } |
@@ -3819,8 +3831,9 @@ static int __init regulator_init_complete(void) | |||
3819 | mutex_lock(®ulator_list_mutex); | 3831 | mutex_lock(®ulator_list_mutex); |
3820 | 3832 | ||
3821 | /* If we have a full configuration then disable any regulators | 3833 | /* If we have a full configuration then disable any regulators |
3822 | * which are not in use or always_on. This will become the | 3834 | * we have permission to change the status for and which are |
3823 | * default behaviour in the future. | 3835 | * not in use or always_on. This is effectively the default |
3836 | * for DT and ACPI as they have full constraints. | ||
3824 | */ | 3837 | */ |
3825 | list_for_each_entry(rdev, ®ulator_list, list) { | 3838 | list_for_each_entry(rdev, ®ulator_list, list) { |
3826 | ops = rdev->desc->ops; | 3839 | ops = rdev->desc->ops; |
@@ -3829,6 +3842,9 @@ static int __init regulator_init_complete(void) | |||
3829 | if (c && c->always_on) | 3842 | if (c && c->always_on) |
3830 | continue; | 3843 | continue; |
3831 | 3844 | ||
3845 | if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS)) | ||
3846 | continue; | ||
3847 | |||
3832 | mutex_lock(&rdev->mutex); | 3848 | mutex_lock(&rdev->mutex); |
3833 | 3849 | ||
3834 | if (rdev->use_count) | 3850 | if (rdev->use_count) |
@@ -3867,4 +3883,4 @@ unlock: | |||
3867 | 3883 | ||
3868 | return 0; | 3884 | return 0; |
3869 | } | 3885 | } |
3870 | late_initcall(regulator_init_complete); | 3886 | late_initcall_sync(regulator_init_complete); |
diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c index f44818b838dc..8f785bc9e510 100644 --- a/drivers/regulator/devres.c +++ b/drivers/regulator/devres.c | |||
@@ -360,9 +360,9 @@ EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias); | |||
360 | * will be removed before returning to the caller. | 360 | * will be removed before returning to the caller. |
361 | */ | 361 | */ |
362 | int devm_regulator_bulk_register_supply_alias(struct device *dev, | 362 | int devm_regulator_bulk_register_supply_alias(struct device *dev, |
363 | const char **id, | 363 | const char *const *id, |
364 | struct device *alias_dev, | 364 | struct device *alias_dev, |
365 | const char **alias_id, | 365 | const char *const *alias_id, |
366 | int num_id) | 366 | int num_id) |
367 | { | 367 | { |
368 | int i; | 368 | int i; |
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias); | |||
404 | * will ensure that the resource is freed. | 404 | * will ensure that the resource is freed. |
405 | */ | 405 | */ |
406 | void devm_regulator_bulk_unregister_supply_alias(struct device *dev, | 406 | void devm_regulator_bulk_unregister_supply_alias(struct device *dev, |
407 | const char **id, | 407 | const char *const *id, |
408 | int num_id) | 408 | int num_id) |
409 | { | 409 | { |
410 | int i; | 410 | int i; |
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index c61f7e97e4f8..354105eff1f8 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
@@ -50,7 +50,6 @@ of_get_fixed_voltage_config(struct device *dev) | |||
50 | { | 50 | { |
51 | struct fixed_voltage_config *config; | 51 | struct fixed_voltage_config *config; |
52 | struct device_node *np = dev->of_node; | 52 | struct device_node *np = dev->of_node; |
53 | const __be32 *delay; | ||
54 | struct regulator_init_data *init_data; | 53 | struct regulator_init_data *init_data; |
55 | 54 | ||
56 | config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), | 55 | config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), |
@@ -91,15 +90,11 @@ of_get_fixed_voltage_config(struct device *dev) | |||
91 | if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER)) | 90 | if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER)) |
92 | return ERR_PTR(-EPROBE_DEFER); | 91 | return ERR_PTR(-EPROBE_DEFER); |
93 | 92 | ||
94 | delay = of_get_property(np, "startup-delay-us", NULL); | 93 | of_property_read_u32(np, "startup-delay-us", &config->startup_delay); |
95 | if (delay) | ||
96 | config->startup_delay = be32_to_cpu(*delay); | ||
97 | 94 | ||
98 | if (of_find_property(np, "enable-active-high", NULL)) | 95 | config->enable_high = of_property_read_bool(np, "enable-active-high"); |
99 | config->enable_high = true; | 96 | config->gpio_is_open_drain = of_property_read_bool(np, |
100 | 97 | "gpio-open-drain"); | |
101 | if (of_find_property(np, "gpio-open-drain", NULL)) | ||
102 | config->gpio_is_open_drain = true; | ||
103 | 98 | ||
104 | if (of_find_property(np, "vin-supply", NULL)) | 99 | if (of_find_property(np, "vin-supply", NULL)) |
105 | config->input_supply = "vin"; | 100 | config->input_supply = "vin"; |
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c new file mode 100644 index 000000000000..110a99ee1162 --- /dev/null +++ b/drivers/regulator/ltc3589.c | |||
@@ -0,0 +1,554 @@ | |||
1 | /* | ||
2 | * Linear Technology LTC3589,LTC3589-1 regulator support | ||
3 | * | ||
4 | * Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix | ||
5 | * | ||
6 | * See file CREDITS for list of people who contributed to this | ||
7 | * project. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 | ||
11 | * as published by the Free Software Foundation. | ||
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 | */ | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/regulator/driver.h> | ||
27 | #include <linux/regulator/of_regulator.h> | ||
28 | |||
29 | #define DRIVER_NAME "ltc3589" | ||
30 | |||
31 | #define LTC3589_IRQSTAT 0x02 | ||
32 | #define LTC3589_SCR1 0x07 | ||
33 | #define LTC3589_OVEN 0x10 | ||
34 | #define LTC3589_SCR2 0x12 | ||
35 | #define LTC3589_PGSTAT 0x13 | ||
36 | #define LTC3589_VCCR 0x20 | ||
37 | #define LTC3589_CLIRQ 0x21 | ||
38 | #define LTC3589_B1DTV1 0x23 | ||
39 | #define LTC3589_B1DTV2 0x24 | ||
40 | #define LTC3589_VRRCR 0x25 | ||
41 | #define LTC3589_B2DTV1 0x26 | ||
42 | #define LTC3589_B2DTV2 0x27 | ||
43 | #define LTC3589_B3DTV1 0x29 | ||
44 | #define LTC3589_B3DTV2 0x2a | ||
45 | #define LTC3589_L2DTV1 0x32 | ||
46 | #define LTC3589_L2DTV2 0x33 | ||
47 | |||
48 | #define LTC3589_IRQSTAT_PGOOD_TIMEOUT BIT(3) | ||
49 | #define LTC3589_IRQSTAT_UNDERVOLT_WARN BIT(4) | ||
50 | #define LTC3589_IRQSTAT_UNDERVOLT_FAULT BIT(5) | ||
51 | #define LTC3589_IRQSTAT_THERMAL_WARN BIT(6) | ||
52 | #define LTC3589_IRQSTAT_THERMAL_FAULT BIT(7) | ||
53 | |||
54 | #define LTC3589_OVEN_SW1 BIT(0) | ||
55 | #define LTC3589_OVEN_SW2 BIT(1) | ||
56 | #define LTC3589_OVEN_SW3 BIT(2) | ||
57 | #define LTC3589_OVEN_BB_OUT BIT(3) | ||
58 | #define LTC3589_OVEN_LDO2 BIT(4) | ||
59 | #define LTC3589_OVEN_LDO3 BIT(5) | ||
60 | #define LTC3589_OVEN_LDO4 BIT(6) | ||
61 | #define LTC3589_OVEN_SW_CTRL BIT(7) | ||
62 | |||
63 | #define LTC3589_VCCR_SW1_GO BIT(0) | ||
64 | #define LTC3589_VCCR_SW2_GO BIT(2) | ||
65 | #define LTC3589_VCCR_SW3_GO BIT(4) | ||
66 | #define LTC3589_VCCR_LDO2_GO BIT(6) | ||
67 | |||
68 | enum ltc3589_variant { | ||
69 | LTC3589, | ||
70 | LTC3589_1, | ||
71 | LTC3589_2, | ||
72 | }; | ||
73 | |||
74 | enum ltc3589_reg { | ||
75 | LTC3589_SW1, | ||
76 | LTC3589_SW2, | ||
77 | LTC3589_SW3, | ||
78 | LTC3589_BB_OUT, | ||
79 | LTC3589_LDO1, | ||
80 | LTC3589_LDO2, | ||
81 | LTC3589_LDO3, | ||
82 | LTC3589_LDO4, | ||
83 | LTC3589_NUM_REGULATORS, | ||
84 | }; | ||
85 | |||
86 | struct ltc3589_regulator { | ||
87 | struct regulator_desc desc; | ||
88 | |||
89 | /* External feedback voltage divider */ | ||
90 | unsigned int r1; | ||
91 | unsigned int r2; | ||
92 | }; | ||
93 | |||
94 | struct ltc3589 { | ||
95 | struct regmap *regmap; | ||
96 | struct device *dev; | ||
97 | enum ltc3589_variant variant; | ||
98 | struct ltc3589_regulator regulator_descs[LTC3589_NUM_REGULATORS]; | ||
99 | struct regulator_dev *regulators[LTC3589_NUM_REGULATORS]; | ||
100 | }; | ||
101 | |||
102 | static const int ltc3589_ldo4[] = { | ||
103 | 2800000, 2500000, 1800000, 3300000, | ||
104 | }; | ||
105 | |||
106 | static const int ltc3589_12_ldo4[] = { | ||
107 | 1200000, 1800000, 2500000, 3200000, | ||
108 | }; | ||
109 | |||
110 | static int ltc3589_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | ||
111 | { | ||
112 | struct ltc3589 *ltc3589 = rdev_get_drvdata(rdev); | ||
113 | int sel, shift; | ||
114 | |||
115 | if (unlikely(ramp_delay <= 0)) | ||
116 | return -EINVAL; | ||
117 | |||
118 | /* VRRCR slew rate offsets are the same as VCCR go bit offsets */ | ||
119 | shift = ffs(rdev->desc->apply_bit) - 1; | ||
120 | |||
121 | /* The slew rate can be set to 0.88, 1.75, 3.5, or 7 mV/uS */ | ||
122 | for (sel = 0; sel < 4; sel++) { | ||
123 | if ((880 << sel) >= ramp_delay) { | ||
124 | return regmap_update_bits(ltc3589->regmap, | ||
125 | LTC3589_VRRCR, | ||
126 | 0x3 << shift, sel << shift); | ||
127 | } | ||
128 | } | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | static int ltc3589_set_suspend_voltage(struct regulator_dev *rdev, int uV) | ||
133 | { | ||
134 | struct ltc3589 *ltc3589 = rdev_get_drvdata(rdev); | ||
135 | int sel; | ||
136 | |||
137 | sel = regulator_map_voltage_linear(rdev, uV, uV); | ||
138 | if (sel < 0) | ||
139 | return sel; | ||
140 | |||
141 | /* DTV2 register follows right after the corresponding DTV1 register */ | ||
142 | return regmap_update_bits(ltc3589->regmap, rdev->desc->vsel_reg + 1, | ||
143 | rdev->desc->vsel_mask, sel); | ||
144 | } | ||
145 | |||
146 | static int ltc3589_set_suspend_mode(struct regulator_dev *rdev, | ||
147 | unsigned int mode) | ||
148 | { | ||
149 | struct ltc3589 *ltc3589 = rdev_get_drvdata(rdev); | ||
150 | int mask, bit = 0; | ||
151 | |||
152 | /* VCCR reference selects are right next to the VCCR go bits */ | ||
153 | mask = rdev->desc->apply_bit << 1; | ||
154 | |||
155 | if (mode == REGULATOR_MODE_STANDBY) | ||
156 | bit = mask; /* Select DTV2 */ | ||
157 | |||
158 | mask |= rdev->desc->apply_bit; | ||
159 | bit |= rdev->desc->apply_bit; | ||
160 | return regmap_update_bits(ltc3589->regmap, LTC3589_VCCR, mask, bit); | ||
161 | } | ||
162 | |||
163 | /* SW1, SW2, SW3, LDO2 */ | ||
164 | static struct regulator_ops ltc3589_linear_regulator_ops = { | ||
165 | .enable = regulator_enable_regmap, | ||
166 | .disable = regulator_disable_regmap, | ||
167 | .is_enabled = regulator_is_enabled_regmap, | ||
168 | .list_voltage = regulator_list_voltage_linear, | ||
169 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
170 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
171 | .set_ramp_delay = ltc3589_set_ramp_delay, | ||
172 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
173 | .set_suspend_voltage = ltc3589_set_suspend_voltage, | ||
174 | .set_suspend_mode = ltc3589_set_suspend_mode, | ||
175 | }; | ||
176 | |||
177 | /* BB_OUT, LDO3 */ | ||
178 | static struct regulator_ops ltc3589_fixed_regulator_ops = { | ||
179 | .enable = regulator_enable_regmap, | ||
180 | .disable = regulator_disable_regmap, | ||
181 | .is_enabled = regulator_is_enabled_regmap, | ||
182 | }; | ||
183 | |||
184 | /* LDO1 */ | ||
185 | static struct regulator_ops ltc3589_fixed_standby_regulator_ops = { | ||
186 | }; | ||
187 | |||
188 | /* LDO4 */ | ||
189 | static struct regulator_ops ltc3589_table_regulator_ops = { | ||
190 | .enable = regulator_enable_regmap, | ||
191 | .disable = regulator_disable_regmap, | ||
192 | .is_enabled = regulator_is_enabled_regmap, | ||
193 | .list_voltage = regulator_list_voltage_table, | ||
194 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
195 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
196 | }; | ||
197 | |||
198 | |||
199 | #define LTC3589_REG(_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit) \ | ||
200 | [LTC3589_ ## _name] = { \ | ||
201 | .desc = { \ | ||
202 | .name = #_name, \ | ||
203 | .n_voltages = (dtv_mask) + 1, \ | ||
204 | .min_uV = (go_bit) ? 362500 : 0, \ | ||
205 | .uV_step = (go_bit) ? 12500 : 0, \ | ||
206 | .ramp_delay = (go_bit) ? 1750 : 0, \ | ||
207 | .fixed_uV = (dtv_mask) ? 0 : 800000, \ | ||
208 | .ops = <c3589_ ## _ops ## _regulator_ops, \ | ||
209 | .type = REGULATOR_VOLTAGE, \ | ||
210 | .id = LTC3589_ ## _name, \ | ||
211 | .owner = THIS_MODULE, \ | ||
212 | .vsel_reg = (dtv1_reg), \ | ||
213 | .vsel_mask = (dtv_mask), \ | ||
214 | .apply_reg = (go_bit) ? LTC3589_VCCR : 0, \ | ||
215 | .apply_bit = (go_bit), \ | ||
216 | .enable_reg = (en_bit) ? LTC3589_OVEN : 0, \ | ||
217 | .enable_mask = (en_bit), \ | ||
218 | }, \ | ||
219 | } | ||
220 | |||
221 | #define LTC3589_LINEAR_REG(_name, _dtv1) \ | ||
222 | LTC3589_REG(_name, linear, LTC3589_OVEN_ ## _name, \ | ||
223 | LTC3589_ ## _dtv1, 0x1f, \ | ||
224 | LTC3589_VCCR_ ## _name ## _GO) | ||
225 | |||
226 | #define LTC3589_FIXED_REG(_name) \ | ||
227 | LTC3589_REG(_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) | ||
228 | |||
229 | static struct ltc3589_regulator ltc3589_regulators[LTC3589_NUM_REGULATORS] = { | ||
230 | LTC3589_LINEAR_REG(SW1, B1DTV1), | ||
231 | LTC3589_LINEAR_REG(SW2, B2DTV1), | ||
232 | LTC3589_LINEAR_REG(SW3, B3DTV1), | ||
233 | LTC3589_FIXED_REG(BB_OUT), | ||
234 | LTC3589_REG(LDO1, fixed_standby, 0, 0, 0, 0), | ||
235 | LTC3589_LINEAR_REG(LDO2, L2DTV1), | ||
236 | LTC3589_FIXED_REG(LDO3), | ||
237 | LTC3589_REG(LDO4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60, 0), | ||
238 | }; | ||
239 | |||
240 | #ifdef CONFIG_OF | ||
241 | static struct of_regulator_match ltc3589_matches[LTC3589_NUM_REGULATORS] = { | ||
242 | { .name = "sw1", }, | ||
243 | { .name = "sw2", }, | ||
244 | { .name = "sw3", }, | ||
245 | { .name = "bb-out", }, | ||
246 | { .name = "ldo1", }, /* standby */ | ||
247 | { .name = "ldo2", }, | ||
248 | { .name = "ldo3", }, | ||
249 | { .name = "ldo4", }, | ||
250 | }; | ||
251 | |||
252 | static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) | ||
253 | { | ||
254 | struct device *dev = ltc3589->dev; | ||
255 | struct device_node *node; | ||
256 | int i, ret; | ||
257 | |||
258 | node = of_find_node_by_name(dev->of_node, "regulators"); | ||
259 | if (!node) { | ||
260 | dev_err(dev, "regulators node not found\n"); | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | |||
264 | ret = of_regulator_match(dev, node, ltc3589_matches, | ||
265 | ARRAY_SIZE(ltc3589_matches)); | ||
266 | of_node_put(node); | ||
267 | if (ret < 0) { | ||
268 | dev_err(dev, "Error parsing regulator init data: %d\n", ret); | ||
269 | return ret; | ||
270 | } | ||
271 | if (ret != LTC3589_NUM_REGULATORS) { | ||
272 | dev_err(dev, "Only %d regulators described in device tree\n", | ||
273 | ret); | ||
274 | return -EINVAL; | ||
275 | } | ||
276 | |||
277 | /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ | ||
278 | for (i = 0; i < LTC3589_LDO3; i++) { | ||
279 | struct ltc3589_regulator *desc = <c3589->regulator_descs[i]; | ||
280 | struct device_node *np = ltc3589_matches[i].of_node; | ||
281 | u32 vdiv[2]; | ||
282 | |||
283 | ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", | ||
284 | vdiv, 2); | ||
285 | if (ret) { | ||
286 | dev_err(dev, "Failed to parse voltage divider: %d\n", | ||
287 | ret); | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | desc->r1 = vdiv[0]; | ||
292 | desc->r2 = vdiv[1]; | ||
293 | } | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static inline struct regulator_init_data *match_init_data(int index) | ||
299 | { | ||
300 | return ltc3589_matches[index].init_data; | ||
301 | } | ||
302 | |||
303 | static inline struct device_node *match_of_node(int index) | ||
304 | { | ||
305 | return ltc3589_matches[index].of_node; | ||
306 | } | ||
307 | #else | ||
308 | static inline int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) | ||
309 | { | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static inline struct regulator_init_data *match_init_data(int index) | ||
314 | { | ||
315 | return NULL; | ||
316 | } | ||
317 | |||
318 | static inline struct device_node *match_of_node(int index) | ||
319 | { | ||
320 | return NULL; | ||
321 | } | ||
322 | #endif | ||
323 | |||
324 | static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg) | ||
325 | { | ||
326 | switch (reg) { | ||
327 | case LTC3589_IRQSTAT: | ||
328 | case LTC3589_SCR1: | ||
329 | case LTC3589_OVEN: | ||
330 | case LTC3589_SCR2: | ||
331 | case LTC3589_VCCR: | ||
332 | case LTC3589_CLIRQ: | ||
333 | case LTC3589_B1DTV1: | ||
334 | case LTC3589_B1DTV2: | ||
335 | case LTC3589_VRRCR: | ||
336 | case LTC3589_B2DTV1: | ||
337 | case LTC3589_B2DTV2: | ||
338 | case LTC3589_B3DTV1: | ||
339 | case LTC3589_B3DTV2: | ||
340 | case LTC3589_L2DTV1: | ||
341 | case LTC3589_L2DTV2: | ||
342 | return true; | ||
343 | } | ||
344 | return false; | ||
345 | } | ||
346 | |||
347 | static bool ltc3589_readable_reg(struct device *dev, unsigned int reg) | ||
348 | { | ||
349 | switch (reg) { | ||
350 | case LTC3589_IRQSTAT: | ||
351 | case LTC3589_SCR1: | ||
352 | case LTC3589_OVEN: | ||
353 | case LTC3589_SCR2: | ||
354 | case LTC3589_PGSTAT: | ||
355 | case LTC3589_VCCR: | ||
356 | case LTC3589_B1DTV1: | ||
357 | case LTC3589_B1DTV2: | ||
358 | case LTC3589_VRRCR: | ||
359 | case LTC3589_B2DTV1: | ||
360 | case LTC3589_B2DTV2: | ||
361 | case LTC3589_B3DTV1: | ||
362 | case LTC3589_B3DTV2: | ||
363 | case LTC3589_L2DTV1: | ||
364 | case LTC3589_L2DTV2: | ||
365 | return true; | ||
366 | } | ||
367 | return false; | ||
368 | } | ||
369 | |||
370 | static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg) | ||
371 | { | ||
372 | switch (reg) { | ||
373 | case LTC3589_IRQSTAT: | ||
374 | case LTC3589_PGSTAT: | ||
375 | return true; | ||
376 | } | ||
377 | return false; | ||
378 | } | ||
379 | |||
380 | struct reg_default ltc3589_reg_defaults[] = { | ||
381 | { LTC3589_SCR1, 0x00 }, | ||
382 | { LTC3589_OVEN, 0x00 }, | ||
383 | { LTC3589_SCR2, 0x00 }, | ||
384 | { LTC3589_VCCR, 0x00 }, | ||
385 | { LTC3589_B1DTV1, 0x19 }, | ||
386 | { LTC3589_B1DTV2, 0x19 }, | ||
387 | { LTC3589_VRRCR, 0xff }, | ||
388 | { LTC3589_B2DTV1, 0x19 }, | ||
389 | { LTC3589_B2DTV2, 0x19 }, | ||
390 | { LTC3589_B3DTV1, 0x19 }, | ||
391 | { LTC3589_B3DTV2, 0x19 }, | ||
392 | { LTC3589_L2DTV1, 0x19 }, | ||
393 | { LTC3589_L2DTV2, 0x19 }, | ||
394 | }; | ||
395 | |||
396 | static const struct regmap_config ltc3589_regmap_config = { | ||
397 | .reg_bits = 8, | ||
398 | .val_bits = 8, | ||
399 | .writeable_reg = ltc3589_writeable_reg, | ||
400 | .readable_reg = ltc3589_readable_reg, | ||
401 | .volatile_reg = ltc3589_volatile_reg, | ||
402 | .max_register = LTC3589_L2DTV2, | ||
403 | .reg_defaults = ltc3589_reg_defaults, | ||
404 | .num_reg_defaults = ARRAY_SIZE(ltc3589_reg_defaults), | ||
405 | .use_single_rw = true, | ||
406 | .cache_type = REGCACHE_RBTREE, | ||
407 | }; | ||
408 | |||
409 | |||
410 | static irqreturn_t ltc3589_isr(int irq, void *dev_id) | ||
411 | { | ||
412 | struct ltc3589 *ltc3589 = dev_id; | ||
413 | unsigned int i, irqstat, event; | ||
414 | |||
415 | regmap_read(ltc3589->regmap, LTC3589_IRQSTAT, &irqstat); | ||
416 | |||
417 | if (irqstat & LTC3589_IRQSTAT_THERMAL_WARN) { | ||
418 | event = REGULATOR_EVENT_OVER_TEMP; | ||
419 | for (i = 0; i < LTC3589_NUM_REGULATORS; i++) | ||
420 | regulator_notifier_call_chain(ltc3589->regulators[i], | ||
421 | event, NULL); | ||
422 | } | ||
423 | |||
424 | if (irqstat & LTC3589_IRQSTAT_UNDERVOLT_WARN) { | ||
425 | event = REGULATOR_EVENT_UNDER_VOLTAGE; | ||
426 | for (i = 0; i < LTC3589_NUM_REGULATORS; i++) | ||
427 | regulator_notifier_call_chain(ltc3589->regulators[i], | ||
428 | event, NULL); | ||
429 | } | ||
430 | |||
431 | /* Clear warning condition */ | ||
432 | regmap_write(ltc3589->regmap, LTC3589_CLIRQ, 0); | ||
433 | |||
434 | return IRQ_HANDLED; | ||
435 | } | ||
436 | |||
437 | static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) | ||
438 | { | ||
439 | uint64_t tmp; | ||
440 | if (uV == 0) | ||
441 | return 0; | ||
442 | tmp = (uint64_t)uV * r1; | ||
443 | do_div(tmp, r2); | ||
444 | return uV + (unsigned int)tmp; | ||
445 | } | ||
446 | |||
447 | static void ltc3589_apply_fb_voltage_divider(struct ltc3589_regulator *rdesc) | ||
448 | { | ||
449 | struct regulator_desc *desc = &rdesc->desc; | ||
450 | |||
451 | if (!rdesc->r1 || !rdesc->r2) | ||
452 | return; | ||
453 | |||
454 | desc->min_uV = ltc3589_scale(desc->min_uV, rdesc->r1, rdesc->r2); | ||
455 | desc->uV_step = ltc3589_scale(desc->uV_step, rdesc->r1, rdesc->r2); | ||
456 | desc->fixed_uV = ltc3589_scale(desc->fixed_uV, rdesc->r1, rdesc->r2); | ||
457 | } | ||
458 | |||
459 | static int ltc3589_probe(struct i2c_client *client, | ||
460 | const struct i2c_device_id *id) | ||
461 | { | ||
462 | struct device *dev = &client->dev; | ||
463 | struct ltc3589_regulator *descs; | ||
464 | struct ltc3589 *ltc3589; | ||
465 | int i, ret; | ||
466 | |||
467 | ltc3589 = devm_kzalloc(dev, sizeof(*ltc3589), GFP_KERNEL); | ||
468 | if (!ltc3589) | ||
469 | return -ENOMEM; | ||
470 | |||
471 | i2c_set_clientdata(client, ltc3589); | ||
472 | ltc3589->variant = id->driver_data; | ||
473 | ltc3589->dev = dev; | ||
474 | |||
475 | descs = ltc3589->regulator_descs; | ||
476 | memcpy(descs, ltc3589_regulators, sizeof(ltc3589_regulators)); | ||
477 | if (ltc3589->variant == LTC3589) { | ||
478 | descs[LTC3589_LDO3].desc.fixed_uV = 1800000; | ||
479 | descs[LTC3589_LDO4].desc.volt_table = ltc3589_ldo4; | ||
480 | } else { | ||
481 | descs[LTC3589_LDO3].desc.fixed_uV = 2800000; | ||
482 | descs[LTC3589_LDO4].desc.volt_table = ltc3589_12_ldo4; | ||
483 | } | ||
484 | |||
485 | ltc3589->regmap = devm_regmap_init_i2c(client, <c3589_regmap_config); | ||
486 | if (IS_ERR(ltc3589->regmap)) { | ||
487 | ret = PTR_ERR(ltc3589->regmap); | ||
488 | dev_err(dev, "failed to initialize regmap: %d\n", ret); | ||
489 | return ret; | ||
490 | } | ||
491 | |||
492 | ret = ltc3589_parse_regulators_dt(ltc3589); | ||
493 | if (ret) | ||
494 | return ret; | ||
495 | |||
496 | for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { | ||
497 | struct ltc3589_regulator *rdesc = <c3589->regulator_descs[i]; | ||
498 | struct regulator_desc *desc = &rdesc->desc; | ||
499 | struct regulator_init_data *init_data; | ||
500 | struct regulator_config config = { }; | ||
501 | |||
502 | init_data = match_init_data(i); | ||
503 | |||
504 | if (i < LTC3589_LDO3) | ||
505 | ltc3589_apply_fb_voltage_divider(rdesc); | ||
506 | |||
507 | config.dev = dev; | ||
508 | config.init_data = init_data; | ||
509 | config.driver_data = ltc3589; | ||
510 | config.of_node = match_of_node(i); | ||
511 | |||
512 | ltc3589->regulators[i] = devm_regulator_register(dev, desc, | ||
513 | &config); | ||
514 | if (IS_ERR(ltc3589->regulators[i])) { | ||
515 | ret = PTR_ERR(ltc3589->regulators[i]); | ||
516 | dev_err(dev, "failed to register regulator %s: %d\n", | ||
517 | desc->name, ret); | ||
518 | return ret; | ||
519 | } | ||
520 | } | ||
521 | |||
522 | ret = devm_request_threaded_irq(dev, client->irq, NULL, ltc3589_isr, | ||
523 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
524 | client->name, ltc3589); | ||
525 | if (ret) { | ||
526 | dev_err(dev, "Failed to request IRQ: %d\n", ret); | ||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static struct i2c_device_id ltc3589_i2c_id[] = { | ||
534 | { "ltc3589", LTC3589 }, | ||
535 | { "ltc3589-1", LTC3589_1 }, | ||
536 | { "ltc3589-2", LTC3589_2 }, | ||
537 | { } | ||
538 | }; | ||
539 | MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id); | ||
540 | |||
541 | static struct i2c_driver ltc3589_driver = { | ||
542 | .driver = { | ||
543 | .name = DRIVER_NAME, | ||
544 | .owner = THIS_MODULE, | ||
545 | }, | ||
546 | .probe = ltc3589_probe, | ||
547 | .id_table = ltc3589_i2c_id, | ||
548 | }; | ||
549 | module_i2c_driver(ltc3589_driver); | ||
550 | |||
551 | MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>"); | ||
552 | MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC3589(-1,2)"); | ||
553 | MODULE_LICENSE("GPL v2"); | ||
554 | MODULE_ALIAS("i2c:ltc3589"); | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 3172da847d24..c8bddcc8f911 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -161,10 +161,8 @@ static int max8649_regulator_probe(struct i2c_client *client, | |||
161 | 161 | ||
162 | info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info), | 162 | info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info), |
163 | GFP_KERNEL); | 163 | GFP_KERNEL); |
164 | if (!info) { | 164 | if (!info) |
165 | dev_err(&client->dev, "No enough memory\n"); | ||
166 | return -ENOMEM; | 165 | return -ENOMEM; |
167 | } | ||
168 | 166 | ||
169 | info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config); | 167 | info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config); |
170 | if (IS_ERR(info->regmap)) { | 168 | if (IS_ERR(info->regmap)) { |
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index d920f5a32ec8..c2792f0271ab 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c | |||
@@ -129,7 +129,7 @@ static const struct regulator_desc regulator = { | |||
129 | }; | 129 | }; |
130 | 130 | ||
131 | #ifdef CONFIG_OF | 131 | #ifdef CONFIG_OF |
132 | static struct of_device_id max8952_dt_match[] = { | 132 | static const struct of_device_id max8952_dt_match[] = { |
133 | { .compatible = "maxim,max8952" }, | 133 | { .compatible = "maxim,max8952" }, |
134 | {}, | 134 | {}, |
135 | }; | 135 | }; |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index ea4f36f2cbe2..ee5e67bc8d5b 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -19,9 +19,7 @@ | |||
19 | static void of_get_regulation_constraints(struct device_node *np, | 19 | static void of_get_regulation_constraints(struct device_node *np, |
20 | struct regulator_init_data **init_data) | 20 | struct regulator_init_data **init_data) |
21 | { | 21 | { |
22 | const __be32 *min_uV, *max_uV, *uV_offset; | 22 | const __be32 *min_uV, *max_uV; |
23 | const __be32 *min_uA, *max_uA, *ramp_delay; | ||
24 | struct property *prop; | ||
25 | struct regulation_constraints *constraints = &(*init_data)->constraints; | 23 | struct regulation_constraints *constraints = &(*init_data)->constraints; |
26 | int ret; | 24 | int ret; |
27 | u32 pval; | 25 | u32 pval; |
@@ -42,36 +40,29 @@ static void of_get_regulation_constraints(struct device_node *np, | |||
42 | if (min_uV && max_uV && constraints->min_uV == constraints->max_uV) | 40 | if (min_uV && max_uV && constraints->min_uV == constraints->max_uV) |
43 | constraints->apply_uV = true; | 41 | constraints->apply_uV = true; |
44 | 42 | ||
45 | uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL); | 43 | if (!of_property_read_u32(np, "regulator-microvolt-offset", &pval)) |
46 | if (uV_offset) | 44 | constraints->uV_offset = pval; |
47 | constraints->uV_offset = be32_to_cpu(*uV_offset); | 45 | if (!of_property_read_u32(np, "regulator-min-microamp", &pval)) |
48 | min_uA = of_get_property(np, "regulator-min-microamp", NULL); | 46 | constraints->min_uA = pval; |
49 | if (min_uA) | 47 | if (!of_property_read_u32(np, "regulator-max-microamp", &pval)) |
50 | constraints->min_uA = be32_to_cpu(*min_uA); | 48 | constraints->max_uA = pval; |
51 | max_uA = of_get_property(np, "regulator-max-microamp", NULL); | ||
52 | if (max_uA) | ||
53 | constraints->max_uA = be32_to_cpu(*max_uA); | ||
54 | 49 | ||
55 | /* Current change possible? */ | 50 | /* Current change possible? */ |
56 | if (constraints->min_uA != constraints->max_uA) | 51 | if (constraints->min_uA != constraints->max_uA) |
57 | constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT; | 52 | constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT; |
58 | 53 | ||
59 | if (of_find_property(np, "regulator-boot-on", NULL)) | 54 | constraints->boot_on = of_property_read_bool(np, "regulator-boot-on"); |
60 | constraints->boot_on = true; | 55 | constraints->always_on = of_property_read_bool(np, "regulator-always-on"); |
61 | 56 | if (!constraints->always_on) /* status change should be possible. */ | |
62 | if (of_find_property(np, "regulator-always-on", NULL)) | ||
63 | constraints->always_on = true; | ||
64 | else /* status change should be possible if not always on. */ | ||
65 | constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; | 57 | constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; |
66 | 58 | ||
67 | if (of_property_read_bool(np, "regulator-allow-bypass")) | 59 | if (of_property_read_bool(np, "regulator-allow-bypass")) |
68 | constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; | 60 | constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; |
69 | 61 | ||
70 | prop = of_find_property(np, "regulator-ramp-delay", NULL); | 62 | ret = of_property_read_u32(np, "regulator-ramp-delay", &pval); |
71 | if (prop && prop->value) { | 63 | if (!ret) { |
72 | ramp_delay = prop->value; | 64 | if (pval) |
73 | if (*ramp_delay) | 65 | constraints->ramp_delay = pval; |
74 | constraints->ramp_delay = be32_to_cpu(*ramp_delay); | ||
75 | else | 66 | else |
76 | constraints->ramp_disable = true; | 67 | constraints->ramp_disable = true; |
77 | } | 68 | } |
@@ -106,6 +97,20 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, | |||
106 | } | 97 | } |
107 | EXPORT_SYMBOL_GPL(of_get_regulator_init_data); | 98 | EXPORT_SYMBOL_GPL(of_get_regulator_init_data); |
108 | 99 | ||
100 | struct devm_of_regulator_matches { | ||
101 | struct of_regulator_match *matches; | ||
102 | unsigned int num_matches; | ||
103 | }; | ||
104 | |||
105 | static void devm_of_regulator_put_matches(struct device *dev, void *res) | ||
106 | { | ||
107 | struct devm_of_regulator_matches *devm_matches = res; | ||
108 | int i; | ||
109 | |||
110 | for (i = 0; i < devm_matches->num_matches; i++) | ||
111 | of_node_put(devm_matches->matches[i].of_node); | ||
112 | } | ||
113 | |||
109 | /** | 114 | /** |
110 | * of_regulator_match - extract multiple regulator init data from device tree. | 115 | * of_regulator_match - extract multiple regulator init data from device tree. |
111 | * @dev: device requesting the data | 116 | * @dev: device requesting the data |
@@ -119,7 +124,8 @@ EXPORT_SYMBOL_GPL(of_get_regulator_init_data); | |||
119 | * regulator. The data parsed from a child node will be matched to a regulator | 124 | * regulator. The data parsed from a child node will be matched to a regulator |
120 | * based on either the deprecated property regulator-compatible if present, | 125 | * based on either the deprecated property regulator-compatible if present, |
121 | * or otherwise the child node's name. Note that the match table is modified | 126 | * or otherwise the child node's name. Note that the match table is modified |
122 | * in place. | 127 | * in place and an additional of_node reference is taken for each matched |
128 | * regulator. | ||
123 | * | 129 | * |
124 | * Returns the number of matches found or a negative error code on failure. | 130 | * Returns the number of matches found or a negative error code on failure. |
125 | */ | 131 | */ |
@@ -131,10 +137,22 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
131 | unsigned int i; | 137 | unsigned int i; |
132 | const char *name; | 138 | const char *name; |
133 | struct device_node *child; | 139 | struct device_node *child; |
140 | struct devm_of_regulator_matches *devm_matches; | ||
134 | 141 | ||
135 | if (!dev || !node) | 142 | if (!dev || !node) |
136 | return -EINVAL; | 143 | return -EINVAL; |
137 | 144 | ||
145 | devm_matches = devres_alloc(devm_of_regulator_put_matches, | ||
146 | sizeof(struct devm_of_regulator_matches), | ||
147 | GFP_KERNEL); | ||
148 | if (!devm_matches) | ||
149 | return -ENOMEM; | ||
150 | |||
151 | devm_matches->matches = matches; | ||
152 | devm_matches->num_matches = num_matches; | ||
153 | |||
154 | devres_add(dev, devm_matches); | ||
155 | |||
138 | for (i = 0; i < num_matches; i++) { | 156 | for (i = 0; i < num_matches; i++) { |
139 | struct of_regulator_match *match = &matches[i]; | 157 | struct of_regulator_match *match = &matches[i]; |
140 | match->init_data = NULL; | 158 | match->init_data = NULL; |
@@ -162,7 +180,7 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
162 | child->name); | 180 | child->name); |
163 | return -EINVAL; | 181 | return -EINVAL; |
164 | } | 182 | } |
165 | match->of_node = child; | 183 | match->of_node = of_node_get(child); |
166 | count++; | 184 | count++; |
167 | break; | 185 | break; |
168 | } | 186 | } |
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 9c62b1d34685..864ed02ce4b7 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -36,6 +36,18 @@ struct regs_info { | |||
36 | int sleep_id; | 36 | int sleep_id; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static const struct regulator_linear_range smps_low_ranges[] = { | ||
40 | REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0), | ||
41 | REGULATOR_LINEAR_RANGE(510000, 0x7, 0x79, 10000), | ||
42 | REGULATOR_LINEAR_RANGE(1650000, 0x7A, 0x7f, 0), | ||
43 | }; | ||
44 | |||
45 | static const struct regulator_linear_range smps_high_ranges[] = { | ||
46 | REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x6, 0), | ||
47 | REGULATOR_LINEAR_RANGE(1020000, 0x7, 0x79, 20000), | ||
48 | REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0), | ||
49 | }; | ||
50 | |||
39 | static const struct regs_info palmas_regs_info[] = { | 51 | static const struct regs_info palmas_regs_info[] = { |
40 | { | 52 | { |
41 | .name = "SMPS12", | 53 | .name = "SMPS12", |
@@ -280,54 +292,6 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, | |||
280 | return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); | 292 | return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); |
281 | } | 293 | } |
282 | 294 | ||
283 | static int palmas_is_enabled_smps(struct regulator_dev *dev) | ||
284 | { | ||
285 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | ||
286 | int id = rdev_get_id(dev); | ||
287 | unsigned int reg; | ||
288 | |||
289 | palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); | ||
290 | |||
291 | reg &= PALMAS_SMPS12_CTRL_STATUS_MASK; | ||
292 | reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; | ||
293 | |||
294 | return !!(reg); | ||
295 | } | ||
296 | |||
297 | static int palmas_enable_smps(struct regulator_dev *dev) | ||
298 | { | ||
299 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | ||
300 | int id = rdev_get_id(dev); | ||
301 | unsigned int reg; | ||
302 | |||
303 | palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); | ||
304 | |||
305 | reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; | ||
306 | if (pmic->current_reg_mode[id]) | ||
307 | reg |= pmic->current_reg_mode[id]; | ||
308 | else | ||
309 | reg |= SMPS_CTRL_MODE_ON; | ||
310 | |||
311 | palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int palmas_disable_smps(struct regulator_dev *dev) | ||
317 | { | ||
318 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | ||
319 | int id = rdev_get_id(dev); | ||
320 | unsigned int reg; | ||
321 | |||
322 | palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); | ||
323 | |||
324 | reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; | ||
325 | |||
326 | palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) | 295 | static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) |
332 | { | 296 | { |
333 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | 297 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); |
@@ -382,81 +346,6 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev) | |||
382 | return 0; | 346 | return 0; |
383 | } | 347 | } |
384 | 348 | ||
385 | static int palmas_list_voltage_smps(struct regulator_dev *dev, | ||
386 | unsigned selector) | ||
387 | { | ||
388 | struct palmas_pmic *pmic = rdev_get_drvdata(dev); | ||
389 | int id = rdev_get_id(dev); | ||
390 | int mult = 1; | ||
391 | |||
392 | /* Read the multiplier set in VSEL register to return | ||
393 | * the correct voltage. | ||
394 | */ | ||
395 | if (pmic->range[id]) | ||
396 | mult = 2; | ||
397 | |||
398 | if (selector == 0) | ||
399 | return 0; | ||
400 | else if (selector < 6) | ||
401 | return 500000 * mult; | ||
402 | else | ||
403 | /* Voltage is linear mapping starting from selector 6, | ||
404 | * volt = (0.49V + ((selector - 5) * 0.01V)) * RANGE | ||
405 | * RANGE is either x1 or x2 | ||
406 | */ | ||
407 | return (490000 + ((selector - 5) * 10000)) * mult; | ||
408 | } | ||
409 | |||
410 | static int palmas_map_voltage_smps(struct regulator_dev *rdev, | ||
411 | int min_uV, int max_uV) | ||
412 | { | ||
413 | struct palmas_pmic *pmic = rdev_get_drvdata(rdev); | ||
414 | int id = rdev_get_id(rdev); | ||
415 | int ret, voltage; | ||
416 | |||
417 | if (min_uV == 0) | ||
418 | return 0; | ||
419 | |||
420 | if (pmic->range[id]) { /* RANGE is x2 */ | ||
421 | if (min_uV < 1000000) | ||
422 | min_uV = 1000000; | ||
423 | ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 6; | ||
424 | } else { /* RANGE is x1 */ | ||
425 | if (min_uV < 500000) | ||
426 | min_uV = 500000; | ||
427 | ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 6; | ||
428 | } | ||
429 | |||
430 | /* Map back into a voltage to verify we're still in bounds */ | ||
431 | voltage = palmas_list_voltage_smps(rdev, ret); | ||
432 | if (voltage < min_uV || voltage > max_uV) | ||
433 | return -EINVAL; | ||
434 | |||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static int palma_smps_set_voltage_smps_time_sel(struct regulator_dev *rdev, | ||
439 | unsigned int old_selector, unsigned int new_selector) | ||
440 | { | ||
441 | struct palmas_pmic *pmic = rdev_get_drvdata(rdev); | ||
442 | int id = rdev_get_id(rdev); | ||
443 | int old_uv, new_uv; | ||
444 | unsigned int ramp_delay = pmic->ramp_delay[id]; | ||
445 | |||
446 | if (!ramp_delay) | ||
447 | return 0; | ||
448 | |||
449 | old_uv = palmas_list_voltage_smps(rdev, old_selector); | ||
450 | if (old_uv < 0) | ||
451 | return old_uv; | ||
452 | |||
453 | new_uv = palmas_list_voltage_smps(rdev, new_selector); | ||
454 | if (new_uv < 0) | ||
455 | return new_uv; | ||
456 | |||
457 | return DIV_ROUND_UP(abs(old_uv - new_uv), ramp_delay); | ||
458 | } | ||
459 | |||
460 | static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, | 349 | static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, |
461 | int ramp_delay) | 350 | int ramp_delay) |
462 | { | 351 | { |
@@ -493,16 +382,16 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, | |||
493 | } | 382 | } |
494 | 383 | ||
495 | static struct regulator_ops palmas_ops_smps = { | 384 | static struct regulator_ops palmas_ops_smps = { |
496 | .is_enabled = palmas_is_enabled_smps, | 385 | .is_enabled = regulator_is_enabled_regmap, |
497 | .enable = palmas_enable_smps, | 386 | .enable = regulator_enable_regmap, |
498 | .disable = palmas_disable_smps, | 387 | .disable = regulator_disable_regmap, |
499 | .set_mode = palmas_set_mode_smps, | 388 | .set_mode = palmas_set_mode_smps, |
500 | .get_mode = palmas_get_mode_smps, | 389 | .get_mode = palmas_get_mode_smps, |
501 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 390 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
502 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 391 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
503 | .list_voltage = palmas_list_voltage_smps, | 392 | .list_voltage = regulator_list_voltage_linear_range, |
504 | .map_voltage = palmas_map_voltage_smps, | 393 | .map_voltage = regulator_map_voltage_linear_range, |
505 | .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, | 394 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
506 | .set_ramp_delay = palmas_smps_set_ramp_delay, | 395 | .set_ramp_delay = palmas_smps_set_ramp_delay, |
507 | }; | 396 | }; |
508 | 397 | ||
@@ -511,9 +400,9 @@ static struct regulator_ops palmas_ops_ext_control_smps = { | |||
511 | .get_mode = palmas_get_mode_smps, | 400 | .get_mode = palmas_get_mode_smps, |
512 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 401 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
513 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 402 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
514 | .list_voltage = palmas_list_voltage_smps, | 403 | .list_voltage = regulator_list_voltage_linear_range, |
515 | .map_voltage = palmas_map_voltage_smps, | 404 | .map_voltage = regulator_map_voltage_linear_range, |
516 | .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, | 405 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
517 | .set_ramp_delay = palmas_smps_set_ramp_delay, | 406 | .set_ramp_delay = palmas_smps_set_ramp_delay, |
518 | }; | 407 | }; |
519 | 408 | ||
@@ -1042,12 +931,17 @@ static int palmas_regulators_probe(struct platform_device *pdev) | |||
1042 | * ranges. Read the current smps mode for later use. | 931 | * ranges. Read the current smps mode for later use. |
1043 | */ | 932 | */ |
1044 | addr = palmas_regs_info[id].vsel_addr; | 933 | addr = palmas_regs_info[id].vsel_addr; |
934 | pmic->desc[id].n_linear_ranges = 3; | ||
1045 | 935 | ||
1046 | ret = palmas_smps_read(pmic->palmas, addr, ®); | 936 | ret = palmas_smps_read(pmic->palmas, addr, ®); |
1047 | if (ret) | 937 | if (ret) |
1048 | return ret; | 938 | return ret; |
1049 | if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) | 939 | if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) |
1050 | pmic->range[id] = 1; | 940 | pmic->range[id] = 1; |
941 | if (pmic->range[id]) | ||
942 | pmic->desc[id].linear_ranges = smps_high_ranges; | ||
943 | else | ||
944 | pmic->desc[id].linear_ranges = smps_low_ranges; | ||
1051 | 945 | ||
1052 | if (reg_init && reg_init->roof_floor) | 946 | if (reg_init && reg_init->roof_floor) |
1053 | pmic->desc[id].ops = | 947 | pmic->desc[id].ops = |
@@ -1199,7 +1093,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) | |||
1199 | return 0; | 1093 | return 0; |
1200 | } | 1094 | } |
1201 | 1095 | ||
1202 | static struct of_device_id of_palmas_match_tbl[] = { | 1096 | static const struct of_device_id of_palmas_match_tbl[] = { |
1203 | { .compatible = "ti,palmas-pmic", }, | 1097 | { .compatible = "ti,palmas-pmic", }, |
1204 | { .compatible = "ti,twl6035-pmic", }, | 1098 | { .compatible = "ti,twl6035-pmic", }, |
1205 | { .compatible = "ti,twl6036-pmic", }, | 1099 | { .compatible = "ti,twl6036-pmic", }, |
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index ded3b3574209..6d02d68dfb46 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c | |||
@@ -38,85 +38,24 @@ struct pbias_reg_info { | |||
38 | struct pbias_regulator_data { | 38 | struct pbias_regulator_data { |
39 | struct regulator_desc desc; | 39 | struct regulator_desc desc; |
40 | void __iomem *pbias_addr; | 40 | void __iomem *pbias_addr; |
41 | unsigned int pbias_reg; | ||
42 | struct regulator_dev *dev; | 41 | struct regulator_dev *dev; |
43 | struct regmap *syscon; | 42 | struct regmap *syscon; |
44 | const struct pbias_reg_info *info; | 43 | const struct pbias_reg_info *info; |
45 | int voltage; | 44 | int voltage; |
46 | }; | 45 | }; |
47 | 46 | ||
48 | static int pbias_regulator_set_voltage(struct regulator_dev *dev, | 47 | static const unsigned int pbias_volt_table[] = { |
49 | int min_uV, int max_uV, unsigned *selector) | 48 | 1800000, |
50 | { | 49 | 3000000 |
51 | struct pbias_regulator_data *data = rdev_get_drvdata(dev); | 50 | }; |
52 | const struct pbias_reg_info *info = data->info; | ||
53 | int ret, vmode; | ||
54 | |||
55 | if (min_uV <= 1800000) | ||
56 | vmode = 0; | ||
57 | else if (min_uV > 1800000) | ||
58 | vmode = info->vmode; | ||
59 | |||
60 | ret = regmap_update_bits(data->syscon, data->pbias_reg, | ||
61 | info->vmode, vmode); | ||
62 | |||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | static int pbias_regulator_get_voltage(struct regulator_dev *rdev) | ||
67 | { | ||
68 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
69 | const struct pbias_reg_info *info = data->info; | ||
70 | int value, voltage; | ||
71 | |||
72 | regmap_read(data->syscon, data->pbias_reg, &value); | ||
73 | value &= info->vmode; | ||
74 | |||
75 | voltage = value ? 3000000 : 1800000; | ||
76 | |||
77 | return voltage; | ||
78 | } | ||
79 | |||
80 | static int pbias_regulator_enable(struct regulator_dev *rdev) | ||
81 | { | ||
82 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
83 | const struct pbias_reg_info *info = data->info; | ||
84 | int ret; | ||
85 | |||
86 | ret = regmap_update_bits(data->syscon, data->pbias_reg, | ||
87 | info->enable_mask, info->enable); | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int pbias_regulator_disable(struct regulator_dev *rdev) | ||
93 | { | ||
94 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
95 | const struct pbias_reg_info *info = data->info; | ||
96 | int ret; | ||
97 | |||
98 | ret = regmap_update_bits(data->syscon, data->pbias_reg, | ||
99 | info->enable_mask, 0); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | static int pbias_regulator_is_enable(struct regulator_dev *rdev) | ||
104 | { | ||
105 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
106 | const struct pbias_reg_info *info = data->info; | ||
107 | int value; | ||
108 | |||
109 | regmap_read(data->syscon, data->pbias_reg, &value); | ||
110 | |||
111 | return (value & info->enable_mask) == info->enable_mask; | ||
112 | } | ||
113 | 51 | ||
114 | static struct regulator_ops pbias_regulator_voltage_ops = { | 52 | static struct regulator_ops pbias_regulator_voltage_ops = { |
115 | .set_voltage = pbias_regulator_set_voltage, | 53 | .list_voltage = regulator_list_voltage_table, |
116 | .get_voltage = pbias_regulator_get_voltage, | 54 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
117 | .enable = pbias_regulator_enable, | 55 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
118 | .disable = pbias_regulator_disable, | 56 | .enable = regulator_enable_regmap, |
119 | .is_enabled = pbias_regulator_is_enable, | 57 | .disable = regulator_disable_regmap, |
58 | .is_enabled = regulator_is_enabled_regmap, | ||
120 | }; | 59 | }; |
121 | 60 | ||
122 | static const struct pbias_reg_info pbias_mmc_omap2430 = { | 61 | static const struct pbias_reg_info pbias_mmc_omap2430 = { |
@@ -183,15 +122,14 @@ static int pbias_regulator_probe(struct platform_device *pdev) | |||
183 | 122 | ||
184 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct pbias_regulator_data) | 123 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct pbias_regulator_data) |
185 | * count, GFP_KERNEL); | 124 | * count, GFP_KERNEL); |
186 | if (drvdata == NULL) { | 125 | if (!drvdata) |
187 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | ||
188 | return -ENOMEM; | 126 | return -ENOMEM; |
189 | } | ||
190 | 127 | ||
191 | syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); | 128 | syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); |
192 | if (IS_ERR(syscon)) | 129 | if (IS_ERR(syscon)) |
193 | return PTR_ERR(syscon); | 130 | return PTR_ERR(syscon); |
194 | 131 | ||
132 | cfg.regmap = syscon; | ||
195 | cfg.dev = &pdev->dev; | 133 | cfg.dev = &pdev->dev; |
196 | 134 | ||
197 | for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) { | 135 | for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) { |
@@ -207,15 +145,20 @@ static int pbias_regulator_probe(struct platform_device *pdev) | |||
207 | if (!res) | 145 | if (!res) |
208 | return -EINVAL; | 146 | return -EINVAL; |
209 | 147 | ||
210 | drvdata[data_idx].pbias_reg = res->start; | ||
211 | drvdata[data_idx].syscon = syscon; | 148 | drvdata[data_idx].syscon = syscon; |
212 | drvdata[data_idx].info = info; | 149 | drvdata[data_idx].info = info; |
213 | drvdata[data_idx].desc.name = info->name; | 150 | drvdata[data_idx].desc.name = info->name; |
214 | drvdata[data_idx].desc.owner = THIS_MODULE; | 151 | drvdata[data_idx].desc.owner = THIS_MODULE; |
215 | drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; | 152 | drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; |
216 | drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; | 153 | drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; |
154 | drvdata[data_idx].desc.volt_table = pbias_volt_table; | ||
217 | drvdata[data_idx].desc.n_voltages = 2; | 155 | drvdata[data_idx].desc.n_voltages = 2; |
218 | drvdata[data_idx].desc.enable_time = info->enable_time; | 156 | drvdata[data_idx].desc.enable_time = info->enable_time; |
157 | drvdata[data_idx].desc.vsel_reg = res->start; | ||
158 | drvdata[data_idx].desc.vsel_mask = info->vmode; | ||
159 | drvdata[data_idx].desc.enable_reg = res->start; | ||
160 | drvdata[data_idx].desc.enable_mask = info->enable_mask; | ||
161 | drvdata[data_idx].desc.enable_val = info->enable; | ||
219 | 162 | ||
220 | cfg.init_data = pbias_matches[idx].init_data; | 163 | cfg.init_data = pbias_matches[idx].init_data; |
221 | cfg.driver_data = &drvdata[data_idx]; | 164 | cfg.driver_data = &drvdata[data_idx]; |
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 67e678c4301c..c879dff597ee 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c | |||
@@ -125,6 +125,9 @@ static struct regulator_ops pfuze100_ldo_regulator_ops = { | |||
125 | }; | 125 | }; |
126 | 126 | ||
127 | static struct regulator_ops pfuze100_fixed_regulator_ops = { | 127 | static struct regulator_ops pfuze100_fixed_regulator_ops = { |
128 | .enable = regulator_enable_regmap, | ||
129 | .disable = regulator_disable_regmap, | ||
130 | .is_enabled = regulator_is_enabled_regmap, | ||
128 | .list_voltage = regulator_list_voltage_linear, | 131 | .list_voltage = regulator_list_voltage_linear, |
129 | }; | 132 | }; |
130 | 133 | ||
@@ -137,6 +140,8 @@ static struct regulator_ops pfuze100_sw_regulator_ops = { | |||
137 | }; | 140 | }; |
138 | 141 | ||
139 | static struct regulator_ops pfuze100_swb_regulator_ops = { | 142 | static struct regulator_ops pfuze100_swb_regulator_ops = { |
143 | .enable = regulator_enable_regmap, | ||
144 | .disable = regulator_disable_regmap, | ||
140 | .list_voltage = regulator_list_voltage_table, | 145 | .list_voltage = regulator_list_voltage_table, |
141 | .map_voltage = regulator_map_voltage_ascend, | 146 | .map_voltage = regulator_map_voltage_ascend, |
142 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 147 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
@@ -189,6 +194,8 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
189 | .volt_table = voltages, \ | 194 | .volt_table = voltages, \ |
190 | .vsel_reg = (base), \ | 195 | .vsel_reg = (base), \ |
191 | .vsel_mask = (mask), \ | 196 | .vsel_mask = (mask), \ |
197 | .enable_reg = (base), \ | ||
198 | .enable_mask = 0x48, \ | ||
192 | }, \ | 199 | }, \ |
193 | } | 200 | } |
194 | 201 | ||
@@ -502,6 +509,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
502 | config.init_data = init_data; | 509 | config.init_data = init_data; |
503 | config.driver_data = pfuze_chip; | 510 | config.driver_data = pfuze_chip; |
504 | config.of_node = match_of_node(i); | 511 | config.of_node = match_of_node(i); |
512 | config.ena_gpio = -EINVAL; | ||
505 | 513 | ||
506 | pfuze_chip->regulators[i] = | 514 | pfuze_chip->regulators[i] = |
507 | devm_regulator_register(&client->dev, desc, &config); | 515 | devm_regulator_register(&client->dev, desc, &config); |
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index f19a30f0fb42..ee83b4876420 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c | |||
@@ -61,7 +61,7 @@ static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | |||
61 | unsigned int ramp_delay = 0; | 61 | unsigned int ramp_delay = 0; |
62 | int old_volt, new_volt; | 62 | int old_volt, new_volt; |
63 | 63 | ||
64 | switch (rdev->desc->id) { | 64 | switch (rdev_get_id(rdev)) { |
65 | case S2MPA01_BUCK2: | 65 | case S2MPA01_BUCK2: |
66 | case S2MPA01_BUCK4: | 66 | case S2MPA01_BUCK4: |
67 | ramp_delay = s2mpa01->ramp_delay24; | 67 | ramp_delay = s2mpa01->ramp_delay24; |
@@ -102,7 +102,7 @@ static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
102 | unsigned int ramp_enable = 1, enable_shift = 0; | 102 | unsigned int ramp_enable = 1, enable_shift = 0; |
103 | int ret; | 103 | int ret; |
104 | 104 | ||
105 | switch (rdev->desc->id) { | 105 | switch (rdev_get_id(rdev)) { |
106 | case S2MPA01_BUCK1: | 106 | case S2MPA01_BUCK1: |
107 | enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT; | 107 | enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT; |
108 | if (!ramp_delay) { | 108 | if (!ramp_delay) { |
@@ -116,7 +116,6 @@ static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
116 | ramp_delay = s2mpa01->ramp_delay16; | 116 | ramp_delay = s2mpa01->ramp_delay16; |
117 | 117 | ||
118 | ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; | 118 | ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT; |
119 | ramp_reg = S2MPA01_REG_RAMP1; | ||
120 | break; | 119 | break; |
121 | case S2MPA01_BUCK2: | 120 | case S2MPA01_BUCK2: |
122 | enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT; | 121 | enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT; |
@@ -192,11 +191,15 @@ static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
192 | if (!ramp_enable) | 191 | if (!ramp_enable) |
193 | goto ramp_disable; | 192 | goto ramp_disable; |
194 | 193 | ||
195 | ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, | 194 | /* Ramp delay can be enabled/disabled only for buck[1234] */ |
196 | 1 << enable_shift, 1 << enable_shift); | 195 | if (rdev_get_id(rdev) >= S2MPA01_BUCK1 && |
197 | if (ret) { | 196 | rdev_get_id(rdev) <= S2MPA01_BUCK4) { |
198 | dev_err(&rdev->dev, "failed to enable ramp rate\n"); | 197 | ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1, |
199 | return ret; | 198 | 1 << enable_shift, 1 << enable_shift); |
199 | if (ret) { | ||
200 | dev_err(&rdev->dev, "failed to enable ramp rate\n"); | ||
201 | return ret; | ||
202 | } | ||
200 | } | 203 | } |
201 | 204 | ||
202 | ramp_val = get_ramp_delay(ramp_delay); | 205 | ramp_val = get_ramp_delay(ramp_delay); |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index e713c162fbd4..02e2fb2fca66 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/regulator/driver.h> | 27 | #include <linux/regulator/driver.h> |
28 | #include <linux/regulator/machine.h> | 28 | #include <linux/regulator/machine.h> |
29 | #include <linux/regulator/of_regulator.h> | 29 | #include <linux/regulator/of_regulator.h> |
30 | #include <linux/of_gpio.h> | ||
30 | #include <linux/mfd/samsung/core.h> | 31 | #include <linux/mfd/samsung/core.h> |
31 | #include <linux/mfd/samsung/s2mps11.h> | 32 | #include <linux/mfd/samsung/s2mps11.h> |
32 | #include <linux/mfd/samsung/s2mps14.h> | 33 | #include <linux/mfd/samsung/s2mps14.h> |
@@ -44,6 +45,8 @@ struct s2mps11_info { | |||
44 | * was enabled. | 45 | * was enabled. |
45 | */ | 46 | */ |
46 | unsigned int s2mps14_suspend_state:30; | 47 | unsigned int s2mps14_suspend_state:30; |
48 | /* Array of size rdev_num with GPIO-s for external sleep control */ | ||
49 | int *ext_control_gpio; | ||
47 | }; | 50 | }; |
48 | 51 | ||
49 | static int get_ramp_delay(int ramp_delay) | 52 | static int get_ramp_delay(int ramp_delay) |
@@ -202,11 +205,16 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
202 | if (!ramp_enable) | 205 | if (!ramp_enable) |
203 | goto ramp_disable; | 206 | goto ramp_disable; |
204 | 207 | ||
205 | ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP, | 208 | /* Ramp delay can be enabled/disabled only for buck[2346] */ |
206 | 1 << enable_shift, 1 << enable_shift); | 209 | if ((rdev_get_id(rdev) >= S2MPS11_BUCK2 && |
207 | if (ret) { | 210 | rdev_get_id(rdev) <= S2MPS11_BUCK4) || |
208 | dev_err(&rdev->dev, "failed to enable ramp rate\n"); | 211 | rdev_get_id(rdev) == S2MPS11_BUCK6) { |
209 | return ret; | 212 | ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP, |
213 | 1 << enable_shift, 1 << enable_shift); | ||
214 | if (ret) { | ||
215 | dev_err(&rdev->dev, "failed to enable ramp rate\n"); | ||
216 | return ret; | ||
217 | } | ||
210 | } | 218 | } |
211 | 219 | ||
212 | ramp_val = get_ramp_delay(ramp_delay); | 220 | ramp_val = get_ramp_delay(ramp_delay); |
@@ -409,6 +417,8 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) | |||
409 | 417 | ||
410 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | 418 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) |
411 | val = S2MPS14_ENABLE_SUSPEND; | 419 | val = S2MPS14_ENABLE_SUSPEND; |
420 | else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) | ||
421 | val = S2MPS14_ENABLE_EXT_CONTROL; | ||
412 | else | 422 | else |
413 | val = rdev->desc->enable_mask; | 423 | val = rdev->desc->enable_mask; |
414 | 424 | ||
@@ -565,12 +575,61 @@ static const struct regulator_desc s2mps14_regulators[] = { | |||
565 | regulator_desc_s2mps14_buck1235(5), | 575 | regulator_desc_s2mps14_buck1235(5), |
566 | }; | 576 | }; |
567 | 577 | ||
578 | static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, | ||
579 | struct regulator_dev *rdev) | ||
580 | { | ||
581 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
582 | rdev->desc->enable_mask, S2MPS14_ENABLE_EXT_CONTROL); | ||
583 | } | ||
584 | |||
585 | static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev, | ||
586 | struct of_regulator_match *rdata, struct s2mps11_info *s2mps11) | ||
587 | { | ||
588 | int *gpio = s2mps11->ext_control_gpio; | ||
589 | unsigned int i; | ||
590 | unsigned int valid_regulators[3] = { S2MPS14_LDO10, S2MPS14_LDO11, | ||
591 | S2MPS14_LDO12 }; | ||
592 | |||
593 | for (i = 0; i < ARRAY_SIZE(valid_regulators); i++) { | ||
594 | unsigned int reg = valid_regulators[i]; | ||
595 | |||
596 | if (!rdata[reg].init_data || !rdata[reg].of_node) | ||
597 | continue; | ||
598 | |||
599 | gpio[reg] = of_get_named_gpio(rdata[reg].of_node, | ||
600 | "samsung,ext-control-gpios", 0); | ||
601 | if (gpio_is_valid(gpio[reg])) | ||
602 | dev_dbg(&pdev->dev, "Using GPIO %d for ext-control over %d/%s\n", | ||
603 | gpio[reg], reg, rdata[reg].name); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | static int s2mps11_pmic_dt_parse(struct platform_device *pdev, | ||
608 | struct of_regulator_match *rdata, struct s2mps11_info *s2mps11, | ||
609 | enum sec_device_type dev_type) | ||
610 | { | ||
611 | struct device_node *reg_np; | ||
612 | |||
613 | reg_np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); | ||
614 | if (!reg_np) { | ||
615 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | ||
616 | return -EINVAL; | ||
617 | } | ||
618 | |||
619 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); | ||
620 | if (dev_type == S2MPS14X) | ||
621 | s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); | ||
622 | |||
623 | of_node_put(reg_np); | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
568 | static int s2mps11_pmic_probe(struct platform_device *pdev) | 628 | static int s2mps11_pmic_probe(struct platform_device *pdev) |
569 | { | 629 | { |
570 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 630 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
571 | struct sec_platform_data *pdata = iodev->pdata; | 631 | struct sec_platform_data *pdata = NULL; |
572 | struct of_regulator_match *rdata = NULL; | 632 | struct of_regulator_match *rdata = NULL; |
573 | struct device_node *reg_np = NULL; | ||
574 | struct regulator_config config = { }; | 633 | struct regulator_config config = { }; |
575 | struct s2mps11_info *s2mps11; | 634 | struct s2mps11_info *s2mps11; |
576 | int i, ret = 0; | 635 | int i, ret = 0; |
@@ -597,8 +656,21 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
597 | return -EINVAL; | 656 | return -EINVAL; |
598 | }; | 657 | }; |
599 | 658 | ||
659 | s2mps11->ext_control_gpio = devm_kzalloc(&pdev->dev, | ||
660 | sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num, | ||
661 | GFP_KERNEL); | ||
662 | if (!s2mps11->ext_control_gpio) | ||
663 | return -ENOMEM; | ||
664 | /* | ||
665 | * 0 is a valid GPIO so initialize all GPIO-s to negative value | ||
666 | * to indicate that external control won't be used for this regulator. | ||
667 | */ | ||
668 | for (i = 0; i < s2mps11->rdev_num; i++) | ||
669 | s2mps11->ext_control_gpio[i] = -EINVAL; | ||
670 | |||
600 | if (!iodev->dev->of_node) { | 671 | if (!iodev->dev->of_node) { |
601 | if (pdata) { | 672 | if (iodev->pdata) { |
673 | pdata = iodev->pdata; | ||
602 | goto common_reg; | 674 | goto common_reg; |
603 | } else { | 675 | } else { |
604 | dev_err(pdev->dev.parent, | 676 | dev_err(pdev->dev.parent, |
@@ -614,15 +686,9 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
614 | for (i = 0; i < s2mps11->rdev_num; i++) | 686 | for (i = 0; i < s2mps11->rdev_num; i++) |
615 | rdata[i].name = regulators[i].name; | 687 | rdata[i].name = regulators[i].name; |
616 | 688 | ||
617 | reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); | 689 | ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type); |
618 | if (!reg_np) { | 690 | if (ret) |
619 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | ||
620 | ret = -EINVAL; | ||
621 | goto out; | 691 | goto out; |
622 | } | ||
623 | |||
624 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); | ||
625 | of_node_put(reg_np); | ||
626 | 692 | ||
627 | common_reg: | 693 | common_reg: |
628 | platform_set_drvdata(pdev, s2mps11); | 694 | platform_set_drvdata(pdev, s2mps11); |
@@ -630,16 +696,18 @@ common_reg: | |||
630 | config.dev = &pdev->dev; | 696 | config.dev = &pdev->dev; |
631 | config.regmap = iodev->regmap_pmic; | 697 | config.regmap = iodev->regmap_pmic; |
632 | config.driver_data = s2mps11; | 698 | config.driver_data = s2mps11; |
699 | config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
633 | for (i = 0; i < s2mps11->rdev_num; i++) { | 700 | for (i = 0; i < s2mps11->rdev_num; i++) { |
634 | struct regulator_dev *regulator; | 701 | struct regulator_dev *regulator; |
635 | 702 | ||
636 | if (!reg_np) { | 703 | if (pdata) { |
637 | config.init_data = pdata->regulators[i].initdata; | 704 | config.init_data = pdata->regulators[i].initdata; |
638 | config.of_node = pdata->regulators[i].reg_node; | 705 | config.of_node = pdata->regulators[i].reg_node; |
639 | } else { | 706 | } else { |
640 | config.init_data = rdata[i].init_data; | 707 | config.init_data = rdata[i].init_data; |
641 | config.of_node = rdata[i].of_node; | 708 | config.of_node = rdata[i].of_node; |
642 | } | 709 | } |
710 | config.ena_gpio = s2mps11->ext_control_gpio[i]; | ||
643 | 711 | ||
644 | regulator = devm_regulator_register(&pdev->dev, | 712 | regulator = devm_regulator_register(&pdev->dev, |
645 | ®ulators[i], &config); | 713 | ®ulators[i], &config); |
@@ -649,6 +717,17 @@ common_reg: | |||
649 | i); | 717 | i); |
650 | goto out; | 718 | goto out; |
651 | } | 719 | } |
720 | |||
721 | if (gpio_is_valid(s2mps11->ext_control_gpio[i])) { | ||
722 | ret = s2mps14_pmic_enable_ext_control(s2mps11, | ||
723 | regulator); | ||
724 | if (ret < 0) { | ||
725 | dev_err(&pdev->dev, | ||
726 | "failed to enable GPIO control over %s: %d\n", | ||
727 | regulator->desc->name, ret); | ||
728 | goto out; | ||
729 | } | ||
730 | } | ||
652 | } | 731 | } |
653 | 732 | ||
654 | out: | 733 | out: |
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 92f19a005dc3..c79af943a5c0 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c | |||
@@ -28,7 +28,6 @@ struct s5m8767_info { | |||
28 | struct device *dev; | 28 | struct device *dev; |
29 | struct sec_pmic_dev *iodev; | 29 | struct sec_pmic_dev *iodev; |
30 | int num_regulators; | 30 | int num_regulators; |
31 | struct regulator_dev **rdev; | ||
32 | struct sec_opmode_data *opmode; | 31 | struct sec_opmode_data *opmode; |
33 | 32 | ||
34 | int ramp_delay; | 33 | int ramp_delay; |
@@ -529,16 +528,6 @@ static int s5m8767_pmic_dt_parse_ds_gpio(struct sec_pmic_dev *iodev, | |||
529 | return 0; | 528 | return 0; |
530 | } | 529 | } |
531 | 530 | ||
532 | static void s5m8767_pmic_dt_parse_ext_control_gpio(struct sec_pmic_dev *iodev, | ||
533 | struct sec_regulator_data *rdata, | ||
534 | struct device_node *reg_np) | ||
535 | { | ||
536 | rdata->ext_control_gpio = of_get_named_gpio(reg_np, | ||
537 | "s5m8767,pmic-ext-control-gpios", 0); | ||
538 | if (!gpio_is_valid(rdata->ext_control_gpio)) | ||
539 | rdata->ext_control_gpio = 0; | ||
540 | } | ||
541 | |||
542 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | 531 | static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, |
543 | struct sec_platform_data *pdata) | 532 | struct sec_platform_data *pdata) |
544 | { | 533 | { |
@@ -587,7 +576,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
587 | continue; | 576 | continue; |
588 | } | 577 | } |
589 | 578 | ||
590 | s5m8767_pmic_dt_parse_ext_control_gpio(iodev, rdata, reg_np); | 579 | rdata->ext_control_gpio = of_get_named_gpio(reg_np, |
580 | "s5m8767,pmic-ext-control-gpios", 0); | ||
591 | 581 | ||
592 | rdata->id = i; | 582 | rdata->id = i; |
593 | rdata->initdata = of_get_regulator_init_data( | 583 | rdata->initdata = of_get_regulator_init_data( |
@@ -695,7 +685,6 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
695 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 685 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
696 | struct sec_platform_data *pdata = iodev->pdata; | 686 | struct sec_platform_data *pdata = iodev->pdata; |
697 | struct regulator_config config = { }; | 687 | struct regulator_config config = { }; |
698 | struct regulator_dev **rdev; | ||
699 | struct s5m8767_info *s5m8767; | 688 | struct s5m8767_info *s5m8767; |
700 | int i, ret, size, buck_init; | 689 | int i, ret, size, buck_init; |
701 | 690 | ||
@@ -737,11 +726,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
737 | return -ENOMEM; | 726 | return -ENOMEM; |
738 | 727 | ||
739 | size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); | 728 | size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); |
740 | s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | ||
741 | if (!s5m8767->rdev) | ||
742 | return -ENOMEM; | ||
743 | 729 | ||
744 | rdev = s5m8767->rdev; | ||
745 | s5m8767->dev = &pdev->dev; | 730 | s5m8767->dev = &pdev->dev; |
746 | s5m8767->iodev = iodev; | 731 | s5m8767->iodev = iodev; |
747 | s5m8767->num_regulators = pdata->num_regulators; | 732 | s5m8767->num_regulators = pdata->num_regulators; |
@@ -938,6 +923,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
938 | const struct sec_voltage_desc *desc; | 923 | const struct sec_voltage_desc *desc; |
939 | int id = pdata->regulators[i].id; | 924 | int id = pdata->regulators[i].id; |
940 | int enable_reg, enable_val; | 925 | int enable_reg, enable_val; |
926 | struct regulator_dev *rdev; | ||
941 | 927 | ||
942 | desc = reg_voltage_map[id]; | 928 | desc = reg_voltage_map[id]; |
943 | if (desc) { | 929 | if (desc) { |
@@ -964,26 +950,27 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
964 | config.driver_data = s5m8767; | 950 | config.driver_data = s5m8767; |
965 | config.regmap = iodev->regmap_pmic; | 951 | config.regmap = iodev->regmap_pmic; |
966 | config.of_node = pdata->regulators[i].reg_node; | 952 | config.of_node = pdata->regulators[i].reg_node; |
967 | config.ena_gpio = config.ena_gpio_flags = 0; | 953 | config.ena_gpio = -EINVAL; |
968 | if (pdata->regulators[i].ext_control_gpio) | 954 | config.ena_gpio_flags = 0; |
955 | if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) | ||
969 | s5m8767_regulator_config_ext_control(s5m8767, | 956 | s5m8767_regulator_config_ext_control(s5m8767, |
970 | &pdata->regulators[i], &config); | 957 | &pdata->regulators[i], &config); |
971 | 958 | ||
972 | rdev[i] = devm_regulator_register(&pdev->dev, ®ulators[id], | 959 | rdev = devm_regulator_register(&pdev->dev, ®ulators[id], |
973 | &config); | 960 | &config); |
974 | if (IS_ERR(rdev[i])) { | 961 | if (IS_ERR(rdev)) { |
975 | ret = PTR_ERR(rdev[i]); | 962 | ret = PTR_ERR(rdev); |
976 | dev_err(s5m8767->dev, "regulator init failed for %d\n", | 963 | dev_err(s5m8767->dev, "regulator init failed for %d\n", |
977 | id); | 964 | id); |
978 | return ret; | 965 | return ret; |
979 | } | 966 | } |
980 | 967 | ||
981 | if (pdata->regulators[i].ext_control_gpio) { | 968 | if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) { |
982 | ret = s5m8767_enable_ext_control(s5m8767, rdev[i]); | 969 | ret = s5m8767_enable_ext_control(s5m8767, rdev); |
983 | if (ret < 0) { | 970 | if (ret < 0) { |
984 | dev_err(s5m8767->dev, | 971 | dev_err(s5m8767->dev, |
985 | "failed to enable gpio control over %s: %d\n", | 972 | "failed to enable gpio control over %s: %d\n", |
986 | rdev[i]->desc->name, ret); | 973 | rdev->desc->name, ret); |
987 | return ret; | 974 | return ret; |
988 | } | 975 | } |
989 | } | 976 | } |
diff --git a/drivers/regulator/st-pwm.c b/drivers/regulator/st-pwm.c index e367af1c5f9d..5ea78df449f8 100644 --- a/drivers/regulator/st-pwm.c +++ b/drivers/regulator/st-pwm.c | |||
@@ -118,7 +118,7 @@ static const struct st_pwm_regulator_pdata b2105_info = { | |||
118 | .duty_cycle_table = b2105_duty_cycle_table, | 118 | .duty_cycle_table = b2105_duty_cycle_table, |
119 | }; | 119 | }; |
120 | 120 | ||
121 | static struct of_device_id st_pwm_of_match[] = { | 121 | static const struct of_device_id st_pwm_of_match[] = { |
122 | { .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, }, | 122 | { .compatible = "st,b2105-pwm-regulator", .data = &b2105_info, }, |
123 | { }, | 123 | { }, |
124 | }; | 124 | }; |
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 2e92ef68574d..2064b3fd45f7 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/delay.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
22 | #include <linux/of_gpio.h> | 23 | #include <linux/of_gpio.h> |
@@ -28,49 +29,216 @@ | |||
28 | #include <linux/regulator/of_regulator.h> | 29 | #include <linux/regulator/of_regulator.h> |
29 | #include <linux/mfd/tps65090.h> | 30 | #include <linux/mfd/tps65090.h> |
30 | 31 | ||
32 | #define MAX_CTRL_READ_TRIES 5 | ||
33 | #define MAX_FET_ENABLE_TRIES 1000 | ||
34 | |||
35 | #define CTRL_EN_BIT 0 /* Regulator enable bit, active high */ | ||
36 | #define CTRL_WT_BIT 2 /* Regulator wait time 0 bit */ | ||
37 | #define CTRL_PG_BIT 4 /* Regulator power good bit, 1=good */ | ||
38 | #define CTRL_TO_BIT 7 /* Regulator timeout bit, 1=wait */ | ||
39 | |||
40 | #define MAX_OVERCURRENT_WAIT 3 /* Overcurrent wait must be <= this */ | ||
41 | |||
42 | /** | ||
43 | * struct tps65090_regulator - Per-regulator data for a tps65090 regulator | ||
44 | * | ||
45 | * @dev: Pointer to our device. | ||
46 | * @desc: The struct regulator_desc for the regulator. | ||
47 | * @rdev: The struct regulator_dev for the regulator. | ||
48 | * @overcurrent_wait_valid: True if overcurrent_wait is valid. | ||
49 | * @overcurrent_wait: For FETs, the value to put in the WTFET bitfield. | ||
50 | */ | ||
51 | |||
31 | struct tps65090_regulator { | 52 | struct tps65090_regulator { |
32 | struct device *dev; | 53 | struct device *dev; |
33 | struct regulator_desc *desc; | 54 | struct regulator_desc *desc; |
34 | struct regulator_dev *rdev; | 55 | struct regulator_dev *rdev; |
56 | bool overcurrent_wait_valid; | ||
57 | int overcurrent_wait; | ||
35 | }; | 58 | }; |
36 | 59 | ||
37 | static struct regulator_ops tps65090_ext_control_ops = { | 60 | static struct regulator_ops tps65090_ext_control_ops = { |
38 | }; | 61 | }; |
39 | 62 | ||
40 | static struct regulator_ops tps65090_reg_contol_ops = { | 63 | /** |
64 | * tps65090_reg_set_overcurrent_wait - Setup overcurrent wait | ||
65 | * | ||
66 | * This will set the overcurrent wait time based on what's in the regulator | ||
67 | * info. | ||
68 | * | ||
69 | * @ri: Overall regulator data | ||
70 | * @rdev: Regulator device | ||
71 | * | ||
72 | * Return: 0 if no error, non-zero if there was an error writing the register. | ||
73 | */ | ||
74 | static int tps65090_reg_set_overcurrent_wait(struct tps65090_regulator *ri, | ||
75 | struct regulator_dev *rdev) | ||
76 | { | ||
77 | int ret; | ||
78 | |||
79 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
80 | MAX_OVERCURRENT_WAIT << CTRL_WT_BIT, | ||
81 | ri->overcurrent_wait << CTRL_WT_BIT); | ||
82 | if (ret) { | ||
83 | dev_err(&rdev->dev, "Error updating overcurrent wait %#x\n", | ||
84 | rdev->desc->enable_reg); | ||
85 | } | ||
86 | |||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * tps65090_try_enable_fet - Try to enable a FET | ||
92 | * | ||
93 | * @rdev: Regulator device | ||
94 | * | ||
95 | * Return: 0 if ok, -ENOTRECOVERABLE if the FET power good bit did not get | ||
96 | * set, or some other -ve value if another error occurred (e.g. i2c error) | ||
97 | */ | ||
98 | static int tps65090_try_enable_fet(struct regulator_dev *rdev) | ||
99 | { | ||
100 | unsigned int control; | ||
101 | int ret, i; | ||
102 | |||
103 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
104 | rdev->desc->enable_mask, | ||
105 | rdev->desc->enable_mask); | ||
106 | if (ret < 0) { | ||
107 | dev_err(&rdev->dev, "Error in updating reg %#x\n", | ||
108 | rdev->desc->enable_reg); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | for (i = 0; i < MAX_CTRL_READ_TRIES; i++) { | ||
113 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, | ||
114 | &control); | ||
115 | if (ret < 0) | ||
116 | return ret; | ||
117 | |||
118 | if (!(control & BIT(CTRL_TO_BIT))) | ||
119 | break; | ||
120 | |||
121 | usleep_range(1000, 1500); | ||
122 | } | ||
123 | if (!(control & BIT(CTRL_PG_BIT))) | ||
124 | return -ENOTRECOVERABLE; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * tps65090_fet_enable - Enable a FET, trying a few times if it fails | ||
131 | * | ||
132 | * Some versions of the tps65090 have issues when turning on the FETs. | ||
133 | * This function goes through several steps to ensure the best chance of the | ||
134 | * FET going on. Specifically: | ||
135 | * - We'll make sure that we bump the "overcurrent wait" to the maximum, which | ||
136 | * increases the chances that we'll turn on properly. | ||
137 | * - We'll retry turning the FET on multiple times (turning off in between). | ||
138 | * | ||
139 | * @rdev: Regulator device | ||
140 | * | ||
141 | * Return: 0 if ok, non-zero if it fails. | ||
142 | */ | ||
143 | static int tps65090_fet_enable(struct regulator_dev *rdev) | ||
144 | { | ||
145 | int ret, tries; | ||
146 | |||
147 | /* | ||
148 | * Try enabling multiple times until we succeed since sometimes the | ||
149 | * first try times out. | ||
150 | */ | ||
151 | tries = 0; | ||
152 | while (true) { | ||
153 | ret = tps65090_try_enable_fet(rdev); | ||
154 | if (!ret) | ||
155 | break; | ||
156 | if (ret != -ENOTRECOVERABLE || tries == MAX_FET_ENABLE_TRIES) | ||
157 | goto err; | ||
158 | |||
159 | /* Try turning the FET off (and then on again) */ | ||
160 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
161 | rdev->desc->enable_mask, 0); | ||
162 | if (ret) | ||
163 | goto err; | ||
164 | |||
165 | tries++; | ||
166 | } | ||
167 | |||
168 | if (tries) | ||
169 | dev_warn(&rdev->dev, "reg %#x enable ok after %d tries\n", | ||
170 | rdev->desc->enable_reg, tries); | ||
171 | |||
172 | return 0; | ||
173 | err: | ||
174 | dev_warn(&rdev->dev, "reg %#x enable failed\n", rdev->desc->enable_reg); | ||
175 | WARN_ON(1); | ||
176 | |||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | static struct regulator_ops tps65090_reg_control_ops = { | ||
41 | .enable = regulator_enable_regmap, | 181 | .enable = regulator_enable_regmap, |
42 | .disable = regulator_disable_regmap, | 182 | .disable = regulator_disable_regmap, |
43 | .is_enabled = regulator_is_enabled_regmap, | 183 | .is_enabled = regulator_is_enabled_regmap, |
44 | }; | 184 | }; |
45 | 185 | ||
186 | static struct regulator_ops tps65090_fet_control_ops = { | ||
187 | .enable = tps65090_fet_enable, | ||
188 | .disable = regulator_disable_regmap, | ||
189 | .is_enabled = regulator_is_enabled_regmap, | ||
190 | }; | ||
191 | |||
46 | static struct regulator_ops tps65090_ldo_ops = { | 192 | static struct regulator_ops tps65090_ldo_ops = { |
47 | }; | 193 | }; |
48 | 194 | ||
49 | #define tps65090_REG_DESC(_id, _sname, _en_reg, _ops) \ | 195 | #define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _ops) \ |
50 | { \ | 196 | { \ |
51 | .name = "TPS65090_RAILS"#_id, \ | 197 | .name = "TPS65090_RAILS"#_id, \ |
52 | .supply_name = _sname, \ | 198 | .supply_name = _sname, \ |
53 | .id = TPS65090_REGULATOR_##_id, \ | 199 | .id = TPS65090_REGULATOR_##_id, \ |
54 | .ops = &_ops, \ | 200 | .ops = &_ops, \ |
55 | .enable_reg = _en_reg, \ | 201 | .enable_reg = _en_reg, \ |
56 | .enable_mask = BIT(0), \ | 202 | .enable_val = _en_bits, \ |
203 | .enable_mask = _en_bits, \ | ||
57 | .type = REGULATOR_VOLTAGE, \ | 204 | .type = REGULATOR_VOLTAGE, \ |
58 | .owner = THIS_MODULE, \ | 205 | .owner = THIS_MODULE, \ |
59 | } | 206 | } |
60 | 207 | ||
61 | static struct regulator_desc tps65090_regulator_desc[] = { | 208 | static struct regulator_desc tps65090_regulator_desc[] = { |
62 | tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, tps65090_reg_contol_ops), | 209 | tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT), |
63 | tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, tps65090_reg_contol_ops), | 210 | tps65090_reg_control_ops), |
64 | tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, tps65090_reg_contol_ops), | 211 | tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT), |
65 | tps65090_REG_DESC(FET1, "infet1", 0x0F, tps65090_reg_contol_ops), | 212 | tps65090_reg_control_ops), |
66 | tps65090_REG_DESC(FET2, "infet2", 0x10, tps65090_reg_contol_ops), | 213 | tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT), |
67 | tps65090_REG_DESC(FET3, "infet3", 0x11, tps65090_reg_contol_ops), | 214 | tps65090_reg_control_ops), |
68 | tps65090_REG_DESC(FET4, "infet4", 0x12, tps65090_reg_contol_ops), | 215 | |
69 | tps65090_REG_DESC(FET5, "infet5", 0x13, tps65090_reg_contol_ops), | 216 | tps65090_REG_DESC(FET1, "infet1", 0x0F, |
70 | tps65090_REG_DESC(FET6, "infet6", 0x14, tps65090_reg_contol_ops), | 217 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), |
71 | tps65090_REG_DESC(FET7, "infet7", 0x15, tps65090_reg_contol_ops), | 218 | tps65090_fet_control_ops), |
72 | tps65090_REG_DESC(LDO1, "vsys-l1", 0, tps65090_ldo_ops), | 219 | tps65090_REG_DESC(FET2, "infet2", 0x10, |
73 | tps65090_REG_DESC(LDO2, "vsys-l2", 0, tps65090_ldo_ops), | 220 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), |
221 | tps65090_fet_control_ops), | ||
222 | tps65090_REG_DESC(FET3, "infet3", 0x11, | ||
223 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), | ||
224 | tps65090_fet_control_ops), | ||
225 | tps65090_REG_DESC(FET4, "infet4", 0x12, | ||
226 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), | ||
227 | tps65090_fet_control_ops), | ||
228 | tps65090_REG_DESC(FET5, "infet5", 0x13, | ||
229 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), | ||
230 | tps65090_fet_control_ops), | ||
231 | tps65090_REG_DESC(FET6, "infet6", 0x14, | ||
232 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), | ||
233 | tps65090_fet_control_ops), | ||
234 | tps65090_REG_DESC(FET7, "infet7", 0x15, | ||
235 | BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), | ||
236 | tps65090_fet_control_ops), | ||
237 | |||
238 | tps65090_REG_DESC(LDO1, "vsys-l1", 0, 0, | ||
239 | tps65090_ldo_ops), | ||
240 | tps65090_REG_DESC(LDO2, "vsys-l2", 0, 0, | ||
241 | tps65090_ldo_ops), | ||
74 | }; | 242 | }; |
75 | 243 | ||
76 | static inline bool is_dcdc(int id) | 244 | static inline bool is_dcdc(int id) |
@@ -209,6 +377,11 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data( | |||
209 | rpdata->gpio = of_get_named_gpio(np, | 377 | rpdata->gpio = of_get_named_gpio(np, |
210 | "dcdc-ext-control-gpios", 0); | 378 | "dcdc-ext-control-gpios", 0); |
211 | 379 | ||
380 | if (of_property_read_u32(tps65090_matches[idx].of_node, | ||
381 | "ti,overcurrent-wait", | ||
382 | &rpdata->overcurrent_wait) == 0) | ||
383 | rpdata->overcurrent_wait_valid = true; | ||
384 | |||
212 | tps65090_pdata->reg_pdata[idx] = rpdata; | 385 | tps65090_pdata->reg_pdata[idx] = rpdata; |
213 | } | 386 | } |
214 | return tps65090_pdata; | 387 | return tps65090_pdata; |
@@ -258,6 +431,11 @@ static int tps65090_regulator_probe(struct platform_device *pdev) | |||
258 | ri = &pmic[num]; | 431 | ri = &pmic[num]; |
259 | ri->dev = &pdev->dev; | 432 | ri->dev = &pdev->dev; |
260 | ri->desc = &tps65090_regulator_desc[num]; | 433 | ri->desc = &tps65090_regulator_desc[num]; |
434 | if (tps_pdata) { | ||
435 | ri->overcurrent_wait_valid = | ||
436 | tps_pdata->overcurrent_wait_valid; | ||
437 | ri->overcurrent_wait = tps_pdata->overcurrent_wait; | ||
438 | } | ||
261 | 439 | ||
262 | /* | 440 | /* |
263 | * TPS5090 DCDC support the control from external digital input. | 441 | * TPS5090 DCDC support the control from external digital input. |
@@ -299,6 +477,12 @@ static int tps65090_regulator_probe(struct platform_device *pdev) | |||
299 | } | 477 | } |
300 | ri->rdev = rdev; | 478 | ri->rdev = rdev; |
301 | 479 | ||
480 | if (ri->overcurrent_wait_valid) { | ||
481 | ret = tps65090_reg_set_overcurrent_wait(ri, rdev); | ||
482 | if (ret < 0) | ||
483 | return ret; | ||
484 | } | ||
485 | |||
302 | /* Enable external control if it is require */ | 486 | /* Enable external control if it is require */ |
303 | if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && | 487 | if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data && |
304 | tps_pdata->enable_ext_control) { | 488 | tps_pdata->enable_ext_control) { |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 10b78d2b766a..f7ed20a5a8b9 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -134,6 +134,7 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { | |||
134 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 134 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
135 | .set_voltage_sel = tps65217_pmic_set_voltage_sel, | 135 | .set_voltage_sel = tps65217_pmic_set_voltage_sel, |
136 | .list_voltage = regulator_list_voltage_table, | 136 | .list_voltage = regulator_list_voltage_table, |
137 | .map_voltage = regulator_map_voltage_ascend, | ||
137 | }; | 138 | }; |
138 | 139 | ||
139 | static const struct regulator_desc regulators[] = { | 140 | static const struct regulator_desc regulators[] = { |
@@ -257,9 +258,6 @@ static int tps65217_regulator_probe(struct platform_device *pdev) | |||
257 | pdev->name); | 258 | pdev->name); |
258 | return PTR_ERR(rdev); | 259 | return PTR_ERR(rdev); |
259 | } | 260 | } |
260 | |||
261 | /* Save regulator for cleanup */ | ||
262 | tps->rdev[i] = rdev; | ||
263 | } | 261 | } |
264 | return 0; | 262 | return 0; |
265 | } | 263 | } |
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index cec72fa71d1d..69b4b7750410 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c | |||
@@ -27,12 +27,10 @@ | |||
27 | #include <linux/regulator/machine.h> | 27 | #include <linux/regulator/machine.h> |
28 | #include <linux/mfd/tps65218.h> | 28 | #include <linux/mfd/tps65218.h> |
29 | 29 | ||
30 | static unsigned int tps65218_ramp_delay = 4000; | ||
31 | |||
32 | enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; | 30 | enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; |
33 | 31 | ||
34 | #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \ | 32 | #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \ |
35 | _lr, _nlr) \ | 33 | _lr, _nlr, _delay) \ |
36 | { \ | 34 | { \ |
37 | .name = _name, \ | 35 | .name = _name, \ |
38 | .id = _id, \ | 36 | .id = _id, \ |
@@ -47,6 +45,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; | |||
47 | .volt_table = _t, \ | 45 | .volt_table = _t, \ |
48 | .linear_ranges = _lr, \ | 46 | .linear_ranges = _lr, \ |
49 | .n_linear_ranges = _nlr, \ | 47 | .n_linear_ranges = _nlr, \ |
48 | .ramp_delay = _delay, \ | ||
50 | } \ | 49 | } \ |
51 | 50 | ||
52 | #define TPS65218_INFO(_id, _nm, _min, _max) \ | 51 | #define TPS65218_INFO(_id, _nm, _min, _max) \ |
@@ -152,22 +151,6 @@ static int tps65218_pmic_disable(struct regulator_dev *dev) | |||
152 | dev->desc->enable_mask, TPS65218_PROTECT_L1); | 151 | dev->desc->enable_mask, TPS65218_PROTECT_L1); |
153 | } | 152 | } |
154 | 153 | ||
155 | static int tps65218_set_voltage_time_sel(struct regulator_dev *rdev, | ||
156 | unsigned int old_selector, unsigned int new_selector) | ||
157 | { | ||
158 | int old_uv, new_uv; | ||
159 | |||
160 | old_uv = regulator_list_voltage_linear_range(rdev, old_selector); | ||
161 | if (old_uv < 0) | ||
162 | return old_uv; | ||
163 | |||
164 | new_uv = regulator_list_voltage_linear_range(rdev, new_selector); | ||
165 | if (new_uv < 0) | ||
166 | return new_uv; | ||
167 | |||
168 | return DIV_ROUND_UP(abs(old_uv - new_uv), tps65218_ramp_delay); | ||
169 | } | ||
170 | |||
171 | /* Operations permitted on DCDC1, DCDC2 */ | 154 | /* Operations permitted on DCDC1, DCDC2 */ |
172 | static struct regulator_ops tps65218_dcdc12_ops = { | 155 | static struct regulator_ops tps65218_dcdc12_ops = { |
173 | .is_enabled = regulator_is_enabled_regmap, | 156 | .is_enabled = regulator_is_enabled_regmap, |
@@ -177,7 +160,7 @@ static struct regulator_ops tps65218_dcdc12_ops = { | |||
177 | .set_voltage_sel = tps65218_pmic_set_voltage_sel, | 160 | .set_voltage_sel = tps65218_pmic_set_voltage_sel, |
178 | .list_voltage = regulator_list_voltage_linear_range, | 161 | .list_voltage = regulator_list_voltage_linear_range, |
179 | .map_voltage = regulator_map_voltage_linear_range, | 162 | .map_voltage = regulator_map_voltage_linear_range, |
180 | .set_voltage_time_sel = tps65218_set_voltage_time_sel, | 163 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
181 | }; | 164 | }; |
182 | 165 | ||
183 | /* Operations permitted on DCDC3, DCDC4 and LDO1 */ | 166 | /* Operations permitted on DCDC3, DCDC4 and LDO1 */ |
@@ -203,33 +186,33 @@ static const struct regulator_desc regulators[] = { | |||
203 | TPS65218_REG_CONTROL_DCDC1, | 186 | TPS65218_REG_CONTROL_DCDC1, |
204 | TPS65218_CONTROL_DCDC1_MASK, | 187 | TPS65218_CONTROL_DCDC1_MASK, |
205 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL, | 188 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL, |
206 | dcdc1_dcdc2_ranges, 2), | 189 | dcdc1_dcdc2_ranges, 2, 4000), |
207 | TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, | 190 | TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, |
208 | TPS65218_REG_CONTROL_DCDC2, | 191 | TPS65218_REG_CONTROL_DCDC2, |
209 | TPS65218_CONTROL_DCDC2_MASK, | 192 | TPS65218_CONTROL_DCDC2_MASK, |
210 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL, | 193 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL, |
211 | dcdc1_dcdc2_ranges, 2), | 194 | dcdc1_dcdc2_ranges, 2, 4000), |
212 | TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, | 195 | TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, |
213 | 64, TPS65218_REG_CONTROL_DCDC3, | 196 | 64, TPS65218_REG_CONTROL_DCDC3, |
214 | TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, | 197 | TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, |
215 | TPS65218_ENABLE1_DC3_EN, NULL, | 198 | TPS65218_ENABLE1_DC3_EN, NULL, |
216 | ldo1_dcdc3_ranges, 2), | 199 | ldo1_dcdc3_ranges, 2, 0), |
217 | TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, | 200 | TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, |
218 | 53, TPS65218_REG_CONTROL_DCDC4, | 201 | 53, TPS65218_REG_CONTROL_DCDC4, |
219 | TPS65218_CONTROL_DCDC4_MASK, | 202 | TPS65218_CONTROL_DCDC4_MASK, |
220 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL, | 203 | TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL, |
221 | dcdc4_ranges, 2), | 204 | dcdc4_ranges, 2, 0), |
222 | TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, | 205 | TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, |
223 | 1, -1, -1, TPS65218_REG_ENABLE1, | 206 | 1, -1, -1, TPS65218_REG_ENABLE1, |
224 | TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0), | 207 | TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0, 0), |
225 | TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, | 208 | TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, |
226 | 1, -1, -1, TPS65218_REG_ENABLE1, | 209 | 1, -1, -1, TPS65218_REG_ENABLE1, |
227 | TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0), | 210 | TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0), |
228 | TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, | 211 | TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, |
229 | TPS65218_REG_CONTROL_DCDC4, | 212 | TPS65218_REG_CONTROL_DCDC4, |
230 | TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, | 213 | TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, |
231 | TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, | 214 | TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, |
232 | 2), | 215 | 2, 0), |
233 | }; | 216 | }; |
234 | 217 | ||
235 | static int tps65218_regulator_probe(struct platform_device *pdev) | 218 | static int tps65218_regulator_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index f3ae28a7e663..147ecc7c11bf 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c | |||
@@ -123,7 +123,7 @@ static int vexpress_regulator_remove(struct platform_device *pdev) | |||
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
125 | 125 | ||
126 | static struct of_device_id vexpress_regulator_of_match[] = { | 126 | static const struct of_device_id vexpress_regulator_of_match[] = { |
127 | { .compatible = "arm,vexpress-volt", }, | 127 | { .compatible = "arm,vexpress-volt", }, |
128 | { } | 128 | { } |
129 | }; | 129 | }; |