Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[linux-block.git] / drivers / regulator / bd71815-regulator.c
CommitLineData
1aad3900
MV
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright 2014 Embest Technology Co. Ltd. Inc.
4// bd71815-regulator.c ROHM BD71815 regulator driver
5//
6// Author: Tony Luo <luofc@embedinfo.com>
7//
8// Partially rewritten at 2021 by
9// Matti Vaittinen <matti.vaitinen@fi.rohmeurope.com>
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/err.h>
15#include <linux/platform_device.h>
3799fa23
AL
16#include <linux/of.h>
17#include <linux/gpio/consumer.h>
1aad3900
MV
18#include <linux/regulator/driver.h>
19#include <linux/delay.h>
20#include <linux/slab.h>
21#include <linux/gpio.h>
22#include <linux/mfd/rohm-generic.h>
23#include <linux/mfd/rohm-bd71815.h>
24#include <linux/regulator/of_regulator.h>
25
26struct bd71815_regulator {
27 struct regulator_desc desc;
28 const struct rohm_dvs_config *dvs;
29};
30
1aad3900
MV
31static const int bd7181x_wled_currents[] = {
32 10, 20, 30, 50, 70, 100, 200, 300, 500, 700, 1000, 2000, 3000, 4000,
33 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,
34 16000, 17000, 18000, 19000, 20000, 21000, 22000, 23000, 24000, 25000,
35};
36
37static const struct rohm_dvs_config buck1_dvs = {
38 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
39 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
40 .run_reg = BD71815_REG_BUCK1_VOLT_H,
41 .run_mask = BD71815_VOLT_MASK,
42 .run_on_mask = BD71815_BUCK_RUN_ON,
43 .snvs_on_mask = BD71815_BUCK_SNVS_ON,
44 .suspend_reg = BD71815_REG_BUCK1_VOLT_L,
45 .suspend_mask = BD71815_VOLT_MASK,
46 .suspend_on_mask = BD71815_BUCK_SUSP_ON,
47 .lpsr_reg = BD71815_REG_BUCK1_VOLT_L,
48 .lpsr_mask = BD71815_VOLT_MASK,
49 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,
50};
51
52static const struct rohm_dvs_config buck2_dvs = {
53 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
54 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
55 .run_reg = BD71815_REG_BUCK2_VOLT_H,
56 .run_mask = BD71815_VOLT_MASK,
57 .run_on_mask = BD71815_BUCK_RUN_ON,
58 .snvs_on_mask = BD71815_BUCK_SNVS_ON,
59 .suspend_reg = BD71815_REG_BUCK2_VOLT_L,
60 .suspend_mask = BD71815_VOLT_MASK,
61 .suspend_on_mask = BD71815_BUCK_SUSP_ON,
62 .lpsr_reg = BD71815_REG_BUCK2_VOLT_L,
63 .lpsr_mask = BD71815_VOLT_MASK,
64 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,
65};
66
67static const struct rohm_dvs_config buck3_dvs = {
68 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
69 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
70 .run_reg = BD71815_REG_BUCK3_VOLT,
71 .run_mask = BD71815_VOLT_MASK,
72 .run_on_mask = BD71815_BUCK_RUN_ON,
73 .snvs_on_mask = BD71815_BUCK_SNVS_ON,
74 .suspend_on_mask = BD71815_BUCK_SUSP_ON,
75 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,
76};
77
78static const struct rohm_dvs_config buck4_dvs = {
79 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
80 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
81 .run_reg = BD71815_REG_BUCK4_VOLT,
82 .run_mask = BD71815_VOLT_MASK,
83 .run_on_mask = BD71815_BUCK_RUN_ON,
84 .snvs_on_mask = BD71815_BUCK_SNVS_ON,
85 .suspend_on_mask = BD71815_BUCK_SUSP_ON,
86 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,
87};
88
89static const struct rohm_dvs_config ldo1_dvs = {
90 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
91 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
92 .run_reg = BD71815_REG_LDO_MODE1,
93 .run_mask = BD71815_VOLT_MASK,
94 .run_on_mask = LDO1_RUN_ON,
95 .snvs_on_mask = LDO1_SNVS_ON,
96 .suspend_on_mask = LDO1_SUSP_ON,
97 .lpsr_on_mask = LDO1_LPSR_ON,
98};
99
100static const struct rohm_dvs_config ldo2_dvs = {
101 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
102 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
103 .run_reg = BD71815_REG_LDO_MODE2,
104 .run_mask = BD71815_VOLT_MASK,
105 .run_on_mask = LDO2_RUN_ON,
106 .snvs_on_mask = LDO2_SNVS_ON,
107 .suspend_on_mask = LDO2_SUSP_ON,
108 .lpsr_on_mask = LDO2_LPSR_ON,
109};
110
111static const struct rohm_dvs_config ldo3_dvs = {
112 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
113 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
114 .run_reg = BD71815_REG_LDO_MODE2,
115 .run_mask = BD71815_VOLT_MASK,
116 .run_on_mask = LDO3_RUN_ON,
117 .snvs_on_mask = LDO3_SNVS_ON,
118 .suspend_on_mask = LDO3_SUSP_ON,
119 .lpsr_on_mask = LDO3_LPSR_ON,
120};
121
122static const struct rohm_dvs_config ldo4_dvs = {
123 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
124 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
125 .run_reg = BD71815_REG_LDO_MODE3,
126 .run_mask = BD71815_VOLT_MASK,
127 .run_on_mask = LDO4_RUN_ON,
128 .snvs_on_mask = LDO4_SNVS_ON,
129 .suspend_on_mask = LDO4_SUSP_ON,
130 .lpsr_on_mask = LDO4_LPSR_ON,
131};
132
133static const struct rohm_dvs_config ldo5_dvs = {
134 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
135 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
136 .run_reg = BD71815_REG_LDO_MODE3,
137 .run_mask = BD71815_VOLT_MASK,
138 .run_on_mask = LDO5_RUN_ON,
139 .snvs_on_mask = LDO5_SNVS_ON,
140 .suspend_on_mask = LDO5_SUSP_ON,
141 .lpsr_on_mask = LDO5_LPSR_ON,
142};
143
144static const struct rohm_dvs_config dvref_dvs = {
145 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
146 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
147 .run_on_mask = DVREF_RUN_ON,
148 .snvs_on_mask = DVREF_SNVS_ON,
149 .suspend_on_mask = DVREF_SUSP_ON,
150 .lpsr_on_mask = DVREF_LPSR_ON,
151};
152
153static const struct rohm_dvs_config ldolpsr_dvs = {
154 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
155 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
156 .run_on_mask = DVREF_RUN_ON,
157 .snvs_on_mask = DVREF_SNVS_ON,
158 .suspend_on_mask = DVREF_SUSP_ON,
159 .lpsr_on_mask = DVREF_LPSR_ON,
160};
161
162static const struct rohm_dvs_config buck5_dvs = {
163 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_SNVS |
164 ROHM_DVS_LEVEL_SUSPEND | ROHM_DVS_LEVEL_LPSR,
165 .run_reg = BD71815_REG_BUCK5_VOLT,
166 .run_mask = BD71815_VOLT_MASK,
167 .run_on_mask = BD71815_BUCK_RUN_ON,
168 .snvs_on_mask = BD71815_BUCK_SNVS_ON,
169 .suspend_on_mask = BD71815_BUCK_SUSP_ON,
170 .lpsr_on_mask = BD71815_BUCK_LPSR_ON,
171};
172
173static int set_hw_dvs_levels(struct device_node *np,
174 const struct regulator_desc *desc,
175 struct regulator_config *cfg)
176{
177 struct bd71815_regulator *data;
178
179 data = container_of(desc, struct bd71815_regulator, desc);
180 return rohm_regulator_set_dvs_levels(data->dvs, np, desc, cfg->regmap);
181}
182
183/*
184 * Bucks 1 and 2 have two voltage selection registers where selected
185 * voltage can be set. Which of the registers is used can be either controlled
186 * by a control bit in register - or by HW state. If HW state specific voltages
187 * are given - then we assume HW state based control should be used.
188 *
189 * If volatge value is updated to currently selected register - then output
190 * voltage is immediately changed no matter what is set as ramp rate. Thus we
191 * default changing voltage by writing new value to inactive register and
192 * then updating the 'register selection' bit. This naturally only works when
193 * HW state machine is not used to select the voltage.
194 */
195static int buck12_set_hw_dvs_levels(struct device_node *np,
196 const struct regulator_desc *desc,
197 struct regulator_config *cfg)
198{
199 struct bd71815_regulator *data;
200 int ret = 0, val;
201
202 data = container_of(desc, struct bd71815_regulator, desc);
203
204 if (of_find_property(np, "rohm,dvs-run-voltage", NULL) ||
205 of_find_property(np, "rohm,dvs-suspend-voltage", NULL) ||
206 of_find_property(np, "rohm,dvs-lpsr-voltage", NULL) ||
207 of_find_property(np, "rohm,dvs-snvs-voltage", NULL)) {
208 ret = regmap_read(cfg->regmap, desc->vsel_reg, &val);
209 if (ret)
210 return ret;
211
212 if (!(BD71815_BUCK_STBY_DVS & val) &&
213 !(BD71815_BUCK_DVSSEL & val)) {
214 int val2;
215
216 /*
217 * We are currently using voltage from _L.
218 * We'd better copy it to _H and switch to it to
219 * avoid shutting us down if LPSR or SUSPEND is set to
220 * disabled. _L value is at reg _H + 1
221 */
222 ret = regmap_read(cfg->regmap, desc->vsel_reg + 1,
223 &val2);
224 if (ret)
225 return ret;
226
227 ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,
228 BD71815_VOLT_MASK |
229 BD71815_BUCK_DVSSEL,
230 val2 | BD71815_BUCK_DVSSEL);
231 if (ret)
232 return ret;
233 }
234 ret = rohm_regulator_set_dvs_levels(data->dvs, np, desc,
235 cfg->regmap);
236 if (ret)
237 return ret;
238 /*
239 * DVS levels were given => use HW-state machine for voltage
240 * controls. NOTE: AFAIK, This means that if voltage is changed
241 * by SW the ramp-rate is not respected. Should we disable
242 * SW voltage control when the HW state machine is used?
243 */
244 ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,
245 BD71815_BUCK_STBY_DVS,
246 BD71815_BUCK_STBY_DVS);
247 }
248
249 return ret;
250}
251
252/*
253 * BUCK1/2
254 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
255 * 00: 10.00mV/usec 10mV 1uS
256 * 01: 5.00mV/usec 10mV 2uS
257 * 10: 2.50mV/usec 10mV 4uS
258 * 11: 1.25mV/usec 10mV 8uS
259 */
260static const unsigned int bd7181x_ramp_table[] = { 1250, 2500, 5000, 10000 };
261
262static int bd7181x_led_set_current_limit(struct regulator_dev *rdev,
263 int min_uA, int max_uA)
264{
265 int ret;
266 int onstatus;
267
268 onstatus = regulator_is_enabled_regmap(rdev);
269
270 ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA);
271 if (!ret) {
272 int newstatus;
273
274 newstatus = regulator_is_enabled_regmap(rdev);
275 if (onstatus != newstatus) {
276 /*
277 * HW FIX: spurious led status change detected. Toggle
278 * state as a workaround
279 */
280 if (onstatus)
281 ret = regulator_enable_regmap(rdev);
282 else
283 ret = regulator_disable_regmap(rdev);
284
285 if (ret)
286 dev_err(rdev_get_dev(rdev),
287 "failed to revert the LED state (%d)\n",
288 ret);
289 }
290 }
291
292 return ret;
293}
294
295static int bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
296{
1aad3900
MV
297 int rid = rdev_get_id(rdev);
298 int ret, regh, regl, val;
299
300 regh = BD71815_REG_BUCK1_VOLT_H + rid * 0x2;
301 regl = BD71815_REG_BUCK1_VOLT_L + rid * 0x2;
302
0ea461b4 303 ret = regmap_read(rdev->regmap, regh, &val);
1aad3900
MV
304 if (ret)
305 return ret;
306
307 /*
308 * If we use HW state machine based voltage reg selection - then we
309 * return BD71815_REG_BUCK1_VOLT_H which is used at RUN.
310 * Else we do return the BD71815_REG_BUCK1_VOLT_H or
311 * BD71815_REG_BUCK1_VOLT_L depending on which is selected to be used
312 * by BD71815_BUCK_DVSSEL bit
313 */
314 if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))
0ea461b4 315 ret = regmap_read(rdev->regmap, regl, &val);
1aad3900
MV
316
317 if (ret)
318 return ret;
319
320 return val & BD71815_VOLT_MASK;
321}
322
323/*
324 * For Buck 1/2.
325 */
326static int bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev,
327 unsigned int sel)
328{
1aad3900
MV
329 int rid = rdev_get_id(rdev);
330 int ret, val, reg, regh, regl;
331
332 regh = BD71815_REG_BUCK1_VOLT_H + rid*0x2;
333 regl = BD71815_REG_BUCK1_VOLT_L + rid*0x2;
334
0ea461b4 335 ret = regmap_read(rdev->regmap, regh, &val);
1aad3900
MV
336 if (ret)
337 return ret;
338
339 /*
340 * If bucks 1 & 2 are controlled by state machine - then the RUN state
341 * voltage is set to BD71815_REG_BUCK1_VOLT_H. Changing SUSPEND/LPSR
342 * voltages at runtime is not supported by this driver.
343 */
344 if (((val & BD71815_BUCK_STBY_DVS))) {
0ea461b4 345 return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,
1aad3900
MV
346 sel);
347 }
348 /* Update new voltage to the register which is not selected now */
349 if (val & BD71815_BUCK_DVSSEL)
350 reg = regl;
351 else
352 reg = regh;
353
0ea461b4 354 ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel);
1aad3900
MV
355 if (ret)
356 return ret;
357
358 /* Select the other DVS register to be used */
0ea461b4
AL
359 return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,
360 ~val);
1aad3900
MV
361}
362
363static const struct regulator_ops bd7181x_ldo_regulator_ops = {
364 .enable = regulator_enable_regmap,
365 .disable = regulator_disable_regmap,
366 .is_enabled = regulator_is_enabled_regmap,
367 .list_voltage = regulator_list_voltage_linear,
368 .set_voltage_sel = regulator_set_voltage_sel_regmap,
369 .get_voltage_sel = regulator_get_voltage_sel_regmap,
370};
371
372static const struct regulator_ops bd7181x_fixed_regulator_ops = {
373 .enable = regulator_enable_regmap,
374 .disable = regulator_disable_regmap,
375 .is_enabled = regulator_is_enabled_regmap,
376 .list_voltage = regulator_list_voltage_linear,
377};
378
379static const struct regulator_ops bd7181x_buck_regulator_ops = {
380 .enable = regulator_enable_regmap,
381 .disable = regulator_disable_regmap,
382 .is_enabled = regulator_is_enabled_regmap,
383 .list_voltage = regulator_list_voltage_linear,
384 .set_voltage_sel = regulator_set_voltage_sel_regmap,
385 .get_voltage_sel = regulator_get_voltage_sel_regmap,
386 .set_voltage_time_sel = regulator_set_voltage_time_sel,
387};
388
389static const struct regulator_ops bd7181x_buck12_regulator_ops = {
390 .enable = regulator_enable_regmap,
391 .disable = regulator_disable_regmap,
392 .is_enabled = regulator_is_enabled_regmap,
393 .list_voltage = regulator_list_voltage_linear,
394 .set_voltage_sel = bd7181x_buck12_set_voltage_sel,
395 .get_voltage_sel = bd7181x_buck12_get_voltage_sel,
396 .set_voltage_time_sel = regulator_set_voltage_time_sel,
397 .set_ramp_delay = regulator_set_ramp_delay_regmap,
398};
399
400static const struct regulator_ops bd7181x_led_regulator_ops = {
401 .enable = regulator_enable_regmap,
402 .disable = regulator_disable_regmap,
403 .is_enabled = regulator_is_enabled_regmap,
404 .set_current_limit = bd7181x_led_set_current_limit,
405 .get_current_limit = regulator_get_current_limit_regmap,
406};
407
408#define BD71815_FIXED_REG(_name, _id, ereg, emsk, voltage, _dvs) \
409 [(_id)] = { \
410 .desc = { \
411 .name = #_name, \
412 .of_match = of_match_ptr(#_name), \
413 .regulators_node = of_match_ptr("regulators"), \
414 .n_voltages = 1, \
415 .ops = &bd7181x_fixed_regulator_ops, \
416 .type = REGULATOR_VOLTAGE, \
417 .id = (_id), \
418 .owner = THIS_MODULE, \
419 .min_uV = (voltage), \
420 .enable_reg = (ereg), \
421 .enable_mask = (emsk), \
422 .of_parse_cb = set_hw_dvs_levels, \
423 }, \
424 .dvs = (_dvs), \
425 }
426
427#define BD71815_BUCK_REG(_name, _id, vsel, ereg, min, max, step, _dvs) \
428 [(_id)] = { \
429 .desc = { \
430 .name = #_name, \
431 .of_match = of_match_ptr(#_name), \
432 .regulators_node = of_match_ptr("regulators"), \
433 .n_voltages = ((max) - (min)) / (step) + 1, \
434 .ops = &bd7181x_buck_regulator_ops, \
435 .type = REGULATOR_VOLTAGE, \
436 .id = (_id), \
437 .owner = THIS_MODULE, \
438 .min_uV = (min), \
439 .uV_step = (step), \
440 .vsel_reg = (vsel), \
441 .vsel_mask = BD71815_VOLT_MASK, \
442 .enable_reg = (ereg), \
443 .enable_mask = BD71815_BUCK_RUN_ON, \
444 .of_parse_cb = set_hw_dvs_levels, \
445 }, \
446 .dvs = (_dvs), \
447 }
448
449#define BD71815_BUCK12_REG(_name, _id, vsel, ereg, min, max, step, \
450 _dvs) \
451 [(_id)] = { \
452 .desc = { \
453 .name = #_name, \
454 .of_match = of_match_ptr(#_name), \
455 .regulators_node = of_match_ptr("regulators"), \
456 .n_voltages = ((max) - (min)) / (step) + 1, \
457 .ops = &bd7181x_buck12_regulator_ops, \
458 .type = REGULATOR_VOLTAGE, \
459 .id = (_id), \
460 .owner = THIS_MODULE, \
461 .min_uV = (min), \
462 .uV_step = (step), \
463 .vsel_reg = (vsel), \
555767fd 464 .vsel_mask = BD71815_VOLT_MASK, \
1aad3900 465 .enable_reg = (ereg), \
555767fd 466 .enable_mask = BD71815_BUCK_RUN_ON, \
1aad3900
MV
467 .ramp_reg = (ereg), \
468 .ramp_mask = BD71815_BUCK_RAMPRATE_MASK, \
469 .ramp_delay_table = bd7181x_ramp_table, \
470 .n_ramp_values = ARRAY_SIZE(bd7181x_ramp_table),\
471 .of_parse_cb = buck12_set_hw_dvs_levels, \
472 }, \
473 .dvs = (_dvs), \
474 }
475
476#define BD71815_LED_REG(_name, _id, csel, mask, ereg, emsk, currents) \
477 [(_id)] = { \
478 .desc = { \
479 .name = #_name, \
480 .of_match = of_match_ptr(#_name), \
481 .regulators_node = of_match_ptr("regulators"), \
482 .n_current_limits = ARRAY_SIZE(currents), \
483 .ops = &bd7181x_led_regulator_ops, \
484 .type = REGULATOR_CURRENT, \
485 .id = (_id), \
486 .owner = THIS_MODULE, \
487 .curr_table = currents, \
488 .csel_reg = (csel), \
489 .csel_mask = (mask), \
490 .enable_reg = (ereg), \
491 .enable_mask = (emsk), \
492 }, \
493 }
494
495#define BD71815_LDO_REG(_name, _id, vsel, ereg, emsk, min, max, step, \
496 _dvs) \
497 [(_id)] = { \
498 .desc = { \
499 .name = #_name, \
500 .of_match = of_match_ptr(#_name), \
501 .regulators_node = of_match_ptr("regulators"), \
502 .n_voltages = ((max) - (min)) / (step) + 1, \
503 .ops = &bd7181x_ldo_regulator_ops, \
504 .type = REGULATOR_VOLTAGE, \
505 .id = (_id), \
506 .owner = THIS_MODULE, \
507 .min_uV = (min), \
508 .uV_step = (step), \
509 .vsel_reg = (vsel), \
510 .vsel_mask = BD71815_VOLT_MASK, \
511 .enable_reg = (ereg), \
512 .enable_mask = (emsk), \
513 .of_parse_cb = set_hw_dvs_levels, \
514 }, \
515 .dvs = (_dvs), \
516 }
517
0ea461b4 518static const struct bd71815_regulator bd71815_regulators[] = {
1aad3900
MV
519 BD71815_BUCK12_REG(buck1, BD71815_BUCK1, BD71815_REG_BUCK1_VOLT_H,
520 BD71815_REG_BUCK1_MODE, 800000, 2000000, 25000,
521 &buck1_dvs),
522 BD71815_BUCK12_REG(buck2, BD71815_BUCK2, BD71815_REG_BUCK2_VOLT_H,
523 BD71815_REG_BUCK2_MODE, 800000, 2000000, 25000,
524 &buck2_dvs),
525 BD71815_BUCK_REG(buck3, BD71815_BUCK3, BD71815_REG_BUCK3_VOLT,
526 BD71815_REG_BUCK3_MODE, 1200000, 2700000, 50000,
527 &buck3_dvs),
528 BD71815_BUCK_REG(buck4, BD71815_BUCK4, BD71815_REG_BUCK4_VOLT,
529 BD71815_REG_BUCK4_MODE, 1100000, 1850000, 25000,
530 &buck4_dvs),
531 BD71815_BUCK_REG(buck5, BD71815_BUCK5, BD71815_REG_BUCK5_VOLT,
532 BD71815_REG_BUCK5_MODE, 1800000, 3300000, 50000,
533 &buck5_dvs),
534 BD71815_LDO_REG(ldo1, BD71815_LDO1, BD71815_REG_LDO1_VOLT,
535 BD71815_REG_LDO_MODE1, LDO1_RUN_ON, 800000, 3300000,
536 50000, &ldo1_dvs),
537 BD71815_LDO_REG(ldo2, BD71815_LDO2, BD71815_REG_LDO2_VOLT,
538 BD71815_REG_LDO_MODE2, LDO2_RUN_ON, 800000, 3300000,
539 50000, &ldo2_dvs),
540 /*
541 * Let's default LDO3 to be enabled by SW. We can override ops if DT
542 * says LDO3 should be enabled by HW when DCIN is connected.
543 */
544 BD71815_LDO_REG(ldo3, BD71815_LDO3, BD71815_REG_LDO3_VOLT,
545 BD71815_REG_LDO_MODE2, LDO3_RUN_ON, 800000, 3300000,
546 50000, &ldo3_dvs),
547 BD71815_LDO_REG(ldo4, BD71815_LDO4, BD71815_REG_LDO4_VOLT,
548 BD71815_REG_LDO_MODE3, LDO4_RUN_ON, 800000, 3300000,
549 50000, &ldo4_dvs),
550 BD71815_LDO_REG(ldo5, BD71815_LDO5, BD71815_REG_LDO5_VOLT_H,
551 BD71815_REG_LDO_MODE3, LDO5_RUN_ON, 800000, 3300000,
552 50000, &ldo5_dvs),
553 BD71815_FIXED_REG(ldodvref, BD71815_LDODVREF, BD71815_REG_LDO_MODE4,
554 DVREF_RUN_ON, 3000000, &dvref_dvs),
555 BD71815_FIXED_REG(ldolpsr, BD71815_LDOLPSR, BD71815_REG_LDO_MODE4,
556 LDO_LPSR_RUN_ON, 1800000, &ldolpsr_dvs),
557 BD71815_LED_REG(wled, BD71815_WLED, BD71815_REG_LED_DIMM, LED_DIMM_MASK,
558 BD71815_REG_LED_CTRL, LED_RUN_ON,
559 bd7181x_wled_currents),
560};
561
562static int bd7181x_probe(struct platform_device *pdev)
563{
1aad3900
MV
564 struct regulator_config config = {};
565 int i, ret;
566 struct gpio_desc *ldo4_en;
0ea461b4 567 struct regmap *regmap;
1aad3900 568
0ea461b4
AL
569 regmap = dev_get_regmap(pdev->dev.parent, NULL);
570 if (!regmap) {
571 dev_err(&pdev->dev, "No parent regmap\n");
1aad3900
MV
572 return -ENODEV;
573 }
1aad3900 574
97c9278e
DT
575 ldo4_en = devm_fwnode_gpiod_get(&pdev->dev,
576 dev_fwnode(pdev->dev.parent),
577 "rohm,vsel", GPIOD_ASIS, "ldo4-en");
1aad3900
MV
578 if (IS_ERR(ldo4_en)) {
579 ret = PTR_ERR(ldo4_en);
580 if (ret != -ENOENT)
581 return ret;
582 ldo4_en = NULL;
583 }
584
585 /* Disable to go to ship-mode */
0ea461b4 586 ret = regmap_update_bits(regmap, BD71815_REG_PWRCTRL, RESTARTEN, 0);
1aad3900
MV
587 if (ret)
588 return ret;
589
590 config.dev = pdev->dev.parent;
0ea461b4 591 config.regmap = regmap;
1aad3900
MV
592
593 for (i = 0; i < BD71815_REGULATOR_CNT; i++) {
0ea461b4 594 const struct regulator_desc *desc;
1aad3900
MV
595 struct regulator_dev *rdev;
596
0ea461b4
AL
597 desc = &bd71815_regulators[i].desc;
598
1aad3900
MV
599 if (i == BD71815_LDO4)
600 config.ena_gpiod = ldo4_en;
0ea461b4
AL
601 else
602 config.ena_gpiod = NULL;
1aad3900
MV
603
604 rdev = devm_regulator_register(&pdev->dev, desc, &config);
d4e93e8d
MV
605 if (IS_ERR(rdev))
606 return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
607 "failed to register %s regulator\n",
608 desc->name);
1aad3900
MV
609 }
610 return 0;
611}
612
613static const struct platform_device_id bd7181x_pmic_id[] = {
614 { "bd71815-pmic", ROHM_CHIP_TYPE_BD71815 },
615 { },
616};
617MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);
618
619static struct platform_driver bd7181x_regulator = {
620 .driver = {
621 .name = "bd7181x-pmic",
1aad3900
MV
622 },
623 .probe = bd7181x_probe,
624 .id_table = bd7181x_pmic_id,
625};
626module_platform_driver(bd7181x_regulator);
627
628MODULE_AUTHOR("Tony Luo <luofc@embedinfo.com>");
629MODULE_DESCRIPTION("BD71815 voltage regulator driver");
630MODULE_LICENSE("GPL v2");
631MODULE_ALIAS("platform:bd7181x-pmic");