aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatti Vaittinen <matti.vaittinen@fi.rohmeurope.com>2018-05-30 04:43:43 -0400
committerMark Brown <broonie@kernel.org>2018-05-30 06:31:22 -0400
commitba08799e90b5935a3df20766a73b5841046f6832 (patch)
treefb98a693669022c8011e71a78f8555195eabeda1
parent196c813570afd0d52d453ef3b77c4c15ca760327 (diff)
regulator: bd71837: BD71837 PMIC regulator driver
Support for controlling the 8 bucks and 7 LDOs the PMIC contains. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/Kconfig11
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/bd71837-regulator.c640
3 files changed, 652 insertions, 0 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 4efae3b7e746..5dbccf5f3037 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -180,6 +180,17 @@ config REGULATOR_BCM590XX
180 BCM590xx PMUs. This will enable support for the software 180 BCM590xx PMUs. This will enable support for the software
181 controllable LDO/Switching regulators. 181 controllable LDO/Switching regulators.
182 182
183config REGULATOR_BD71837
184 tristate "ROHM BD71837 Power Regulator"
185 depends on MFD_BD71837
186 help
187 This driver supports voltage regulators on ROHM BD71837 PMIC.
188 This will enable support for the software controllable buck
189 and LDO regulators.
190
191 This driver can also be built as a module. If so, the module
192 will be called bd71837-regulator.
193
183config REGULATOR_BD9571MWV 194config REGULATOR_BD9571MWV
184 tristate "ROHM BD9571MWV Regulators" 195 tristate "ROHM BD9571MWV Regulators"
185 depends on MFD_BD9571MWV 196 depends on MFD_BD9571MWV
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d81fb02bd6e9..bd818ceb7c72 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
27obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o 27obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
28obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o 28obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
29obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o 29obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
30obj-$(CONFIG_REGULATOR_BD71837) += bd71837-regulator.o
30obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o 31obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
31obj-$(CONFIG_REGULATOR_DA903X) += da903x.o 32obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
32obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o 33obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
new file mode 100644
index 000000000000..6eae4d0432a2
--- /dev/null
+++ b/drivers/regulator/bd71837-regulator.c
@@ -0,0 +1,640 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 ROHM Semiconductors
3// bd71837-regulator.c ROHM BD71837MWV regulator driver
4
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/init.h>
8#include <linux/err.h>
9#include <linux/interrupt.h>
10#include <linux/platform_device.h>
11#include <linux/regulator/driver.h>
12#include <linux/regulator/machine.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/gpio.h>
16#include <linux/mfd/bd71837.h>
17#include <linux/regulator/of_regulator.h>
18
19struct bd71837_pmic {
20 struct regulator_desc descs[BD71837_REGULATOR_CNT];
21 struct bd71837 *mfd;
22 struct platform_device *pdev;
23 struct regulator_dev *rdev[BD71837_REGULATOR_CNT];
24};
25
26/*
27 * BUCK1/2/3/4
28 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
29 * 00: 10.00mV/usec 10mV 1uS
30 * 01: 5.00mV/usec 10mV 2uS
31 * 10: 2.50mV/usec 10mV 4uS
32 * 11: 1.25mV/usec 10mV 8uS
33 */
34static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
35 int ramp_delay)
36{
37 struct bd71837_pmic *pmic = rdev_get_drvdata(rdev);
38 struct bd71837 *mfd = pmic->mfd;
39 int id = rdev->desc->id;
40 unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
41
42 dev_dbg(&(pmic->pdev->dev), "Buck[%d] Set Ramp = %d\n", id + 1,
43 ramp_delay);
44 switch (ramp_delay) {
45 case 1 ... 1250:
46 ramp_value = BUCK_RAMPRATE_1P25MV;
47 break;
48 case 1251 ... 2500:
49 ramp_value = BUCK_RAMPRATE_2P50MV;
50 break;
51 case 2501 ... 5000:
52 ramp_value = BUCK_RAMPRATE_5P00MV;
53 break;
54 case 5001 ... 10000:
55 ramp_value = BUCK_RAMPRATE_10P00MV;
56 break;
57 default:
58 ramp_value = BUCK_RAMPRATE_10P00MV;
59 dev_err(&pmic->pdev->dev,
60 "%s: ramp_delay: %d not supported, setting 10000mV//us\n",
61 rdev->desc->name, ramp_delay);
62 }
63
64 return regmap_update_bits(mfd->regmap, BD71837_REG_BUCK1_CTRL + id,
65 BUCK_RAMPRATE_MASK, ramp_value << 6);
66}
67
68/* Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
69 * Bucks 5 to 8 and LDOs can use PFM and must be disabled when voltage
70 * is changed. Hence we return -EBUSY for these if voltage is changed
71 * when BUCK/LDO is enabled.
72 */
73static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
74 unsigned int sel)
75{
76 int ret;
77
78 ret = regulator_is_enabled_regmap(rdev);
79 if (!ret)
80 ret = regulator_set_voltage_sel_regmap(rdev, sel);
81 else if (ret == 1)
82 ret = -EBUSY;
83 return ret;
84}
85
86static struct regulator_ops bd71837_ldo_regulator_ops = {
87 .enable = regulator_enable_regmap,
88 .disable = regulator_disable_regmap,
89 .is_enabled = regulator_is_enabled_regmap,
90 .list_voltage = regulator_list_voltage_linear_range,
91 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
92 .get_voltage_sel = regulator_get_voltage_sel_regmap,
93};
94
95static struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
96 .enable = regulator_enable_regmap,
97 .disable = regulator_disable_regmap,
98 .is_enabled = regulator_is_enabled_regmap,
99 .list_voltage = regulator_list_voltage_table,
100 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
101 .get_voltage_sel = regulator_get_voltage_sel_regmap,
102};
103
104static struct regulator_ops bd71837_buck_regulator_ops = {
105 .enable = regulator_enable_regmap,
106 .disable = regulator_disable_regmap,
107 .is_enabled = regulator_is_enabled_regmap,
108 .list_voltage = regulator_list_voltage_linear_range,
109 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
110 .get_voltage_sel = regulator_get_voltage_sel_regmap,
111 .set_voltage_time_sel = regulator_set_voltage_time_sel,
112};
113
114static struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
115 .enable = regulator_enable_regmap,
116 .disable = regulator_disable_regmap,
117 .is_enabled = regulator_is_enabled_regmap,
118 .list_voltage = regulator_list_voltage_table,
119 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
120 .get_voltage_sel = regulator_get_voltage_sel_regmap,
121 .set_voltage_time_sel = regulator_set_voltage_time_sel,
122};
123
124static struct regulator_ops bd71837_buck1234_regulator_ops = {
125 .enable = regulator_enable_regmap,
126 .disable = regulator_disable_regmap,
127 .is_enabled = regulator_is_enabled_regmap,
128 .list_voltage = regulator_list_voltage_linear_range,
129 .set_voltage_sel = regulator_set_voltage_sel_regmap,
130 .get_voltage_sel = regulator_get_voltage_sel_regmap,
131 .set_voltage_time_sel = regulator_set_voltage_time_sel,
132 .set_ramp_delay = bd71837_buck1234_set_ramp_delay,
133};
134
135/*
136 * BUCK1/2/3/4
137 * 0.70 to 1.30V (10mV step)
138 */
139static const struct regulator_linear_range bd71837_buck1234_voltage_ranges[] = {
140 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
141 REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
142};
143
144/*
145 * BUCK5
146 * 0.9V to 1.35V ()
147 */
148static const struct regulator_linear_range bd71837_buck5_voltage_ranges[] = {
149 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
150 REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
151 REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
152};
153
154/*
155 * BUCK6
156 * 3.0V to 3.3V (step 100mV)
157 */
158static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
159 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
160};
161
162/*
163 * BUCK7
164 * 000 = 1.605V
165 * 001 = 1.695V
166 * 010 = 1.755V
167 * 011 = 1.8V (Initial)
168 * 100 = 1.845V
169 * 101 = 1.905V
170 * 110 = 1.95V
171 * 111 = 1.995V
172 */
173static const unsigned int buck_7_volts[] = {
174 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
175};
176
177/*
178 * BUCK8
179 * 0.8V to 1.40V (step 10mV)
180 */
181static const struct regulator_linear_range bd71837_buck8_voltage_ranges[] = {
182 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
183 REGULATOR_LINEAR_RANGE(1400000, 0x3D, 0x3F, 0),
184};
185
186/*
187 * LDO1
188 * 3.0 to 3.3V (100mV step)
189 */
190static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
191 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
192};
193
194/*
195 * LDO2
196 * 0.8 or 0.9V
197 */
198const unsigned int ldo_2_volts[] = {
199 900000, 800000
200};
201
202/*
203 * LDO3
204 * 1.8 to 3.3V (100mV step)
205 */
206static const struct regulator_linear_range bd71837_ldo3_voltage_ranges[] = {
207 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
208};
209
210/*
211 * LDO4
212 * 0.9 to 1.8V (100mV step)
213 */
214static const struct regulator_linear_range bd71837_ldo4_voltage_ranges[] = {
215 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
216 REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
217};
218
219/*
220 * LDO5
221 * 1.8 to 3.3V (100mV step)
222 */
223static const struct regulator_linear_range bd71837_ldo5_voltage_ranges[] = {
224 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
225};
226
227/*
228 * LDO6
229 * 0.9 to 1.8V (100mV step)
230 */
231static const struct regulator_linear_range bd71837_ldo6_voltage_ranges[] = {
232 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
233 REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
234};
235
236/*
237 * LDO7
238 * 1.8 to 3.3V (100mV step)
239 */
240static const struct regulator_linear_range bd71837_ldo7_voltage_ranges[] = {
241 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
242};
243
244static const struct regulator_desc bd71837_regulators[] = {
245 {
246 .name = "buck1",
247 .of_match = of_match_ptr("BUCK1"),
248 .regulators_node = of_match_ptr("regulators"),
249 .id = BD71837_BUCK1,
250 .ops = &bd71837_buck1234_regulator_ops,
251 .type = REGULATOR_VOLTAGE,
252 .n_voltages = BD71837_BUCK1_VOLTAGE_NUM,
253 .linear_ranges = bd71837_buck1234_voltage_ranges,
254 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
255 .vsel_reg = BD71837_REG_BUCK1_VOLT_RUN,
256 .vsel_mask = BUCK1_RUN_MASK,
257 .enable_reg = BD71837_REG_BUCK1_CTRL,
258 .enable_mask = BD71837_BUCK_EN,
259 .owner = THIS_MODULE,
260 },
261 {
262 .name = "buck2",
263 .of_match = of_match_ptr("BUCK2"),
264 .regulators_node = of_match_ptr("regulators"),
265 .id = BD71837_BUCK2,
266 .ops = &bd71837_buck1234_regulator_ops,
267 .type = REGULATOR_VOLTAGE,
268 .n_voltages = BD71837_BUCK2_VOLTAGE_NUM,
269 .linear_ranges = bd71837_buck1234_voltage_ranges,
270 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
271 .vsel_reg = BD71837_REG_BUCK2_VOLT_RUN,
272 .vsel_mask = BUCK2_RUN_MASK,
273 .enable_reg = BD71837_REG_BUCK2_CTRL,
274 .enable_mask = BD71837_BUCK_EN,
275 .owner = THIS_MODULE,
276 },
277 {
278 .name = "buck3",
279 .of_match = of_match_ptr("BUCK3"),
280 .regulators_node = of_match_ptr("regulators"),
281 .id = BD71837_BUCK3,
282 .ops = &bd71837_buck1234_regulator_ops,
283 .type = REGULATOR_VOLTAGE,
284 .n_voltages = BD71837_BUCK3_VOLTAGE_NUM,
285 .linear_ranges = bd71837_buck1234_voltage_ranges,
286 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
287 .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
288 .vsel_mask = BUCK3_RUN_MASK,
289 .enable_reg = BD71837_REG_BUCK3_CTRL,
290 .enable_mask = BD71837_BUCK_EN,
291 .owner = THIS_MODULE,
292 },
293 {
294 .name = "buck4",
295 .of_match = of_match_ptr("BUCK4"),
296 .regulators_node = of_match_ptr("regulators"),
297 .id = BD71837_BUCK4,
298 .ops = &bd71837_buck1234_regulator_ops,
299 .type = REGULATOR_VOLTAGE,
300 .n_voltages = BD71837_BUCK4_VOLTAGE_NUM,
301 .linear_ranges = bd71837_buck1234_voltage_ranges,
302 .n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
303 .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
304 .vsel_mask = BUCK4_RUN_MASK,
305 .enable_reg = BD71837_REG_BUCK4_CTRL,
306 .enable_mask = BD71837_BUCK_EN,
307 .owner = THIS_MODULE,
308 },
309 {
310 .name = "buck5",
311 .of_match = of_match_ptr("BUCK5"),
312 .regulators_node = of_match_ptr("regulators"),
313 .id = BD71837_BUCK5,
314 .ops = &bd71837_buck_regulator_ops,
315 .type = REGULATOR_VOLTAGE,
316 .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
317 .linear_ranges = bd71837_buck5_voltage_ranges,
318 .n_linear_ranges = ARRAY_SIZE(bd71837_buck5_voltage_ranges),
319 .vsel_reg = BD71837_REG_BUCK5_VOLT,
320 .vsel_mask = BUCK5_MASK,
321 .enable_reg = BD71837_REG_BUCK5_CTRL,
322 .enable_mask = BD71837_BUCK_EN,
323 .owner = THIS_MODULE,
324 },
325 {
326 .name = "buck6",
327 .of_match = of_match_ptr("BUCK6"),
328 .regulators_node = of_match_ptr("regulators"),
329 .id = BD71837_BUCK6,
330 .ops = &bd71837_buck_regulator_ops,
331 .type = REGULATOR_VOLTAGE,
332 .n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
333 .linear_ranges = bd71837_buck6_voltage_ranges,
334 .n_linear_ranges = ARRAY_SIZE(bd71837_buck6_voltage_ranges),
335 .vsel_reg = BD71837_REG_BUCK6_VOLT,
336 .vsel_mask = BUCK6_MASK,
337 .enable_reg = BD71837_REG_BUCK6_CTRL,
338 .enable_mask = BD71837_BUCK_EN,
339 .owner = THIS_MODULE,
340 },
341 {
342 .name = "buck7",
343 .of_match = of_match_ptr("BUCK7"),
344 .regulators_node = of_match_ptr("regulators"),
345 .id = BD71837_BUCK7,
346 .ops = &bd71837_buck_regulator_nolinear_ops,
347 .type = REGULATOR_VOLTAGE,
348 .volt_table = &buck_7_volts[0],
349 .n_voltages = ARRAY_SIZE(buck_7_volts),
350 .vsel_reg = BD71837_REG_BUCK7_VOLT,
351 .vsel_mask = BUCK7_MASK,
352 .enable_reg = BD71837_REG_BUCK7_CTRL,
353 .enable_mask = BD71837_BUCK_EN,
354 .owner = THIS_MODULE,
355 },
356 {
357 .name = "buck8",
358 .of_match = of_match_ptr("BUCK8"),
359 .regulators_node = of_match_ptr("regulators"),
360 .id = BD71837_BUCK8,
361 .ops = &bd71837_buck_regulator_ops,
362 .type = REGULATOR_VOLTAGE,
363 .n_voltages = BD71837_BUCK8_VOLTAGE_NUM,
364 .linear_ranges = bd71837_buck8_voltage_ranges,
365 .n_linear_ranges = ARRAY_SIZE(bd71837_buck8_voltage_ranges),
366 .vsel_reg = BD71837_REG_BUCK8_VOLT,
367 .vsel_mask = BUCK8_MASK,
368 .enable_reg = BD71837_REG_BUCK8_CTRL,
369 .enable_mask = BD71837_BUCK_EN,
370 .owner = THIS_MODULE,
371 },
372 {
373 .name = "ldo1",
374 .of_match = of_match_ptr("LDO1"),
375 .regulators_node = of_match_ptr("regulators"),
376 .id = BD71837_LDO1,
377 .ops = &bd71837_ldo_regulator_ops,
378 .type = REGULATOR_VOLTAGE,
379 .n_voltages = BD71837_LDO1_VOLTAGE_NUM,
380 .linear_ranges = bd71837_ldo1_voltage_ranges,
381 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo1_voltage_ranges),
382 .vsel_reg = BD71837_REG_LDO1_VOLT,
383 .vsel_mask = LDO1_MASK,
384 .enable_reg = BD71837_REG_LDO1_VOLT,
385 .enable_mask = BD71837_LDO_EN,
386 .owner = THIS_MODULE,
387 },
388 {
389 .name = "ldo2",
390 .of_match = of_match_ptr("LDO2"),
391 .regulators_node = of_match_ptr("regulators"),
392 .id = BD71837_LDO2,
393 .ops = &bd71837_ldo_regulator_nolinear_ops,
394 .type = REGULATOR_VOLTAGE,
395 .volt_table = &ldo_2_volts[0],
396 .vsel_reg = BD71837_REG_LDO2_VOLT,
397 .vsel_mask = LDO2_MASK,
398 .n_voltages = ARRAY_SIZE(ldo_2_volts),
399 .n_voltages = BD71837_LDO2_VOLTAGE_NUM,
400 .enable_reg = BD71837_REG_LDO2_VOLT,
401 .enable_mask = BD71837_LDO_EN,
402 .owner = THIS_MODULE,
403 },
404 {
405 .name = "ldo3",
406 .of_match = of_match_ptr("LDO3"),
407 .regulators_node = of_match_ptr("regulators"),
408 .id = BD71837_LDO3,
409 .ops = &bd71837_ldo_regulator_ops,
410 .type = REGULATOR_VOLTAGE,
411 .n_voltages = BD71837_LDO3_VOLTAGE_NUM,
412 .linear_ranges = bd71837_ldo3_voltage_ranges,
413 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo3_voltage_ranges),
414 .vsel_reg = BD71837_REG_LDO3_VOLT,
415 .vsel_mask = LDO3_MASK,
416 .enable_reg = BD71837_REG_LDO3_VOLT,
417 .enable_mask = BD71837_LDO_EN,
418 .owner = THIS_MODULE,
419 },
420 {
421 .name = "ldo4",
422 .of_match = of_match_ptr("LDO4"),
423 .regulators_node = of_match_ptr("regulators"),
424 .id = BD71837_LDO4,
425 .ops = &bd71837_ldo_regulator_ops,
426 .type = REGULATOR_VOLTAGE,
427 .n_voltages = BD71837_LDO4_VOLTAGE_NUM,
428 .linear_ranges = bd71837_ldo4_voltage_ranges,
429 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo4_voltage_ranges),
430 .vsel_reg = BD71837_REG_LDO4_VOLT,
431 .vsel_mask = LDO4_MASK,
432 .enable_reg = BD71837_REG_LDO4_VOLT,
433 .enable_mask = BD71837_LDO_EN,
434 .owner = THIS_MODULE,
435 },
436 {
437 .name = "ldo5",
438 .of_match = of_match_ptr("LDO5"),
439 .regulators_node = of_match_ptr("regulators"),
440 .id = BD71837_LDO5,
441 .ops = &bd71837_ldo_regulator_ops,
442 .type = REGULATOR_VOLTAGE,
443 .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
444 .linear_ranges = bd71837_ldo5_voltage_ranges,
445 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_voltage_ranges),
446 /* LDO5 is supplied by buck6 */
447 .supply_name = "buck6",
448 .vsel_reg = BD71837_REG_LDO5_VOLT,
449 .vsel_mask = LDO5_MASK,
450 .enable_reg = BD71837_REG_LDO5_VOLT,
451 .enable_mask = BD71837_LDO_EN,
452 .owner = THIS_MODULE,
453 },
454 {
455 .name = "ldo6",
456 .of_match = of_match_ptr("LDO6"),
457 .regulators_node = of_match_ptr("regulators"),
458 .id = BD71837_LDO6,
459 .ops = &bd71837_ldo_regulator_ops,
460 .type = REGULATOR_VOLTAGE,
461 .n_voltages = BD71837_LDO6_VOLTAGE_NUM,
462 .linear_ranges = bd71837_ldo6_voltage_ranges,
463 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo6_voltage_ranges),
464 /* LDO6 is supplied by buck7 */
465 .supply_name = "buck7",
466 .vsel_reg = BD71837_REG_LDO6_VOLT,
467 .vsel_mask = LDO6_MASK,
468 .enable_reg = BD71837_REG_LDO6_VOLT,
469 .enable_mask = BD71837_LDO_EN,
470 .owner = THIS_MODULE,
471 },
472 {
473 .name = "ldo7",
474 .of_match = of_match_ptr("LDO7"),
475 .regulators_node = of_match_ptr("regulators"),
476 .id = BD71837_LDO7,
477 .ops = &bd71837_ldo_regulator_ops,
478 .type = REGULATOR_VOLTAGE,
479 .n_voltages = BD71837_LDO7_VOLTAGE_NUM,
480 .linear_ranges = bd71837_ldo7_voltage_ranges,
481 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_voltage_ranges),
482 .vsel_reg = BD71837_REG_LDO7_VOLT,
483 .vsel_mask = LDO7_MASK,
484 .enable_reg = BD71837_REG_LDO7_VOLT,
485 .enable_mask = BD71837_LDO_EN,
486 .owner = THIS_MODULE,
487 },
488};
489
490struct reg_init {
491 unsigned int reg;
492 unsigned int mask;
493};
494
495static int bd71837_probe(struct platform_device *pdev)
496{
497 struct bd71837_pmic *pmic;
498 struct bd71837_board *pdata;
499 struct regulator_config config = { 0 };
500 struct reg_init pmic_regulator_inits[] = {
501 {
502 .reg = BD71837_REG_BUCK1_CTRL,
503 .mask = BD71837_BUCK_SEL,
504 }, {
505 .reg = BD71837_REG_BUCK2_CTRL,
506 .mask = BD71837_BUCK_SEL,
507 }, {
508 .reg = BD71837_REG_BUCK3_CTRL,
509 .mask = BD71837_BUCK_SEL,
510 }, {
511 .reg = BD71837_REG_BUCK4_CTRL,
512 .mask = BD71837_BUCK_SEL,
513 }, {
514 .reg = BD71837_REG_BUCK5_CTRL,
515 .mask = BD71837_BUCK_SEL,
516 }, {
517 .reg = BD71837_REG_BUCK6_CTRL,
518 .mask = BD71837_BUCK_SEL,
519 }, {
520 .reg = BD71837_REG_BUCK7_CTRL,
521 .mask = BD71837_BUCK_SEL,
522 }, {
523 .reg = BD71837_REG_BUCK8_CTRL,
524 .mask = BD71837_BUCK_SEL,
525 }, {
526 .reg = BD71837_REG_LDO1_VOLT,
527 .mask = BD71837_LDO_SEL,
528 }, {
529 .reg = BD71837_REG_LDO2_VOLT,
530 .mask = BD71837_LDO_SEL,
531 }, {
532 .reg = BD71837_REG_LDO3_VOLT,
533 .mask = BD71837_LDO_SEL,
534 }, {
535 .reg = BD71837_REG_LDO4_VOLT,
536 .mask = BD71837_LDO_SEL,
537 }, {
538 .reg = BD71837_REG_LDO5_VOLT,
539 .mask = BD71837_LDO_SEL,
540 }, {
541 .reg = BD71837_REG_LDO6_VOLT,
542 .mask = BD71837_LDO_SEL,
543 }, {
544 .reg = BD71837_REG_LDO7_VOLT,
545 .mask = BD71837_LDO_SEL,
546 }
547 };
548
549 int i, err;
550
551 pmic = devm_kzalloc(&pdev->dev, sizeof(struct bd71837_pmic),
552 GFP_KERNEL);
553 if (!pmic)
554 return -ENOMEM;
555
556 memcpy(pmic->descs, bd71837_regulators, sizeof(pmic->descs));
557
558 pmic->pdev = pdev;
559 pmic->mfd = dev_get_drvdata(pdev->dev.parent);
560
561 if (!pmic->mfd) {
562 dev_err(&pdev->dev, "No MFD driver data\n");
563 err = -EINVAL;
564 goto err;
565 }
566 platform_set_drvdata(pdev, pmic);
567 pdata = dev_get_platdata(pmic->mfd->dev);
568
569 /* Register LOCK release */
570 err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK,
571 (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
572 if (err) {
573 dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err);
574 goto err;
575 } else {
576 dev_dbg(&pmic->pdev->dev, "%s: Unlocked lock register 0x%x\n",
577 __func__, BD71837_REG_REGLOCK);
578 }
579
580 for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
581
582 struct regulator_desc *desc;
583 struct regulator_dev *rdev;
584
585 desc = &pmic->descs[i];
586
587 if (pdata)
588 config.init_data = pdata->init_data[i];
589
590 config.dev = pdev->dev.parent;
591 config.driver_data = pmic;
592 config.regmap = pmic->mfd->regmap;
593
594 rdev = devm_regulator_register(&pdev->dev, desc, &config);
595 if (IS_ERR(rdev)) {
596 dev_err(pmic->mfd->dev,
597 "failed to register %s regulator\n",
598 desc->name);
599 err = PTR_ERR(rdev);
600 goto err;
601 }
602 /* Regulator register gets the regulator constraints and
603 * applies them (set_machine_constraints). This should have
604 * turned the control register(s) to correct values and we
605 * can now switch the control from PMIC state machine to the
606 * register interface
607 */
608 err = regmap_update_bits(pmic->mfd->regmap,
609 pmic_regulator_inits[i].reg,
610 pmic_regulator_inits[i].mask,
611 0xFFFFFFFF);
612 if (err) {
613 dev_err(&pmic->pdev->dev,
614 "Failed to write BUCK/LDO SEL bit for (%s)\n",
615 desc->name);
616 goto err;
617 }
618
619 pmic->rdev[i] = rdev;
620 }
621
622 return 0;
623
624err:
625 return err;
626}
627
628static struct platform_driver bd71837_regulator = {
629 .driver = {
630 .name = "bd71837-pmic",
631 .owner = THIS_MODULE,
632 },
633 .probe = bd71837_probe,
634};
635
636module_platform_driver(bd71837_regulator);
637
638MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
639MODULE_DESCRIPTION("BD71837 voltage regulator driver");
640MODULE_LICENSE("GPL");