1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (C) 2019 ROHM Semiconductors
3// bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver
4//
5
6#include <linux/delay.h>
7#include <linux/err.h>
8#include <linux/interrupt.h>
9#include <linux/kernel.h>
10#include <linux/mfd/rohm-bd71828.h>
11#include <linux/module.h>
12#include <linux/of.h>
13#include <linux/platform_device.h>
14#include <linux/regmap.h>
15#include <linux/regulator/driver.h>
16#include <linux/regulator/machine.h>
17#include <linux/regulator/of_regulator.h>
18
19struct reg_init {
20 unsigned int reg;
21 unsigned int mask;
22 unsigned int val;
23};
24struct bd71828_regulator_data {
25 struct regulator_desc desc;
26 const struct rohm_dvs_config dvs;
27 const struct reg_init *reg_inits;
28 int reg_init_amnt;
29};
30
31static const struct reg_init buck1_inits[] = {
32 /*
33 * DVS Buck voltages can be changed by register values or via GPIO.
34 * Use register accesses by default.
35 */
36 {
37 .reg = BD71828_REG_PS_CTRL_1,
38 .mask = BD71828_MASK_DVS_BUCK1_CTRL,
39 .val = BD71828_DVS_BUCK1_CTRL_I2C,
40 },
41};
42
43static const struct reg_init buck2_inits[] = {
44 {
45 .reg = BD71828_REG_PS_CTRL_1,
46 .mask = BD71828_MASK_DVS_BUCK2_CTRL,
47 .val = BD71828_DVS_BUCK2_CTRL_I2C,
48 },
49};
50
51static const struct reg_init buck6_inits[] = {
52 {
53 .reg = BD71828_REG_PS_CTRL_1,
54 .mask = BD71828_MASK_DVS_BUCK6_CTRL,
55 .val = BD71828_DVS_BUCK6_CTRL_I2C,
56 },
57};
58
59static const struct reg_init buck7_inits[] = {
60 {
61 .reg = BD71828_REG_PS_CTRL_1,
62 .mask = BD71828_MASK_DVS_BUCK7_CTRL,
63 .val = BD71828_DVS_BUCK7_CTRL_I2C,
64 },
65};
66
67static const struct linear_range bd71828_buck1267_volts[] = {
68 REGULATOR_LINEAR_RANGE(500000, 0x00, 0xef, 6250),
69 REGULATOR_LINEAR_RANGE(2000000, 0xf0, 0xff, 0),
70};
71
72static const struct linear_range bd71828_buck3_volts[] = {
73 REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x0f, 50000),
74 REGULATOR_LINEAR_RANGE(2000000, 0x10, 0x1f, 0),
75};
76
77static const struct linear_range bd71828_buck4_volts[] = {
78 REGULATOR_LINEAR_RANGE(1000000, 0x00, 0x1f, 25000),
79 REGULATOR_LINEAR_RANGE(1800000, 0x20, 0x3f, 0),
80};
81
82static const struct linear_range bd71828_buck5_volts[] = {
83 REGULATOR_LINEAR_RANGE(2500000, 0x00, 0x0f, 50000),
84 REGULATOR_LINEAR_RANGE(3300000, 0x10, 0x1f, 0),
85};
86
87static const struct linear_range bd71828_ldo_volts[] = {
88 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x31, 50000),
89 REGULATOR_LINEAR_RANGE(3300000, 0x32, 0x3f, 0),
90};
91
92static const unsigned int bd71828_ramp_delay[] = { 2500, 5000, 10000, 20000 };
93
94static int buck_set_hw_dvs_levels(struct device_node *np,
95 const struct regulator_desc *desc,
96 struct regulator_config *cfg)
97{
98 struct bd71828_regulator_data *data;
99
100 data = container_of(desc, struct bd71828_regulator_data, desc);
101
102 return rohm_regulator_set_dvs_levels(dvs: &data->dvs, np, desc, regmap: cfg->regmap);
103}
104
105static int ldo6_parse_dt(struct device_node *np,
106 const struct regulator_desc *desc,
107 struct regulator_config *cfg)
108{
109 int ret, i;
110 uint32_t uv = 0;
111 unsigned int en;
112 struct regmap *regmap = cfg->regmap;
113 static const char * const props[] = { "rohm,dvs-run-voltage",
114 "rohm,dvs-idle-voltage",
115 "rohm,dvs-suspend-voltage",
116 "rohm,dvs-lpsr-voltage" };
117 unsigned int mask[] = { BD71828_MASK_RUN_EN, BD71828_MASK_IDLE_EN,
118 BD71828_MASK_SUSP_EN, BD71828_MASK_LPSR_EN };
119
120 for (i = 0; i < ARRAY_SIZE(props); i++) {
121 ret = of_property_read_u32(np, propname: props[i], out_value: &uv);
122 if (ret) {
123 if (ret != -EINVAL)
124 return ret;
125 continue;
126 }
127 if (uv)
128 en = 0xffffffff;
129 else
130 en = 0;
131
132 ret = regmap_update_bits(map: regmap, reg: desc->enable_reg, mask: mask[i], val: en);
133 if (ret)
134 return ret;
135 }
136 return 0;
137}
138
139static const struct regulator_ops bd71828_buck_ops = {
140 .enable = regulator_enable_regmap,
141 .disable = regulator_disable_regmap,
142 .is_enabled = regulator_is_enabled_regmap,
143 .list_voltage = regulator_list_voltage_linear_range,
144 .set_voltage_sel = regulator_set_voltage_sel_regmap,
145 .get_voltage_sel = regulator_get_voltage_sel_regmap,
146};
147
148static const struct regulator_ops bd71828_dvs_buck_ops = {
149 .enable = regulator_enable_regmap,
150 .disable = regulator_disable_regmap,
151 .is_enabled = regulator_is_enabled_regmap,
152 .list_voltage = regulator_list_voltage_linear_range,
153 .set_voltage_sel = regulator_set_voltage_sel_regmap,
154 .get_voltage_sel = regulator_get_voltage_sel_regmap,
155 .set_voltage_time_sel = regulator_set_voltage_time_sel,
156 .set_ramp_delay = regulator_set_ramp_delay_regmap,
157};
158
159static const struct regulator_ops bd71828_ldo_ops = {
160 .enable = regulator_enable_regmap,
161 .disable = regulator_disable_regmap,
162 .is_enabled = regulator_is_enabled_regmap,
163 .list_voltage = regulator_list_voltage_linear_range,
164 .set_voltage_sel = regulator_set_voltage_sel_regmap,
165 .get_voltage_sel = regulator_get_voltage_sel_regmap,
166};
167
168static const struct regulator_ops bd71828_ldo6_ops = {
169 .enable = regulator_enable_regmap,
170 .disable = regulator_disable_regmap,
171 .is_enabled = regulator_is_enabled_regmap,
172};
173
174static const struct bd71828_regulator_data bd71828_rdata[] = {
175 {
176 .desc = {
177 .name = "buck1",
178 .of_match = of_match_ptr("BUCK1"),
179 .regulators_node = of_match_ptr("regulators"),
180 .id = BD71828_BUCK1,
181 .ops = &bd71828_dvs_buck_ops,
182 .type = REGULATOR_VOLTAGE,
183 .linear_ranges = bd71828_buck1267_volts,
184 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
185 .n_voltages = BD71828_BUCK1267_VOLTS,
186 .enable_reg = BD71828_REG_BUCK1_EN,
187 .enable_mask = BD71828_MASK_RUN_EN,
188 .vsel_reg = BD71828_REG_BUCK1_VOLT,
189 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,
190 .ramp_delay_table = bd71828_ramp_delay,
191 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
192 .ramp_reg = BD71828_REG_BUCK1_MODE,
193 .ramp_mask = BD71828_MASK_RAMP_DELAY,
194 .owner = THIS_MODULE,
195 .of_parse_cb = buck_set_hw_dvs_levels,
196 },
197 .dvs = {
198 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
199 ROHM_DVS_LEVEL_SUSPEND |
200 ROHM_DVS_LEVEL_LPSR,
201 .run_reg = BD71828_REG_BUCK1_VOLT,
202 .run_mask = BD71828_MASK_BUCK1267_VOLT,
203 .idle_reg = BD71828_REG_BUCK1_IDLE_VOLT,
204 .idle_mask = BD71828_MASK_BUCK1267_VOLT,
205 .idle_on_mask = BD71828_MASK_IDLE_EN,
206 .suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT,
207 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,
208 .suspend_on_mask = BD71828_MASK_SUSP_EN,
209 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
210 /*
211 * LPSR voltage is same as SUSPEND voltage. Allow
212 * setting it so that regulator can be set enabled at
213 * LPSR state
214 */
215 .lpsr_reg = BD71828_REG_BUCK1_SUSP_VOLT,
216 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
217 },
218 .reg_inits = buck1_inits,
219 .reg_init_amnt = ARRAY_SIZE(buck1_inits),
220 },
221 {
222 .desc = {
223 .name = "buck2",
224 .of_match = of_match_ptr("BUCK2"),
225 .regulators_node = of_match_ptr("regulators"),
226 .id = BD71828_BUCK2,
227 .ops = &bd71828_dvs_buck_ops,
228 .type = REGULATOR_VOLTAGE,
229 .linear_ranges = bd71828_buck1267_volts,
230 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
231 .n_voltages = BD71828_BUCK1267_VOLTS,
232 .enable_reg = BD71828_REG_BUCK2_EN,
233 .enable_mask = BD71828_MASK_RUN_EN,
234 .vsel_reg = BD71828_REG_BUCK2_VOLT,
235 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,
236 .ramp_delay_table = bd71828_ramp_delay,
237 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
238 .ramp_reg = BD71828_REG_BUCK2_MODE,
239 .ramp_mask = BD71828_MASK_RAMP_DELAY,
240 .owner = THIS_MODULE,
241 .of_parse_cb = buck_set_hw_dvs_levels,
242 },
243 .dvs = {
244 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
245 ROHM_DVS_LEVEL_SUSPEND |
246 ROHM_DVS_LEVEL_LPSR,
247 .run_reg = BD71828_REG_BUCK2_VOLT,
248 .run_mask = BD71828_MASK_BUCK1267_VOLT,
249 .idle_reg = BD71828_REG_BUCK2_IDLE_VOLT,
250 .idle_mask = BD71828_MASK_BUCK1267_VOLT,
251 .idle_on_mask = BD71828_MASK_IDLE_EN,
252 .suspend_reg = BD71828_REG_BUCK2_SUSP_VOLT,
253 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,
254 .suspend_on_mask = BD71828_MASK_SUSP_EN,
255 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
256 .lpsr_reg = BD71828_REG_BUCK2_SUSP_VOLT,
257 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
258 },
259 .reg_inits = buck2_inits,
260 .reg_init_amnt = ARRAY_SIZE(buck2_inits),
261 },
262 {
263 .desc = {
264 .name = "buck3",
265 .of_match = of_match_ptr("BUCK3"),
266 .regulators_node = of_match_ptr("regulators"),
267 .id = BD71828_BUCK3,
268 .ops = &bd71828_buck_ops,
269 .type = REGULATOR_VOLTAGE,
270 .linear_ranges = bd71828_buck3_volts,
271 .n_linear_ranges = ARRAY_SIZE(bd71828_buck3_volts),
272 .n_voltages = BD71828_BUCK3_VOLTS,
273 .enable_reg = BD71828_REG_BUCK3_EN,
274 .enable_mask = BD71828_MASK_RUN_EN,
275 .vsel_reg = BD71828_REG_BUCK3_VOLT,
276 .vsel_mask = BD71828_MASK_BUCK3_VOLT,
277 .owner = THIS_MODULE,
278 .of_parse_cb = buck_set_hw_dvs_levels,
279 },
280 .dvs = {
281 /*
282 * BUCK3 only supports single voltage for all states.
283 * voltage can be individually enabled for each state
284 * though => allow setting all states to support
285 * enabling power rail on different states.
286 */
287 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
288 ROHM_DVS_LEVEL_SUSPEND |
289 ROHM_DVS_LEVEL_LPSR,
290 .run_reg = BD71828_REG_BUCK3_VOLT,
291 .idle_reg = BD71828_REG_BUCK3_VOLT,
292 .suspend_reg = BD71828_REG_BUCK3_VOLT,
293 .lpsr_reg = BD71828_REG_BUCK3_VOLT,
294 .run_mask = BD71828_MASK_BUCK3_VOLT,
295 .idle_mask = BD71828_MASK_BUCK3_VOLT,
296 .suspend_mask = BD71828_MASK_BUCK3_VOLT,
297 .lpsr_mask = BD71828_MASK_BUCK3_VOLT,
298 .idle_on_mask = BD71828_MASK_IDLE_EN,
299 .suspend_on_mask = BD71828_MASK_SUSP_EN,
300 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
301 },
302 },
303 {
304 .desc = {
305 .name = "buck4",
306 .of_match = of_match_ptr("BUCK4"),
307 .regulators_node = of_match_ptr("regulators"),
308 .id = BD71828_BUCK4,
309 .ops = &bd71828_buck_ops,
310 .type = REGULATOR_VOLTAGE,
311 .linear_ranges = bd71828_buck4_volts,
312 .n_linear_ranges = ARRAY_SIZE(bd71828_buck4_volts),
313 .n_voltages = BD71828_BUCK4_VOLTS,
314 .enable_reg = BD71828_REG_BUCK4_EN,
315 .enable_mask = BD71828_MASK_RUN_EN,
316 .vsel_reg = BD71828_REG_BUCK4_VOLT,
317 .vsel_mask = BD71828_MASK_BUCK4_VOLT,
318 .owner = THIS_MODULE,
319 .of_parse_cb = buck_set_hw_dvs_levels,
320 },
321 .dvs = {
322 /*
323 * BUCK4 only supports single voltage for all states.
324 * voltage can be individually enabled for each state
325 * though => allow setting all states to support
326 * enabling power rail on different states.
327 */
328 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
329 ROHM_DVS_LEVEL_SUSPEND |
330 ROHM_DVS_LEVEL_LPSR,
331 .run_reg = BD71828_REG_BUCK4_VOLT,
332 .idle_reg = BD71828_REG_BUCK4_VOLT,
333 .suspend_reg = BD71828_REG_BUCK4_VOLT,
334 .lpsr_reg = BD71828_REG_BUCK4_VOLT,
335 .run_mask = BD71828_MASK_BUCK4_VOLT,
336 .idle_mask = BD71828_MASK_BUCK4_VOLT,
337 .suspend_mask = BD71828_MASK_BUCK4_VOLT,
338 .lpsr_mask = BD71828_MASK_BUCK4_VOLT,
339 .idle_on_mask = BD71828_MASK_IDLE_EN,
340 .suspend_on_mask = BD71828_MASK_SUSP_EN,
341 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
342 },
343 },
344 {
345 .desc = {
346 .name = "buck5",
347 .of_match = of_match_ptr("BUCK5"),
348 .regulators_node = of_match_ptr("regulators"),
349 .id = BD71828_BUCK5,
350 .ops = &bd71828_buck_ops,
351 .type = REGULATOR_VOLTAGE,
352 .linear_ranges = bd71828_buck5_volts,
353 .n_linear_ranges = ARRAY_SIZE(bd71828_buck5_volts),
354 .n_voltages = BD71828_BUCK5_VOLTS,
355 .enable_reg = BD71828_REG_BUCK5_EN,
356 .enable_mask = BD71828_MASK_RUN_EN,
357 .vsel_reg = BD71828_REG_BUCK5_VOLT,
358 .vsel_mask = BD71828_MASK_BUCK5_VOLT,
359 .owner = THIS_MODULE,
360 .of_parse_cb = buck_set_hw_dvs_levels,
361 },
362 .dvs = {
363 /*
364 * BUCK5 only supports single voltage for all states.
365 * voltage can be individually enabled for each state
366 * though => allow setting all states to support
367 * enabling power rail on different states.
368 */
369 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
370 ROHM_DVS_LEVEL_SUSPEND |
371 ROHM_DVS_LEVEL_LPSR,
372 .run_reg = BD71828_REG_BUCK5_VOLT,
373 .idle_reg = BD71828_REG_BUCK5_VOLT,
374 .suspend_reg = BD71828_REG_BUCK5_VOLT,
375 .lpsr_reg = BD71828_REG_BUCK5_VOLT,
376 .run_mask = BD71828_MASK_BUCK5_VOLT,
377 .idle_mask = BD71828_MASK_BUCK5_VOLT,
378 .suspend_mask = BD71828_MASK_BUCK5_VOLT,
379 .lpsr_mask = BD71828_MASK_BUCK5_VOLT,
380 .idle_on_mask = BD71828_MASK_IDLE_EN,
381 .suspend_on_mask = BD71828_MASK_SUSP_EN,
382 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
383 },
384 },
385 {
386 .desc = {
387 .name = "buck6",
388 .of_match = of_match_ptr("BUCK6"),
389 .regulators_node = of_match_ptr("regulators"),
390 .id = BD71828_BUCK6,
391 .ops = &bd71828_dvs_buck_ops,
392 .type = REGULATOR_VOLTAGE,
393 .linear_ranges = bd71828_buck1267_volts,
394 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
395 .n_voltages = BD71828_BUCK1267_VOLTS,
396 .enable_reg = BD71828_REG_BUCK6_EN,
397 .enable_mask = BD71828_MASK_RUN_EN,
398 .vsel_reg = BD71828_REG_BUCK6_VOLT,
399 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,
400 .ramp_delay_table = bd71828_ramp_delay,
401 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
402 .ramp_reg = BD71828_REG_BUCK6_MODE,
403 .ramp_mask = BD71828_MASK_RAMP_DELAY,
404 .owner = THIS_MODULE,
405 .of_parse_cb = buck_set_hw_dvs_levels,
406 },
407 .dvs = {
408 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
409 ROHM_DVS_LEVEL_SUSPEND |
410 ROHM_DVS_LEVEL_LPSR,
411 .run_reg = BD71828_REG_BUCK6_VOLT,
412 .run_mask = BD71828_MASK_BUCK1267_VOLT,
413 .idle_reg = BD71828_REG_BUCK6_IDLE_VOLT,
414 .idle_mask = BD71828_MASK_BUCK1267_VOLT,
415 .idle_on_mask = BD71828_MASK_IDLE_EN,
416 .suspend_reg = BD71828_REG_BUCK6_SUSP_VOLT,
417 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,
418 .suspend_on_mask = BD71828_MASK_SUSP_EN,
419 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
420 .lpsr_reg = BD71828_REG_BUCK6_SUSP_VOLT,
421 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
422 },
423 .reg_inits = buck6_inits,
424 .reg_init_amnt = ARRAY_SIZE(buck6_inits),
425 },
426 {
427 .desc = {
428 .name = "buck7",
429 .of_match = of_match_ptr("BUCK7"),
430 .regulators_node = of_match_ptr("regulators"),
431 .id = BD71828_BUCK7,
432 .ops = &bd71828_dvs_buck_ops,
433 .type = REGULATOR_VOLTAGE,
434 .linear_ranges = bd71828_buck1267_volts,
435 .n_linear_ranges = ARRAY_SIZE(bd71828_buck1267_volts),
436 .n_voltages = BD71828_BUCK1267_VOLTS,
437 .enable_reg = BD71828_REG_BUCK7_EN,
438 .enable_mask = BD71828_MASK_RUN_EN,
439 .vsel_reg = BD71828_REG_BUCK7_VOLT,
440 .vsel_mask = BD71828_MASK_BUCK1267_VOLT,
441 .ramp_delay_table = bd71828_ramp_delay,
442 .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay),
443 .ramp_reg = BD71828_REG_BUCK7_MODE,
444 .ramp_mask = BD71828_MASK_RAMP_DELAY,
445 .owner = THIS_MODULE,
446 .of_parse_cb = buck_set_hw_dvs_levels,
447 },
448 .dvs = {
449 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
450 ROHM_DVS_LEVEL_SUSPEND |
451 ROHM_DVS_LEVEL_LPSR,
452 .run_reg = BD71828_REG_BUCK7_VOLT,
453 .run_mask = BD71828_MASK_BUCK1267_VOLT,
454 .idle_reg = BD71828_REG_BUCK7_IDLE_VOLT,
455 .idle_mask = BD71828_MASK_BUCK1267_VOLT,
456 .idle_on_mask = BD71828_MASK_IDLE_EN,
457 .suspend_reg = BD71828_REG_BUCK7_SUSP_VOLT,
458 .suspend_mask = BD71828_MASK_BUCK1267_VOLT,
459 .suspend_on_mask = BD71828_MASK_SUSP_EN,
460 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
461 .lpsr_reg = BD71828_REG_BUCK7_SUSP_VOLT,
462 .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
463 },
464 .reg_inits = buck7_inits,
465 .reg_init_amnt = ARRAY_SIZE(buck7_inits),
466 },
467 {
468 .desc = {
469 .name = "ldo1",
470 .of_match = of_match_ptr("LDO1"),
471 .regulators_node = of_match_ptr("regulators"),
472 .id = BD71828_LDO1,
473 .ops = &bd71828_ldo_ops,
474 .type = REGULATOR_VOLTAGE,
475 .linear_ranges = bd71828_ldo_volts,
476 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
477 .n_voltages = BD71828_LDO_VOLTS,
478 .enable_reg = BD71828_REG_LDO1_EN,
479 .enable_mask = BD71828_MASK_RUN_EN,
480 .vsel_reg = BD71828_REG_LDO1_VOLT,
481 .vsel_mask = BD71828_MASK_LDO_VOLT,
482 .owner = THIS_MODULE,
483 .of_parse_cb = buck_set_hw_dvs_levels,
484 },
485 .dvs = {
486 /*
487 * LDO1 only supports single voltage for all states.
488 * voltage can be individually enabled for each state
489 * though => allow setting all states to support
490 * enabling power rail on different states.
491 */
492 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
493 ROHM_DVS_LEVEL_SUSPEND |
494 ROHM_DVS_LEVEL_LPSR,
495 .run_reg = BD71828_REG_LDO1_VOLT,
496 .idle_reg = BD71828_REG_LDO1_VOLT,
497 .suspend_reg = BD71828_REG_LDO1_VOLT,
498 .lpsr_reg = BD71828_REG_LDO1_VOLT,
499 .run_mask = BD71828_MASK_LDO_VOLT,
500 .idle_mask = BD71828_MASK_LDO_VOLT,
501 .suspend_mask = BD71828_MASK_LDO_VOLT,
502 .lpsr_mask = BD71828_MASK_LDO_VOLT,
503 .idle_on_mask = BD71828_MASK_IDLE_EN,
504 .suspend_on_mask = BD71828_MASK_SUSP_EN,
505 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
506 },
507 }, {
508 .desc = {
509 .name = "ldo2",
510 .of_match = of_match_ptr("LDO2"),
511 .regulators_node = of_match_ptr("regulators"),
512 .id = BD71828_LDO2,
513 .ops = &bd71828_ldo_ops,
514 .type = REGULATOR_VOLTAGE,
515 .linear_ranges = bd71828_ldo_volts,
516 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
517 .n_voltages = BD71828_LDO_VOLTS,
518 .enable_reg = BD71828_REG_LDO2_EN,
519 .enable_mask = BD71828_MASK_RUN_EN,
520 .vsel_reg = BD71828_REG_LDO2_VOLT,
521 .vsel_mask = BD71828_MASK_LDO_VOLT,
522 .owner = THIS_MODULE,
523 .of_parse_cb = buck_set_hw_dvs_levels,
524 },
525 .dvs = {
526 /*
527 * LDO2 only supports single voltage for all states.
528 * voltage can be individually enabled for each state
529 * though => allow setting all states to support
530 * enabling power rail on different states.
531 */
532 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
533 ROHM_DVS_LEVEL_SUSPEND |
534 ROHM_DVS_LEVEL_LPSR,
535 .run_reg = BD71828_REG_LDO2_VOLT,
536 .idle_reg = BD71828_REG_LDO2_VOLT,
537 .suspend_reg = BD71828_REG_LDO2_VOLT,
538 .lpsr_reg = BD71828_REG_LDO2_VOLT,
539 .run_mask = BD71828_MASK_LDO_VOLT,
540 .idle_mask = BD71828_MASK_LDO_VOLT,
541 .suspend_mask = BD71828_MASK_LDO_VOLT,
542 .lpsr_mask = BD71828_MASK_LDO_VOLT,
543 .idle_on_mask = BD71828_MASK_IDLE_EN,
544 .suspend_on_mask = BD71828_MASK_SUSP_EN,
545 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
546 },
547 }, {
548 .desc = {
549 .name = "ldo3",
550 .of_match = of_match_ptr("LDO3"),
551 .regulators_node = of_match_ptr("regulators"),
552 .id = BD71828_LDO3,
553 .ops = &bd71828_ldo_ops,
554 .type = REGULATOR_VOLTAGE,
555 .linear_ranges = bd71828_ldo_volts,
556 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
557 .n_voltages = BD71828_LDO_VOLTS,
558 .enable_reg = BD71828_REG_LDO3_EN,
559 .enable_mask = BD71828_MASK_RUN_EN,
560 .vsel_reg = BD71828_REG_LDO3_VOLT,
561 .vsel_mask = BD71828_MASK_LDO_VOLT,
562 .owner = THIS_MODULE,
563 .of_parse_cb = buck_set_hw_dvs_levels,
564 },
565 .dvs = {
566 /*
567 * LDO3 only supports single voltage for all states.
568 * voltage can be individually enabled for each state
569 * though => allow setting all states to support
570 * enabling power rail on different states.
571 */
572 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
573 ROHM_DVS_LEVEL_SUSPEND |
574 ROHM_DVS_LEVEL_LPSR,
575 .run_reg = BD71828_REG_LDO3_VOLT,
576 .idle_reg = BD71828_REG_LDO3_VOLT,
577 .suspend_reg = BD71828_REG_LDO3_VOLT,
578 .lpsr_reg = BD71828_REG_LDO3_VOLT,
579 .run_mask = BD71828_MASK_LDO_VOLT,
580 .idle_mask = BD71828_MASK_LDO_VOLT,
581 .suspend_mask = BD71828_MASK_LDO_VOLT,
582 .lpsr_mask = BD71828_MASK_LDO_VOLT,
583 .idle_on_mask = BD71828_MASK_IDLE_EN,
584 .suspend_on_mask = BD71828_MASK_SUSP_EN,
585 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
586 },
587
588 }, {
589 .desc = {
590 .name = "ldo4",
591 .of_match = of_match_ptr("LDO4"),
592 .regulators_node = of_match_ptr("regulators"),
593 .id = BD71828_LDO4,
594 .ops = &bd71828_ldo_ops,
595 .type = REGULATOR_VOLTAGE,
596 .linear_ranges = bd71828_ldo_volts,
597 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
598 .n_voltages = BD71828_LDO_VOLTS,
599 .enable_reg = BD71828_REG_LDO4_EN,
600 .enable_mask = BD71828_MASK_RUN_EN,
601 .vsel_reg = BD71828_REG_LDO4_VOLT,
602 .vsel_mask = BD71828_MASK_LDO_VOLT,
603 .owner = THIS_MODULE,
604 .of_parse_cb = buck_set_hw_dvs_levels,
605 },
606 .dvs = {
607 /*
608 * LDO1 only supports single voltage for all states.
609 * voltage can be individually enabled for each state
610 * though => allow setting all states to support
611 * enabling power rail on different states.
612 */
613 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
614 ROHM_DVS_LEVEL_SUSPEND |
615 ROHM_DVS_LEVEL_LPSR,
616 .run_reg = BD71828_REG_LDO4_VOLT,
617 .idle_reg = BD71828_REG_LDO4_VOLT,
618 .suspend_reg = BD71828_REG_LDO4_VOLT,
619 .lpsr_reg = BD71828_REG_LDO4_VOLT,
620 .run_mask = BD71828_MASK_LDO_VOLT,
621 .idle_mask = BD71828_MASK_LDO_VOLT,
622 .suspend_mask = BD71828_MASK_LDO_VOLT,
623 .lpsr_mask = BD71828_MASK_LDO_VOLT,
624 .idle_on_mask = BD71828_MASK_IDLE_EN,
625 .suspend_on_mask = BD71828_MASK_SUSP_EN,
626 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
627 },
628 }, {
629 .desc = {
630 .name = "ldo5",
631 .of_match = of_match_ptr("LDO5"),
632 .regulators_node = of_match_ptr("regulators"),
633 .id = BD71828_LDO5,
634 .ops = &bd71828_ldo_ops,
635 .type = REGULATOR_VOLTAGE,
636 .linear_ranges = bd71828_ldo_volts,
637 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
638 .n_voltages = BD71828_LDO_VOLTS,
639 .enable_reg = BD71828_REG_LDO5_EN,
640 .enable_mask = BD71828_MASK_RUN_EN,
641 .vsel_reg = BD71828_REG_LDO5_VOLT,
642 .vsel_mask = BD71828_MASK_LDO_VOLT,
643 .of_parse_cb = buck_set_hw_dvs_levels,
644 .owner = THIS_MODULE,
645 },
646 /*
647 * LDO5 is special. It can choose vsel settings to be configured
648 * from 2 different registers (by GPIO).
649 *
650 * This driver supports only configuration where
651 * BD71828_REG_LDO5_VOLT_L is used.
652 */
653 .dvs = {
654 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
655 ROHM_DVS_LEVEL_SUSPEND |
656 ROHM_DVS_LEVEL_LPSR,
657 .run_reg = BD71828_REG_LDO5_VOLT,
658 .idle_reg = BD71828_REG_LDO5_VOLT,
659 .suspend_reg = BD71828_REG_LDO5_VOLT,
660 .lpsr_reg = BD71828_REG_LDO5_VOLT,
661 .run_mask = BD71828_MASK_LDO_VOLT,
662 .idle_mask = BD71828_MASK_LDO_VOLT,
663 .suspend_mask = BD71828_MASK_LDO_VOLT,
664 .lpsr_mask = BD71828_MASK_LDO_VOLT,
665 .idle_on_mask = BD71828_MASK_IDLE_EN,
666 .suspend_on_mask = BD71828_MASK_SUSP_EN,
667 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
668 },
669
670 }, {
671 .desc = {
672 .name = "ldo6",
673 .of_match = of_match_ptr("LDO6"),
674 .regulators_node = of_match_ptr("regulators"),
675 .id = BD71828_LDO6,
676 .ops = &bd71828_ldo6_ops,
677 .type = REGULATOR_VOLTAGE,
678 .fixed_uV = BD71828_LDO_6_VOLTAGE,
679 .n_voltages = 1,
680 .enable_reg = BD71828_REG_LDO6_EN,
681 .enable_mask = BD71828_MASK_RUN_EN,
682 .owner = THIS_MODULE,
683 /*
684 * LDO6 only supports enable/disable for all states.
685 * Voltage for LDO6 is fixed.
686 */
687 .of_parse_cb = ldo6_parse_dt,
688 },
689 }, {
690 .desc = {
691 /* SNVS LDO in data-sheet */
692 .name = "ldo7",
693 .of_match = of_match_ptr("LDO7"),
694 .regulators_node = of_match_ptr("regulators"),
695 .id = BD71828_LDO_SNVS,
696 .ops = &bd71828_ldo_ops,
697 .type = REGULATOR_VOLTAGE,
698 .linear_ranges = bd71828_ldo_volts,
699 .n_linear_ranges = ARRAY_SIZE(bd71828_ldo_volts),
700 .n_voltages = BD71828_LDO_VOLTS,
701 .enable_reg = BD71828_REG_LDO7_EN,
702 .enable_mask = BD71828_MASK_RUN_EN,
703 .vsel_reg = BD71828_REG_LDO7_VOLT,
704 .vsel_mask = BD71828_MASK_LDO_VOLT,
705 .owner = THIS_MODULE,
706 .of_parse_cb = buck_set_hw_dvs_levels,
707 },
708 .dvs = {
709 /*
710 * LDO7 only supports single voltage for all states.
711 * voltage can be individually enabled for each state
712 * though => allow setting all states to support
713 * enabling power rail on different states.
714 */
715 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
716 ROHM_DVS_LEVEL_SUSPEND |
717 ROHM_DVS_LEVEL_LPSR,
718 .run_reg = BD71828_REG_LDO7_VOLT,
719 .idle_reg = BD71828_REG_LDO7_VOLT,
720 .suspend_reg = BD71828_REG_LDO7_VOLT,
721 .lpsr_reg = BD71828_REG_LDO7_VOLT,
722 .run_mask = BD71828_MASK_LDO_VOLT,
723 .idle_mask = BD71828_MASK_LDO_VOLT,
724 .suspend_mask = BD71828_MASK_LDO_VOLT,
725 .lpsr_mask = BD71828_MASK_LDO_VOLT,
726 .idle_on_mask = BD71828_MASK_IDLE_EN,
727 .suspend_on_mask = BD71828_MASK_SUSP_EN,
728 .lpsr_on_mask = BD71828_MASK_LPSR_EN,
729 },
730
731 },
732};
733
734static int bd71828_probe(struct platform_device *pdev)
735{
736 int i, j, ret;
737 struct regulator_config config = {
738 .dev = pdev->dev.parent,
739 };
740
741 config.regmap = dev_get_regmap(dev: pdev->dev.parent, NULL);
742 if (!config.regmap)
743 return -ENODEV;
744
745 for (i = 0; i < ARRAY_SIZE(bd71828_rdata); i++) {
746 struct regulator_dev *rdev;
747 const struct bd71828_regulator_data *rd;
748
749 rd = &bd71828_rdata[i];
750 rdev = devm_regulator_register(dev: &pdev->dev,
751 regulator_desc: &rd->desc, config: &config);
752 if (IS_ERR(ptr: rdev))
753 return dev_err_probe(dev: &pdev->dev, err: PTR_ERR(ptr: rdev),
754 fmt: "failed to register %s regulator\n",
755 rd->desc.name);
756
757 for (j = 0; j < rd->reg_init_amnt; j++) {
758 ret = regmap_update_bits(map: config.regmap,
759 reg: rd->reg_inits[j].reg,
760 mask: rd->reg_inits[j].mask,
761 val: rd->reg_inits[j].val);
762 if (ret)
763 return dev_err_probe(dev: &pdev->dev, err: ret,
764 fmt: "regulator %s init failed\n",
765 rd->desc.name);
766 }
767 }
768 return 0;
769}
770
771static struct platform_driver bd71828_regulator = {
772 .driver = {
773 .name = "bd71828-pmic",
774 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
775 },
776 .probe = bd71828_probe,
777};
778
779module_platform_driver(bd71828_regulator);
780
781MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
782MODULE_DESCRIPTION("BD71828 voltage regulator driver");
783MODULE_LICENSE("GPL");
784MODULE_ALIAS("platform:bd71828-pmic");
785

source code of linux/drivers/regulator/bd71828-regulator.c