Commit | Line | Data |
---|---|---|
ba08799e MV |
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 | ||
19 | struct 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 | */ | |
34 | static 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 | */ | |
73 | static 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 | ||
86 | static 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 | ||
95 | static 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 | ||
104 | static 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 | ||
114 | static 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 | ||
124 | static 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 | */ | |
139 | static 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 | */ | |
148 | static 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 | */ | |
158 | static 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 | */ | |
173 | static 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 | */ | |
181 | static 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 | */ | |
190 | static 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 | */ | |
198 | const unsigned int ldo_2_volts[] = { | |
199 | 900000, 800000 | |
200 | }; | |
201 | ||
202 | /* | |
203 | * LDO3 | |
204 | * 1.8 to 3.3V (100mV step) | |
205 | */ | |
206 | static 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 | */ | |
214 | static 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 | */ | |
223 | static 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 | */ | |
231 | static 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 | */ | |
240 | static const struct regulator_linear_range bd71837_ldo7_voltage_ranges[] = { | |
241 | REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000), | |
242 | }; | |
243 | ||
244 | static 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 | ||
490 | struct reg_init { | |
491 | unsigned int reg; | |
492 | unsigned int mask; | |
493 | }; | |
494 | ||
495 | static 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 | ||
624 | err: | |
625 | return err; | |
626 | } | |
627 | ||
628 | static struct platform_driver bd71837_regulator = { | |
629 | .driver = { | |
630 | .name = "bd71837-pmic", | |
631 | .owner = THIS_MODULE, | |
632 | }, | |
633 | .probe = bd71837_probe, | |
634 | }; | |
635 | ||
636 | module_platform_driver(bd71837_regulator); | |
637 | ||
638 | MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); | |
639 | MODULE_DESCRIPTION("BD71837 voltage regulator driver"); | |
640 | MODULE_LICENSE("GPL"); |