blob: 8ff47ea522d6904650c0f30e53c76ec98d150bc5 [file] [log] [blame]
Matti Vaittinenba087992018-05-30 11:43:43 +03001// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2018 ROHM Semiconductors
Matti Vaittinendd2be632018-09-14 11:32:26 +03003// bd71837-regulator.c ROHM BD71837MWV/BD71847MWV regulator driver
Matti Vaittinenba087992018-05-30 11:43:43 +03004
Matti Vaittinenc9dc4cf2018-06-28 14:22:23 +03005#include <linux/delay.h>
Matti Vaittinenba087992018-05-30 11:43:43 +03006#include <linux/err.h>
7#include <linux/interrupt.h>
Matti Vaittinenc9dc4cf2018-06-28 14:22:23 +03008#include <linux/kernel.h>
Matti Vaittinen410e8b42018-07-30 14:50:08 +03009#include <linux/mfd/rohm-bd718x7.h>
Matti Vaittinenc9dc4cf2018-06-28 14:22:23 +030010#include <linux/module.h>
Matti Vaittinen9cce7242018-10-29 14:16:30 +020011#include <linux/of.h>
Matti Vaittinenba087992018-05-30 11:43:43 +030012#include <linux/platform_device.h>
13#include <linux/regulator/driver.h>
14#include <linux/regulator/machine.h>
Matti Vaittinenba087992018-05-30 11:43:43 +030015#include <linux/regulator/of_regulator.h>
Matti Vaittinenc9dc4cf2018-06-28 14:22:23 +030016#include <linux/slab.h>
Matti Vaittinenba087992018-05-30 11:43:43 +030017
Guido Günther3b66e4a2020-12-18 19:38:07 +010018/* Typical regulator startup times as per data sheet in uS */
19#define BD71847_BUCK1_STARTUP_TIME 144
20#define BD71847_BUCK2_STARTUP_TIME 162
21#define BD71847_BUCK3_STARTUP_TIME 162
22#define BD71847_BUCK4_STARTUP_TIME 240
23#define BD71847_BUCK5_STARTUP_TIME 270
24#define BD71847_BUCK6_STARTUP_TIME 200
25#define BD71847_LDO1_STARTUP_TIME 440
26#define BD71847_LDO2_STARTUP_TIME 370
27#define BD71847_LDO3_STARTUP_TIME 310
28#define BD71847_LDO4_STARTUP_TIME 400
29#define BD71847_LDO5_STARTUP_TIME 530
30#define BD71847_LDO6_STARTUP_TIME 400
31
32#define BD71837_BUCK1_STARTUP_TIME 160
33#define BD71837_BUCK2_STARTUP_TIME 180
34#define BD71837_BUCK3_STARTUP_TIME 180
35#define BD71837_BUCK4_STARTUP_TIME 180
36#define BD71837_BUCK5_STARTUP_TIME 160
37#define BD71837_BUCK6_STARTUP_TIME 240
38#define BD71837_BUCK7_STARTUP_TIME 220
39#define BD71837_BUCK8_STARTUP_TIME 200
40#define BD71837_LDO1_STARTUP_TIME 440
41#define BD71837_LDO2_STARTUP_TIME 370
42#define BD71837_LDO3_STARTUP_TIME 310
43#define BD71837_LDO4_STARTUP_TIME 400
44#define BD71837_LDO5_STARTUP_TIME 310
45#define BD71837_LDO6_STARTUP_TIME 400
46#define BD71837_LDO7_STARTUP_TIME 530
47
Matti Vaittinenba087992018-05-30 11:43:43 +030048/*
Matti Vaittinen1d848d62020-09-03 21:39:02 +030049 * BD718(37/47/50) have two "enable control modes". ON/OFF can either be
50 * controlled by software - or by PMIC internal HW state machine. Whether
51 * regulator should be under SW or HW control can be defined from device-tree.
52 * Let's provide separate ops for regulators to use depending on the "enable
53 * control mode".
54 */
55#define BD718XX_HWOPNAME(swopname) swopname##_hwcontrol
56
57#define BD718XX_OPS(name, _list_voltage, _map_voltage, _set_voltage_sel, \
58 _get_voltage_sel, _set_voltage_time_sel, _set_ramp_delay) \
59static const struct regulator_ops name = { \
60 .enable = regulator_enable_regmap, \
61 .disable = regulator_disable_regmap, \
62 .is_enabled = regulator_is_enabled_regmap, \
63 .list_voltage = (_list_voltage), \
64 .map_voltage = (_map_voltage), \
65 .set_voltage_sel = (_set_voltage_sel), \
66 .get_voltage_sel = (_get_voltage_sel), \
67 .set_voltage_time_sel = (_set_voltage_time_sel), \
68 .set_ramp_delay = (_set_ramp_delay), \
69}; \
70 \
71static const struct regulator_ops BD718XX_HWOPNAME(name) = { \
72 .is_enabled = always_enabled_by_hwstate, \
73 .list_voltage = (_list_voltage), \
74 .map_voltage = (_map_voltage), \
75 .set_voltage_sel = (_set_voltage_sel), \
76 .get_voltage_sel = (_get_voltage_sel), \
77 .set_voltage_time_sel = (_set_voltage_time_sel), \
78 .set_ramp_delay = (_set_ramp_delay), \
79} \
80
81/*
Matti Vaittinenba087992018-05-30 11:43:43 +030082 * BUCK1/2/3/4
83 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
84 * 00: 10.00mV/usec 10mV 1uS
85 * 01: 5.00mV/usec 10mV 2uS
86 * 10: 2.50mV/usec 10mV 4uS
87 * 11: 1.25mV/usec 10mV 8uS
88 */
Matti Vaittinendd2be632018-09-14 11:32:26 +030089static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
Matti Vaittinenba087992018-05-30 11:43:43 +030090 int ramp_delay)
91{
Axel Lin0a245f02019-04-07 17:03:02 +080092 int id = rdev_get_id(rdev);
93 unsigned int ramp_value;
Matti Vaittinenba087992018-05-30 11:43:43 +030094
Axel Linbcb047e2018-10-04 15:25:58 +080095 dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1,
Matti Vaittinenba087992018-05-30 11:43:43 +030096 ramp_delay);
97 switch (ramp_delay) {
98 case 1 ... 1250:
99 ramp_value = BUCK_RAMPRATE_1P25MV;
100 break;
101 case 1251 ... 2500:
102 ramp_value = BUCK_RAMPRATE_2P50MV;
103 break;
104 case 2501 ... 5000:
105 ramp_value = BUCK_RAMPRATE_5P00MV;
106 break;
107 case 5001 ... 10000:
108 ramp_value = BUCK_RAMPRATE_10P00MV;
109 break;
110 default:
111 ramp_value = BUCK_RAMPRATE_10P00MV;
Axel Linbcb047e2018-10-04 15:25:58 +0800112 dev_err(&rdev->dev,
Matti Vaittinenba087992018-05-30 11:43:43 +0300113 "%s: ramp_delay: %d not supported, setting 10000mV//us\n",
114 rdev->desc->name, ramp_delay);
115 }
116
Axel Linbcb047e2018-10-04 15:25:58 +0800117 return regmap_update_bits(rdev->regmap, BD718XX_REG_BUCK1_CTRL + id,
Matti Vaittinenba087992018-05-30 11:43:43 +0300118 BUCK_RAMPRATE_MASK, ramp_value << 6);
119}
120
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300121/* These functions are used when regulators are under HW state machine control.
122 * We assume PMIC is in RUN state because SW running and able to query the
123 * status. Most of the regulators have fixed ON or OFF state at RUN/IDLE so for
124 * them we just return a constant. BD71837 BUCK3 and BUCK4 are exceptions as
125 * they support configuring the ON/OFF state for RUN.
126 *
127 * Note for next hacker - these PMICs have a register where the HW state can be
128 * read. If assuming RUN appears to be false in your use-case - you can
129 * implement state reading (although that is not going to be atomic) before
130 * returning the enable state.
131 */
132static int always_enabled_by_hwstate(struct regulator_dev *rdev)
133{
134 return 1;
135}
136
137static int never_enabled_by_hwstate(struct regulator_dev *rdev)
138{
139 return 0;
140}
141
142static int bd71837_get_buck34_enable_hwctrl(struct regulator_dev *rdev)
143{
144 int ret;
145 unsigned int val;
146
147 ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
148 if (ret)
149 return ret;
150
151 return !!(BD718XX_BUCK_RUN_ON & val);
152}
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300153/*
154 * On BD71837 (not on BD71847, BD71850, ...)
155 * Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
Matti Vaittinenba087992018-05-30 11:43:43 +0300156 * Bucks 5 to 8 and LDOs can use PFM and must be disabled when voltage
157 * is changed. Hence we return -EBUSY for these if voltage is changed
158 * when BUCK/LDO is enabled.
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300159 *
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300160 * On BD71847, BD71850, ... The LDO voltage can be changed when LDO is
161 * enabled. But if voltage is increased the LDO power-good monitoring
162 * must be disabled for the duration of changing + 1mS to ensure voltage
163 * has reached the higher level before HW does next under voltage detection
164 * cycle.
Matti Vaittinenba087992018-05-30 11:43:43 +0300165 */
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300166static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
Matti Vaittinenba087992018-05-30 11:43:43 +0300167 unsigned int sel)
168{
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300169 if (rdev->desc->ops->is_enabled(rdev))
Axel Linffdc4982018-06-27 20:40:14 +0800170 return -EBUSY;
Matti Vaittinenba087992018-05-30 11:43:43 +0300171
Axel Linffdc4982018-06-27 20:40:14 +0800172 return regulator_set_voltage_sel_regmap(rdev, sel);
Matti Vaittinenba087992018-05-30 11:43:43 +0300173}
174
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300175static void voltage_change_done(struct regulator_dev *rdev, unsigned int sel,
176 unsigned int *mask)
177{
178 int ret;
179
180 if (*mask) {
181 /*
182 * Let's allow scheduling as we use I2C anyways. We just need to
183 * guarantee minimum of 1ms sleep - it shouldn't matter if we
184 * exceed it due to the scheduling.
185 */
186 msleep(1);
187 /*
188 * Note for next hacker. The PWRGOOD should not be masked on
189 * BD71847 so we will just unconditionally enable detection
190 * when voltage is set.
191 * If someone want's to disable PWRGOOD he must implement
192 * caching and restoring the old value here. I am not
193 * aware of such use-cases so for the sake of the simplicity
194 * we just always enable PWRGOOD here.
195 */
196 ret = regmap_update_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2,
197 *mask, 0);
198 if (ret)
199 dev_err(&rdev->dev,
200 "Failed to re-enable voltage monitoring (%d)\n",
201 ret);
202 }
203}
204
205static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel,
206 unsigned int *mask)
207{
208 int ret;
209
210 *mask = 0;
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300211 if (rdev->desc->ops->is_enabled(rdev)) {
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300212 int now, new;
213
214 now = rdev->desc->ops->get_voltage_sel(rdev);
215 if (now < 0)
216 return now;
217
218 now = rdev->desc->ops->list_voltage(rdev, now);
219 if (now < 0)
220 return now;
221
222 new = rdev->desc->ops->list_voltage(rdev, sel);
223 if (new < 0)
224 return new;
225
226 /*
227 * If we increase LDO voltage when LDO is enabled we need to
228 * disable the power-good detection until voltage has reached
229 * the new level. According to HW colleagues the maximum time
230 * it takes is 1000us. I assume that on systems with light load
231 * this might be less - and we could probably use DT to give
232 * system specific delay value if performance matters.
233 *
234 * Well, knowing we use I2C here and can add scheduling delays
235 * I don't think it is worth the hassle and I just add fixed
236 * 1ms sleep here (and allow scheduling). If this turns out to
237 * be a problem we can change it to delay and make the delay
238 * time configurable.
239 */
240 if (new > now) {
241 int ldo_offset = rdev->desc->id - BD718XX_LDO1;
242
243 *mask = BD718XX_LDO1_VRMON80 << ldo_offset;
244 ret = regmap_update_bits(rdev->regmap,
245 BD718XX_REG_MVRFLTMASK2,
246 *mask, *mask);
247 if (ret) {
248 dev_err(&rdev->dev,
249 "Failed to stop voltage monitoring\n");
250 return ret;
251 }
252 }
253 }
254
255 return 0;
256}
257
258static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
259 unsigned int sel)
260{
261 int ret;
262 int mask;
263
264 ret = voltage_change_prepare(rdev, sel, &mask);
265 if (ret)
266 return ret;
267
268 ret = regulator_set_voltage_sel_regmap(rdev, sel);
269 voltage_change_done(rdev, sel, &mask);
270
271 return ret;
272}
273
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300274static int bd718xx_set_voltage_sel_pickable_restricted(
275 struct regulator_dev *rdev, unsigned int sel)
276{
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300277 int ret;
278 int mask;
279
280 ret = voltage_change_prepare(rdev, sel, &mask);
281 if (ret)
282 return ret;
283
284 ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel);
285 voltage_change_done(rdev, sel, &mask);
286
287 return ret;
288}
289
290static int bd71837_set_voltage_sel_pickable_restricted(
291 struct regulator_dev *rdev, unsigned int sel)
292{
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300293 if (rdev->desc->ops->is_enabled(rdev))
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300294 return -EBUSY;
295
296 return regulator_set_voltage_sel_pickable_regmap(rdev, sel);
297}
298
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300299/*
300 * OPS common for BD71847 and BD71850
301 */
302BD718XX_OPS(bd718xx_pickable_range_ldo_ops,
303 regulator_list_voltage_pickable_linear_range, NULL,
304 bd718xx_set_voltage_sel_pickable_restricted,
305 regulator_get_voltage_sel_pickable_regmap, NULL, NULL);
306
307/* BD71847 and BD71850 LDO 5 is by default OFF at RUN state */
308static const struct regulator_ops bd718xx_ldo5_ops_hwstate = {
309 .is_enabled = never_enabled_by_hwstate,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300310 .list_voltage = regulator_list_voltage_pickable_linear_range,
311 .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
312 .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300313};
314
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300315BD718XX_OPS(bd718xx_pickable_range_buck_ops,
316 regulator_list_voltage_pickable_linear_range, NULL,
317 regulator_set_voltage_sel_pickable_regmap,
318 regulator_get_voltage_sel_pickable_regmap,
319 regulator_set_voltage_time_sel, NULL);
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300320
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300321BD718XX_OPS(bd718xx_ldo_regulator_ops, regulator_list_voltage_linear_range,
322 NULL, bd718xx_set_voltage_sel_restricted,
323 regulator_get_voltage_sel_regmap, NULL, NULL);
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300324
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300325BD718XX_OPS(bd718xx_ldo_regulator_nolinear_ops, regulator_list_voltage_table,
326 NULL, bd718xx_set_voltage_sel_restricted,
327 regulator_get_voltage_sel_regmap, NULL, NULL);
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300328
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300329BD718XX_OPS(bd718xx_buck_regulator_ops, regulator_list_voltage_linear_range,
330 NULL, regulator_set_voltage_sel_regmap,
331 regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
332 NULL);
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300333
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300334BD718XX_OPS(bd718xx_buck_regulator_nolinear_ops, regulator_list_voltage_table,
335 regulator_map_voltage_ascend, regulator_set_voltage_sel_regmap,
336 regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
337 NULL);
Matti Vaittinenba087992018-05-30 11:43:43 +0300338
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300339/*
340 * OPS for BD71837
341 */
342BD718XX_OPS(bd71837_pickable_range_ldo_ops,
343 regulator_list_voltage_pickable_linear_range, NULL,
344 bd71837_set_voltage_sel_pickable_restricted,
345 regulator_get_voltage_sel_pickable_regmap, NULL, NULL);
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300346
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300347BD718XX_OPS(bd71837_pickable_range_buck_ops,
348 regulator_list_voltage_pickable_linear_range, NULL,
349 bd71837_set_voltage_sel_pickable_restricted,
350 regulator_get_voltage_sel_pickable_regmap,
351 regulator_set_voltage_time_sel, NULL);
Matti Vaittinenba087992018-05-30 11:43:43 +0300352
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300353BD718XX_OPS(bd71837_ldo_regulator_ops, regulator_list_voltage_linear_range,
354 NULL, bd71837_set_voltage_sel_restricted,
355 regulator_get_voltage_sel_regmap, NULL, NULL);
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300356
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300357BD718XX_OPS(bd71837_ldo_regulator_nolinear_ops, regulator_list_voltage_table,
358 NULL, bd71837_set_voltage_sel_restricted,
359 regulator_get_voltage_sel_regmap, NULL, NULL);
Matti Vaittinenba087992018-05-30 11:43:43 +0300360
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300361BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range,
362 NULL, bd71837_set_voltage_sel_restricted,
363 regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
364 NULL);
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300365
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300366BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table,
367 regulator_map_voltage_ascend, bd718xx_set_voltage_sel_restricted,
368 regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
369 NULL);
370/*
371 * BD71837 bucks 3 and 4 support defining their enable/disable state also
372 * when buck enable state is under HW state machine control. In that case the
373 * bit [2] in CTRL register is used to indicate if regulator should be ON.
374 */
375static const struct regulator_ops bd71837_buck34_ops_hwctrl = {
376 .is_enabled = bd71837_get_buck34_enable_hwctrl,
Matti Vaittinenba087992018-05-30 11:43:43 +0300377 .list_voltage = regulator_list_voltage_linear_range,
378 .set_voltage_sel = regulator_set_voltage_sel_regmap,
379 .get_voltage_sel = regulator_get_voltage_sel_regmap,
380 .set_voltage_time_sel = regulator_set_voltage_time_sel,
Matti Vaittinendd2be632018-09-14 11:32:26 +0300381 .set_ramp_delay = bd718xx_buck1234_set_ramp_delay,
Matti Vaittinenba087992018-05-30 11:43:43 +0300382};
383
384/*
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300385 * OPS for all of the ICs - BD718(37/47/50)
386 */
387BD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range,
388 NULL, regulator_set_voltage_sel_regmap,
389 regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel,
390 bd718xx_buck1234_set_ramp_delay);
391
392/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300393 * BD71837 BUCK1/2/3/4
394 * BD71847 BUCK1/2
Matti Vaittinenba087992018-05-30 11:43:43 +0300395 * 0.70 to 1.30V (10mV step)
396 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300397static const struct linear_range bd718xx_dvs_buck_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300398 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
399 REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
400};
401
402/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300403 * BD71837 BUCK5
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300404 * 0.7V to 1.35V (range 0)
405 * and
406 * 0.675 to 1.325 (range 1)
Matti Vaittinenba087992018-05-30 11:43:43 +0300407 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300408static const struct linear_range bd71837_buck5_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300409 /* Ranges when VOLT_SEL bit is 0 */
Matti Vaittinenba087992018-05-30 11:43:43 +0300410 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
411 REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
412 REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300413 /* Ranges when VOLT_SEL bit is 1 */
414 REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
415 REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
416 REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300417};
418
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300419/*
420 * Range selector for first 3 linear ranges is 0x0
421 * and 0x1 for last 3 ranges.
422 */
423static const unsigned int bd71837_buck5_volt_range_sel[] = {
424 0x0, 0x0, 0x0, 0x80, 0x80, 0x80
Matti Vaittinen494edd22018-09-14 11:27:46 +0300425};
426
Matti Vaittinenba087992018-05-30 11:43:43 +0300427/*
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300428 * BD71847 BUCK3
429 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300430static const struct linear_range bd71847_buck3_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300431 /* Ranges when VOLT_SEL bits are 00 */
432 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
433 REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
434 REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
435 /* Ranges when VOLT_SEL bits are 01 */
436 REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000),
437 /* Ranges when VOLT_SEL bits are 11 */
438 REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
439 REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
440 REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
441};
442
443static const unsigned int bd71847_buck3_volt_range_sel[] = {
444 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
445};
446
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300447static const struct linear_range bd71847_buck4_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300448 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
449 REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
450};
451
452static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
453
454/*
Matti Vaittinenba087992018-05-30 11:43:43 +0300455 * BUCK6
456 * 3.0V to 3.3V (step 100mV)
457 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300458static const struct linear_range bd71837_buck6_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300459 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
460};
461
462/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300463 * BD71837 BUCK7
464 * BD71847 BUCK5
Matti Vaittinenba087992018-05-30 11:43:43 +0300465 * 000 = 1.605V
466 * 001 = 1.695V
467 * 010 = 1.755V
468 * 011 = 1.8V (Initial)
469 * 100 = 1.845V
470 * 101 = 1.905V
471 * 110 = 1.95V
472 * 111 = 1.995V
473 */
Matti Vaittinen494edd22018-09-14 11:27:46 +0300474static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300475 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
476};
477
478/*
479 * BUCK8
480 * 0.8V to 1.40V (step 10mV)
481 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300482static const struct linear_range bd718xx_4th_nodvs_buck_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300483 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300484};
485
486/*
487 * LDO1
488 * 3.0 to 3.3V (100mV step)
489 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300490static const struct linear_range bd718xx_ldo1_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300491 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300492 REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300493};
494
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300495static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 };
496
Matti Vaittinenba087992018-05-30 11:43:43 +0300497/*
498 * LDO2
499 * 0.8 or 0.9V
500 */
Axel Linadb78a82018-06-27 20:40:13 +0800501static const unsigned int ldo_2_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300502 900000, 800000
503};
504
505/*
506 * LDO3
507 * 1.8 to 3.3V (100mV step)
508 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300509static const struct linear_range bd718xx_ldo3_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300510 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
511};
512
513/*
514 * LDO4
515 * 0.9 to 1.8V (100mV step)
516 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300517static const struct linear_range bd718xx_ldo4_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300518 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300519};
520
521/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300522 * LDO5 for BD71837
Matti Vaittinenba087992018-05-30 11:43:43 +0300523 * 1.8 to 3.3V (100mV step)
524 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300525static const struct linear_range bd71837_ldo5_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300526 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
527};
528
529/*
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300530 * LDO5 for BD71837
531 * 1.8 to 3.3V (100mV step)
532 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300533static const struct linear_range bd71847_ldo5_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300534 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
535 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
536};
537
538static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
539
540/*
Matti Vaittinenba087992018-05-30 11:43:43 +0300541 * LDO6
542 * 0.9 to 1.8V (100mV step)
543 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300544static const struct linear_range bd718xx_ldo6_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300545 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300546};
547
548/*
549 * LDO7
550 * 1.8 to 3.3V (100mV step)
551 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300552static const struct linear_range bd71837_ldo7_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300553 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
554};
555
Matti Vaittinenba087992018-05-30 11:43:43 +0300556struct reg_init {
557 unsigned int reg;
558 unsigned int mask;
Matti Vaittinen494edd22018-09-14 11:27:46 +0300559 unsigned int val;
560};
561struct bd718xx_regulator_data {
562 struct regulator_desc desc;
Matti Vaittinen21b72152020-01-20 15:44:45 +0200563 const struct rohm_dvs_config dvs;
Matti Vaittinen494edd22018-09-14 11:27:46 +0300564 const struct reg_init init;
565 const struct reg_init *additional_inits;
566 int additional_init_amnt;
567};
568
569/*
570 * There is a HW quirk in BD71837. The shutdown sequence timings for
571 * bucks/LDOs which are controlled via register interface are changed.
572 * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
573 * beginning of shut-down sequence. As bucks 6 and 7 are parent
574 * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
575 * monitoring to errorneously detect under voltage and force PMIC to
576 * emergency state instead of poweroff. In order to avoid this we
577 * disable voltage monitoring for LDO5 and LDO6
578 */
579static const struct reg_init bd71837_ldo5_inits[] = {
580 {
581 .reg = BD718XX_REG_MVRFLTMASK2,
582 .mask = BD718XX_LDO5_VRMON80,
583 .val = BD718XX_LDO5_VRMON80,
584 },
585};
586
587static const struct reg_init bd71837_ldo6_inits[] = {
588 {
589 .reg = BD718XX_REG_MVRFLTMASK2,
590 .mask = BD718XX_LDO6_VRMON80,
591 .val = BD718XX_LDO6_VRMON80,
592 },
593};
594
Matti Vaittinen21b72152020-01-20 15:44:45 +0200595static int buck_set_hw_dvs_levels(struct device_node *np,
Matti Vaittinen049369d2019-02-14 11:39:36 +0200596 const struct regulator_desc *desc,
597 struct regulator_config *cfg)
598{
Matti Vaittinen21b72152020-01-20 15:44:45 +0200599 struct bd718xx_regulator_data *data;
Matti Vaittinen049369d2019-02-14 11:39:36 +0200600
Matti Vaittinen21b72152020-01-20 15:44:45 +0200601 data = container_of(desc, struct bd718xx_regulator_data, desc);
Matti Vaittinen049369d2019-02-14 11:39:36 +0200602
Matti Vaittinen21b72152020-01-20 15:44:45 +0200603 return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
Matti Vaittinen049369d2019-02-14 11:39:36 +0200604}
605
YueHaibing02f8eaa2020-09-10 11:42:40 +0800606static const struct regulator_ops *bd71847_swcontrol_ops[] = {
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300607 &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops,
608 &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops,
609 &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops,
610 &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_nolinear_ops,
611 &bd718xx_ldo_regulator_ops, &bd718xx_ldo_regulator_ops,
612 &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops,
613};
614
YueHaibing02f8eaa2020-09-10 11:42:40 +0800615static const struct regulator_ops *bd71847_hwcontrol_ops[] = {
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300616 &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
617 &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
618 &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops),
619 &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops),
620 &BD718XX_HWOPNAME(bd718xx_buck_regulator_nolinear_ops),
621 &BD718XX_HWOPNAME(bd718xx_buck_regulator_ops),
622 &BD718XX_HWOPNAME(bd718xx_pickable_range_ldo_ops),
623 &BD718XX_HWOPNAME(bd718xx_ldo_regulator_nolinear_ops),
624 &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops),
625 &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops),
626 &bd718xx_ldo5_ops_hwstate,
627 &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops),
628};
629
630static struct bd718xx_regulator_data bd71847_regulators[] = {
Matti Vaittinen494edd22018-09-14 11:27:46 +0300631 {
632 .desc = {
633 .name = "buck1",
634 .of_match = of_match_ptr("BUCK1"),
635 .regulators_node = of_match_ptr("regulators"),
636 .id = BD718XX_BUCK1,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300637 .type = REGULATOR_VOLTAGE,
638 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
639 .linear_ranges = bd718xx_dvs_buck_volts,
640 .n_linear_ranges =
641 ARRAY_SIZE(bd718xx_dvs_buck_volts),
642 .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
643 .vsel_mask = DVS_BUCK_RUN_MASK,
644 .enable_reg = BD718XX_REG_BUCK1_CTRL,
645 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100646 .enable_time = BD71847_BUCK1_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300647 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200648 .of_parse_cb = buck_set_hw_dvs_levels,
649 },
650 .dvs = {
651 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
652 ROHM_DVS_LEVEL_SUSPEND,
653 .run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
654 .run_mask = DVS_BUCK_RUN_MASK,
655 .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
656 .idle_mask = DVS_BUCK_RUN_MASK,
657 .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
658 .suspend_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300659 },
660 .init = {
661 .reg = BD718XX_REG_BUCK1_CTRL,
662 .mask = BD718XX_BUCK_SEL,
663 .val = BD718XX_BUCK_SEL,
664 },
665 },
666 {
667 .desc = {
668 .name = "buck2",
669 .of_match = of_match_ptr("BUCK2"),
670 .regulators_node = of_match_ptr("regulators"),
671 .id = BD718XX_BUCK2,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300672 .type = REGULATOR_VOLTAGE,
673 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
674 .linear_ranges = bd718xx_dvs_buck_volts,
675 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
676 .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
677 .vsel_mask = DVS_BUCK_RUN_MASK,
678 .enable_reg = BD718XX_REG_BUCK2_CTRL,
679 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100680 .enable_time = BD71847_BUCK2_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300681 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200682 .of_parse_cb = buck_set_hw_dvs_levels,
683 },
684 .dvs = {
685 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
686 .run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
687 .run_mask = DVS_BUCK_RUN_MASK,
688 .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
689 .idle_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300690 },
691 .init = {
692 .reg = BD718XX_REG_BUCK2_CTRL,
693 .mask = BD718XX_BUCK_SEL,
694 .val = BD718XX_BUCK_SEL,
695 },
696 },
697 {
698 .desc = {
699 .name = "buck3",
700 .of_match = of_match_ptr("BUCK3"),
701 .regulators_node = of_match_ptr("regulators"),
702 .id = BD718XX_BUCK3,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300703 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300704 .n_voltages = BD71847_BUCK3_VOLTAGE_NUM,
705 .linear_ranges = bd71847_buck3_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300706 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300707 ARRAY_SIZE(bd71847_buck3_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300708 .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
709 .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300710 .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
711 .vsel_range_mask = BD71847_BUCK3_RANGE_MASK,
712 .linear_range_selectors = bd71847_buck3_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300713 .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
714 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100715 .enable_time = BD71847_BUCK3_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300716 .owner = THIS_MODULE,
717 },
718 .init = {
719 .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
720 .mask = BD718XX_BUCK_SEL,
721 .val = BD718XX_BUCK_SEL,
722 },
723 },
724 {
725 .desc = {
726 .name = "buck4",
727 .of_match = of_match_ptr("BUCK4"),
728 .regulators_node = of_match_ptr("regulators"),
729 .id = BD718XX_BUCK4,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300730 .type = REGULATOR_VOLTAGE,
731 .n_voltages = BD71847_BUCK4_VOLTAGE_NUM,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300732 .linear_ranges = bd71847_buck4_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300733 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300734 ARRAY_SIZE(bd71847_buck4_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300735 .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
736 .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
737 .vsel_mask = BD71847_BUCK4_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300738 .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
739 .vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
740 .linear_range_selectors = bd71847_buck4_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300741 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100742 .enable_time = BD71847_BUCK4_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300743 .owner = THIS_MODULE,
744 },
745 .init = {
746 .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
747 .mask = BD718XX_BUCK_SEL,
748 .val = BD718XX_BUCK_SEL,
749 },
750 },
751 {
752 .desc = {
753 .name = "buck5",
754 .of_match = of_match_ptr("BUCK5"),
Matti Vaittinendd2be632018-09-14 11:32:26 +0300755 .regulators_node = of_match_ptr("regulators"),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300756 .id = BD718XX_BUCK5,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300757 .type = REGULATOR_VOLTAGE,
758 .volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
759 .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
760 .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
761 .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
762 .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
763 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100764 .enable_time = BD71847_BUCK5_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300765 .owner = THIS_MODULE,
766 },
767 .init = {
768 .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
769 .mask = BD718XX_BUCK_SEL,
770 .val = BD718XX_BUCK_SEL,
771 },
772 },
773 {
774 .desc = {
775 .name = "buck6",
776 .of_match = of_match_ptr("BUCK6"),
777 .regulators_node = of_match_ptr("regulators"),
778 .id = BD718XX_BUCK6,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300779 .type = REGULATOR_VOLTAGE,
Matti Vaittinendd2be632018-09-14 11:32:26 +0300780 .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300781 .linear_ranges = bd718xx_4th_nodvs_buck_volts,
782 .n_linear_ranges =
783 ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
784 .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
785 .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
786 .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
787 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100788 .enable_time = BD71847_BUCK6_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300789 .owner = THIS_MODULE,
790 },
791 .init = {
792 .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
793 .mask = BD718XX_BUCK_SEL,
794 .val = BD718XX_BUCK_SEL,
795 },
796 },
797 {
798 .desc = {
799 .name = "ldo1",
800 .of_match = of_match_ptr("LDO1"),
801 .regulators_node = of_match_ptr("regulators"),
802 .id = BD718XX_LDO1,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300803 .type = REGULATOR_VOLTAGE,
804 .n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
805 .linear_ranges = bd718xx_ldo1_volts,
806 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
807 .vsel_reg = BD718XX_REG_LDO1_VOLT,
808 .vsel_mask = BD718XX_LDO1_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300809 .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
810 .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
811 .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300812 .enable_reg = BD718XX_REG_LDO1_VOLT,
813 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100814 .enable_time = BD71847_LDO1_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300815 .owner = THIS_MODULE,
816 },
817 .init = {
818 .reg = BD718XX_REG_LDO1_VOLT,
819 .mask = BD718XX_LDO_SEL,
820 .val = BD718XX_LDO_SEL,
821 },
822 },
823 {
824 .desc = {
825 .name = "ldo2",
826 .of_match = of_match_ptr("LDO2"),
827 .regulators_node = of_match_ptr("regulators"),
828 .id = BD718XX_LDO2,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300829 .type = REGULATOR_VOLTAGE,
830 .volt_table = &ldo_2_volts[0],
831 .vsel_reg = BD718XX_REG_LDO2_VOLT,
832 .vsel_mask = BD718XX_LDO2_MASK,
833 .n_voltages = ARRAY_SIZE(ldo_2_volts),
834 .enable_reg = BD718XX_REG_LDO2_VOLT,
835 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100836 .enable_time = BD71847_LDO2_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300837 .owner = THIS_MODULE,
838 },
839 .init = {
840 .reg = BD718XX_REG_LDO2_VOLT,
841 .mask = BD718XX_LDO_SEL,
842 .val = BD718XX_LDO_SEL,
843 },
844 },
845 {
846 .desc = {
847 .name = "ldo3",
848 .of_match = of_match_ptr("LDO3"),
849 .regulators_node = of_match_ptr("regulators"),
850 .id = BD718XX_LDO3,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300851 .type = REGULATOR_VOLTAGE,
852 .n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
853 .linear_ranges = bd718xx_ldo3_volts,
854 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
855 .vsel_reg = BD718XX_REG_LDO3_VOLT,
856 .vsel_mask = BD718XX_LDO3_MASK,
857 .enable_reg = BD718XX_REG_LDO3_VOLT,
858 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100859 .enable_time = BD71847_LDO3_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300860 .owner = THIS_MODULE,
861 },
862 .init = {
863 .reg = BD718XX_REG_LDO3_VOLT,
864 .mask = BD718XX_LDO_SEL,
865 .val = BD718XX_LDO_SEL,
866 },
867 },
868 {
869 .desc = {
870 .name = "ldo4",
871 .of_match = of_match_ptr("LDO4"),
872 .regulators_node = of_match_ptr("regulators"),
873 .id = BD718XX_LDO4,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300874 .type = REGULATOR_VOLTAGE,
875 .n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
876 .linear_ranges = bd718xx_ldo4_volts,
877 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
878 .vsel_reg = BD718XX_REG_LDO4_VOLT,
879 .vsel_mask = BD718XX_LDO4_MASK,
880 .enable_reg = BD718XX_REG_LDO4_VOLT,
881 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100882 .enable_time = BD71847_LDO4_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300883 .owner = THIS_MODULE,
884 },
885 .init = {
886 .reg = BD718XX_REG_LDO4_VOLT,
887 .mask = BD718XX_LDO_SEL,
888 .val = BD718XX_LDO_SEL,
889 },
890 },
891 {
892 .desc = {
893 .name = "ldo5",
894 .of_match = of_match_ptr("LDO5"),
895 .regulators_node = of_match_ptr("regulators"),
896 .id = BD718XX_LDO5,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300897 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300898 .n_voltages = BD71847_LDO5_VOLTAGE_NUM,
899 .linear_ranges = bd71847_ldo5_volts,
900 .n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300901 .vsel_reg = BD718XX_REG_LDO5_VOLT,
902 .vsel_mask = BD71847_LDO5_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300903 .vsel_range_reg = BD718XX_REG_LDO5_VOLT,
904 .vsel_range_mask = BD71847_LDO5_RANGE_MASK,
905 .linear_range_selectors = bd71847_ldo5_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300906 .enable_reg = BD718XX_REG_LDO5_VOLT,
907 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100908 .enable_time = BD71847_LDO5_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300909 .owner = THIS_MODULE,
910 },
911 .init = {
912 .reg = BD718XX_REG_LDO5_VOLT,
913 .mask = BD718XX_LDO_SEL,
914 .val = BD718XX_LDO_SEL,
915 },
916 },
917 {
918 .desc = {
919 .name = "ldo6",
920 .of_match = of_match_ptr("LDO6"),
921 .regulators_node = of_match_ptr("regulators"),
922 .id = BD718XX_LDO6,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300923 .type = REGULATOR_VOLTAGE,
924 .n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
925 .linear_ranges = bd718xx_ldo6_volts,
926 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
927 /* LDO6 is supplied by buck5 */
928 .supply_name = "buck5",
929 .vsel_reg = BD718XX_REG_LDO6_VOLT,
930 .vsel_mask = BD718XX_LDO6_MASK,
931 .enable_reg = BD718XX_REG_LDO6_VOLT,
932 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100933 .enable_time = BD71847_LDO6_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300934 .owner = THIS_MODULE,
935 },
936 .init = {
937 .reg = BD718XX_REG_LDO6_VOLT,
938 .mask = BD718XX_LDO_SEL,
939 .val = BD718XX_LDO_SEL,
940 },
941 },
942};
943
YueHaibing02f8eaa2020-09-10 11:42:40 +0800944static const struct regulator_ops *bd71837_swcontrol_ops[] = {
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300945 &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops,
946 &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops,
947 &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops,
948 &bd71837_buck_regulator_nolinear_ops, &bd71837_buck_regulator_ops,
949 &bd71837_pickable_range_ldo_ops, &bd71837_ldo_regulator_nolinear_ops,
950 &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops,
951 &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops,
952 &bd71837_ldo_regulator_ops,
953};
954
YueHaibing02f8eaa2020-09-10 11:42:40 +0800955static const struct regulator_ops *bd71837_hwcontrol_ops[] = {
Matti Vaittinen1d848d62020-09-03 21:39:02 +0300956 &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
957 &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops),
958 &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl,
959 &BD718XX_HWOPNAME(bd71837_pickable_range_buck_ops),
960 &BD718XX_HWOPNAME(bd71837_buck_regulator_ops),
961 &BD718XX_HWOPNAME(bd71837_buck_regulator_nolinear_ops),
962 &BD718XX_HWOPNAME(bd71837_buck_regulator_ops),
963 &BD718XX_HWOPNAME(bd71837_pickable_range_ldo_ops),
964 &BD718XX_HWOPNAME(bd71837_ldo_regulator_nolinear_ops),
965 &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
966 &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
967 &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
968 &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
969 &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops),
970};
971
972static struct bd718xx_regulator_data bd71837_regulators[] = {
Matti Vaittinen494edd22018-09-14 11:27:46 +0300973 {
974 .desc = {
975 .name = "buck1",
976 .of_match = of_match_ptr("BUCK1"),
977 .regulators_node = of_match_ptr("regulators"),
978 .id = BD718XX_BUCK1,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300979 .type = REGULATOR_VOLTAGE,
980 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
981 .linear_ranges = bd718xx_dvs_buck_volts,
982 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
983 .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
984 .vsel_mask = DVS_BUCK_RUN_MASK,
985 .enable_reg = BD718XX_REG_BUCK1_CTRL,
986 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +0100987 .enable_time = BD71837_BUCK1_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300988 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200989 .of_parse_cb = buck_set_hw_dvs_levels,
990 },
991 .dvs = {
992 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
993 ROHM_DVS_LEVEL_SUSPEND,
994 .run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
995 .run_mask = DVS_BUCK_RUN_MASK,
996 .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
997 .idle_mask = DVS_BUCK_RUN_MASK,
998 .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
999 .suspend_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001000 },
1001 .init = {
1002 .reg = BD718XX_REG_BUCK1_CTRL,
1003 .mask = BD718XX_BUCK_SEL,
1004 .val = BD718XX_BUCK_SEL,
1005 },
1006 },
1007 {
1008 .desc = {
1009 .name = "buck2",
1010 .of_match = of_match_ptr("BUCK2"),
1011 .regulators_node = of_match_ptr("regulators"),
1012 .id = BD718XX_BUCK2,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001013 .type = REGULATOR_VOLTAGE,
1014 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
1015 .linear_ranges = bd718xx_dvs_buck_volts,
1016 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
1017 .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
1018 .vsel_mask = DVS_BUCK_RUN_MASK,
1019 .enable_reg = BD718XX_REG_BUCK2_CTRL,
1020 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001021 .enable_time = BD71837_BUCK2_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001022 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +02001023 .of_parse_cb = buck_set_hw_dvs_levels,
1024 },
1025 .dvs = {
1026 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
1027 .run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
1028 .run_mask = DVS_BUCK_RUN_MASK,
1029 .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
1030 .idle_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001031 },
1032 .init = {
1033 .reg = BD718XX_REG_BUCK2_CTRL,
1034 .mask = BD718XX_BUCK_SEL,
1035 .val = BD718XX_BUCK_SEL,
1036 },
1037 },
1038 {
1039 .desc = {
1040 .name = "buck3",
1041 .of_match = of_match_ptr("BUCK3"),
1042 .regulators_node = of_match_ptr("regulators"),
1043 .id = BD718XX_BUCK3,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001044 .type = REGULATOR_VOLTAGE,
1045 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
1046 .linear_ranges = bd718xx_dvs_buck_volts,
1047 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
1048 .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
1049 .vsel_mask = DVS_BUCK_RUN_MASK,
1050 .enable_reg = BD71837_REG_BUCK3_CTRL,
1051 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001052 .enable_time = BD71837_BUCK3_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001053 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +02001054 .of_parse_cb = buck_set_hw_dvs_levels,
1055 },
1056 .dvs = {
1057 .level_map = ROHM_DVS_LEVEL_RUN,
1058 .run_reg = BD71837_REG_BUCK3_VOLT_RUN,
1059 .run_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001060 },
1061 .init = {
1062 .reg = BD71837_REG_BUCK3_CTRL,
1063 .mask = BD718XX_BUCK_SEL,
1064 .val = BD718XX_BUCK_SEL,
1065 },
1066 },
1067 {
1068 .desc = {
1069 .name = "buck4",
1070 .of_match = of_match_ptr("BUCK4"),
1071 .regulators_node = of_match_ptr("regulators"),
1072 .id = BD718XX_BUCK4,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001073 .type = REGULATOR_VOLTAGE,
1074 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
1075 .linear_ranges = bd718xx_dvs_buck_volts,
1076 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
1077 .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
1078 .vsel_mask = DVS_BUCK_RUN_MASK,
1079 .enable_reg = BD71837_REG_BUCK4_CTRL,
1080 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001081 .enable_time = BD71837_BUCK4_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001082 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +02001083 .of_parse_cb = buck_set_hw_dvs_levels,
1084 },
1085 .dvs = {
1086 .level_map = ROHM_DVS_LEVEL_RUN,
1087 .run_reg = BD71837_REG_BUCK4_VOLT_RUN,
1088 .run_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001089 },
1090 .init = {
1091 .reg = BD71837_REG_BUCK4_CTRL,
1092 .mask = BD718XX_BUCK_SEL,
1093 .val = BD718XX_BUCK_SEL,
1094 },
1095 },
1096 {
1097 .desc = {
1098 .name = "buck5",
1099 .of_match = of_match_ptr("BUCK5"),
1100 .regulators_node = of_match_ptr("regulators"),
1101 .id = BD718XX_BUCK5,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001102 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001103 .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
1104 .linear_ranges = bd71837_buck5_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001105 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001106 ARRAY_SIZE(bd71837_buck5_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +03001107 .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001108 .vsel_mask = BD71837_BUCK5_MASK,
1109 .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
1110 .vsel_range_mask = BD71837_BUCK5_RANGE_MASK,
1111 .linear_range_selectors = bd71837_buck5_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001112 .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
1113 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001114 .enable_time = BD71837_BUCK5_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001115 .owner = THIS_MODULE,
1116 },
1117 .init = {
1118 .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
1119 .mask = BD718XX_BUCK_SEL,
1120 .val = BD718XX_BUCK_SEL,
1121 },
1122 },
1123 {
1124 .desc = {
1125 .name = "buck6",
1126 .of_match = of_match_ptr("BUCK6"),
1127 .regulators_node = of_match_ptr("regulators"),
1128 .id = BD718XX_BUCK6,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001129 .type = REGULATOR_VOLTAGE,
1130 .n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001131 .linear_ranges = bd71837_buck6_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001132 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001133 ARRAY_SIZE(bd71837_buck6_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +03001134 .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
1135 .vsel_mask = BD71837_BUCK6_MASK,
1136 .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
1137 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001138 .enable_time = BD71837_BUCK6_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001139 .owner = THIS_MODULE,
1140 },
1141 .init = {
1142 .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
1143 .mask = BD718XX_BUCK_SEL,
1144 .val = BD718XX_BUCK_SEL,
1145 },
1146 },
1147 {
1148 .desc = {
1149 .name = "buck7",
1150 .of_match = of_match_ptr("BUCK7"),
1151 .regulators_node = of_match_ptr("regulators"),
1152 .id = BD718XX_BUCK7,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001153 .type = REGULATOR_VOLTAGE,
1154 .volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
1155 .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
1156 .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
1157 .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
1158 .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
1159 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001160 .enable_time = BD71837_BUCK7_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001161 .owner = THIS_MODULE,
1162 },
1163 .init = {
1164 .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
1165 .mask = BD718XX_BUCK_SEL,
1166 .val = BD718XX_BUCK_SEL,
1167 },
1168 },
1169 {
1170 .desc = {
1171 .name = "buck8",
1172 .of_match = of_match_ptr("BUCK8"),
1173 .regulators_node = of_match_ptr("regulators"),
1174 .id = BD718XX_BUCK8,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001175 .type = REGULATOR_VOLTAGE,
Matti Vaittinendd2be632018-09-14 11:32:26 +03001176 .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001177 .linear_ranges = bd718xx_4th_nodvs_buck_volts,
1178 .n_linear_ranges =
1179 ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
1180 .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
1181 .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
1182 .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
1183 .enable_mask = BD718XX_BUCK_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001184 .enable_time = BD71837_BUCK8_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001185 .owner = THIS_MODULE,
1186 },
1187 .init = {
1188 .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
1189 .mask = BD718XX_BUCK_SEL,
1190 .val = BD718XX_BUCK_SEL,
1191 },
1192 },
1193 {
1194 .desc = {
1195 .name = "ldo1",
1196 .of_match = of_match_ptr("LDO1"),
1197 .regulators_node = of_match_ptr("regulators"),
1198 .id = BD718XX_LDO1,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001199 .type = REGULATOR_VOLTAGE,
1200 .n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
1201 .linear_ranges = bd718xx_ldo1_volts,
1202 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
1203 .vsel_reg = BD718XX_REG_LDO1_VOLT,
1204 .vsel_mask = BD718XX_LDO1_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001205 .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
1206 .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
1207 .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001208 .enable_reg = BD718XX_REG_LDO1_VOLT,
1209 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001210 .enable_time = BD71837_LDO1_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001211 .owner = THIS_MODULE,
1212 },
1213 .init = {
1214 .reg = BD718XX_REG_LDO1_VOLT,
1215 .mask = BD718XX_LDO_SEL,
1216 .val = BD718XX_LDO_SEL,
1217 },
1218 },
1219 {
1220 .desc = {
1221 .name = "ldo2",
1222 .of_match = of_match_ptr("LDO2"),
1223 .regulators_node = of_match_ptr("regulators"),
1224 .id = BD718XX_LDO2,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001225 .type = REGULATOR_VOLTAGE,
1226 .volt_table = &ldo_2_volts[0],
1227 .vsel_reg = BD718XX_REG_LDO2_VOLT,
1228 .vsel_mask = BD718XX_LDO2_MASK,
1229 .n_voltages = ARRAY_SIZE(ldo_2_volts),
1230 .enable_reg = BD718XX_REG_LDO2_VOLT,
1231 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001232 .enable_time = BD71837_LDO2_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001233 .owner = THIS_MODULE,
1234 },
1235 .init = {
1236 .reg = BD718XX_REG_LDO2_VOLT,
1237 .mask = BD718XX_LDO_SEL,
1238 .val = BD718XX_LDO_SEL,
1239 },
1240 },
1241 {
1242 .desc = {
1243 .name = "ldo3",
1244 .of_match = of_match_ptr("LDO3"),
1245 .regulators_node = of_match_ptr("regulators"),
1246 .id = BD718XX_LDO3,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001247 .type = REGULATOR_VOLTAGE,
1248 .n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
1249 .linear_ranges = bd718xx_ldo3_volts,
1250 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
1251 .vsel_reg = BD718XX_REG_LDO3_VOLT,
1252 .vsel_mask = BD718XX_LDO3_MASK,
1253 .enable_reg = BD718XX_REG_LDO3_VOLT,
1254 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001255 .enable_time = BD71837_LDO3_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001256 .owner = THIS_MODULE,
1257 },
1258 .init = {
1259 .reg = BD718XX_REG_LDO3_VOLT,
1260 .mask = BD718XX_LDO_SEL,
1261 .val = BD718XX_LDO_SEL,
1262 },
1263 },
1264 {
1265 .desc = {
1266 .name = "ldo4",
1267 .of_match = of_match_ptr("LDO4"),
1268 .regulators_node = of_match_ptr("regulators"),
1269 .id = BD718XX_LDO4,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001270 .type = REGULATOR_VOLTAGE,
1271 .n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
1272 .linear_ranges = bd718xx_ldo4_volts,
1273 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
1274 .vsel_reg = BD718XX_REG_LDO4_VOLT,
1275 .vsel_mask = BD718XX_LDO4_MASK,
1276 .enable_reg = BD718XX_REG_LDO4_VOLT,
1277 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001278 .enable_time = BD71837_LDO4_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001279 .owner = THIS_MODULE,
1280 },
1281 .init = {
1282 .reg = BD718XX_REG_LDO4_VOLT,
1283 .mask = BD718XX_LDO_SEL,
1284 .val = BD718XX_LDO_SEL,
1285 },
1286 },
1287 {
1288 .desc = {
1289 .name = "ldo5",
1290 .of_match = of_match_ptr("LDO5"),
1291 .regulators_node = of_match_ptr("regulators"),
1292 .id = BD718XX_LDO5,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001293 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001294 .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
1295 .linear_ranges = bd71837_ldo5_volts,
1296 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +03001297 /* LDO5 is supplied by buck6 */
1298 .supply_name = "buck6",
1299 .vsel_reg = BD718XX_REG_LDO5_VOLT,
1300 .vsel_mask = BD71837_LDO5_MASK,
1301 .enable_reg = BD718XX_REG_LDO5_VOLT,
1302 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001303 .enable_time = BD71837_LDO5_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001304 .owner = THIS_MODULE,
1305 },
1306 .init = {
1307 .reg = BD718XX_REG_LDO5_VOLT,
1308 .mask = BD718XX_LDO_SEL,
1309 .val = BD718XX_LDO_SEL,
1310 },
1311 .additional_inits = bd71837_ldo5_inits,
1312 .additional_init_amnt = ARRAY_SIZE(bd71837_ldo5_inits),
1313 },
1314 {
1315 .desc = {
1316 .name = "ldo6",
1317 .of_match = of_match_ptr("LDO6"),
1318 .regulators_node = of_match_ptr("regulators"),
1319 .id = BD718XX_LDO6,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001320 .type = REGULATOR_VOLTAGE,
1321 .n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
1322 .linear_ranges = bd718xx_ldo6_volts,
1323 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
1324 /* LDO6 is supplied by buck7 */
1325 .supply_name = "buck7",
1326 .vsel_reg = BD718XX_REG_LDO6_VOLT,
1327 .vsel_mask = BD718XX_LDO6_MASK,
1328 .enable_reg = BD718XX_REG_LDO6_VOLT,
1329 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001330 .enable_time = BD71837_LDO6_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001331 .owner = THIS_MODULE,
1332 },
1333 .init = {
1334 .reg = BD718XX_REG_LDO6_VOLT,
1335 .mask = BD718XX_LDO_SEL,
1336 .val = BD718XX_LDO_SEL,
1337 },
1338 .additional_inits = bd71837_ldo6_inits,
1339 .additional_init_amnt = ARRAY_SIZE(bd71837_ldo6_inits),
1340 },
1341 {
1342 .desc = {
1343 .name = "ldo7",
1344 .of_match = of_match_ptr("LDO7"),
1345 .regulators_node = of_match_ptr("regulators"),
1346 .id = BD718XX_LDO7,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001347 .type = REGULATOR_VOLTAGE,
1348 .n_voltages = BD71837_LDO7_VOLTAGE_NUM,
1349 .linear_ranges = bd71837_ldo7_volts,
1350 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts),
1351 .vsel_reg = BD71837_REG_LDO7_VOLT,
1352 .vsel_mask = BD71837_LDO7_MASK,
1353 .enable_reg = BD71837_REG_LDO7_VOLT,
1354 .enable_mask = BD718XX_LDO_EN,
Guido Günther3b66e4a2020-12-18 19:38:07 +01001355 .enable_time = BD71837_LDO7_STARTUP_TIME,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001356 .owner = THIS_MODULE,
1357 },
1358 .init = {
1359 .reg = BD71837_REG_LDO7_VOLT,
1360 .mask = BD718XX_LDO_SEL,
1361 .val = BD718XX_LDO_SEL,
1362 },
1363 },
1364};
1365
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001366static void mark_hw_controlled(struct device *dev, struct device_node *np,
1367 struct bd718xx_regulator_data *reg_data,
1368 unsigned int num_reg_data, int *info)
1369{
1370 int i;
1371
1372 for (i = 1; i <= num_reg_data; i++) {
1373 if (!of_node_name_eq(np, reg_data[i-1].desc.of_match))
1374 continue;
1375
1376 *info |= 1 << (i - 1);
1377 dev_dbg(dev, "regulator %d runlevel controlled\n", i);
1378 return;
1379 }
1380 dev_warn(dev, "Bad regulator node\n");
1381}
1382
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001383/*
1384 * Setups where regulator (especially the buck8) output voltage is scaled
1385 * by adding external connection where some other regulator output is connected
1386 * to feedback-pin (over suitable resistors) is getting popular amongst users
1387 * of BD71837. (This allows for example scaling down the buck8 voltages to suit
1388 * lover GPU voltages for projects where buck8 is (ab)used to supply power
1389 * for GPU. Additionally some setups do allow DVS for buck8 but as this do
1390 * produce voltage spikes the HW must be evaluated to be able to survive this
1391 * - hence I keep the DVS disabled for non DVS bucks by default. I don't want
1392 * to help you burn your proto board)
1393 *
1394 * So we allow describing this external connection from DT and scale the
1395 * voltages accordingly. This is what the connection should look like:
1396 *
1397 * |------------|
1398 * | buck 8 |-------+----->Vout
1399 * | | |
1400 * |------------| |
1401 * | FB pin |
1402 * | |
1403 * +-------+--R2---+
1404 * |
1405 * R1
1406 * |
1407 * V FB-pull-up
1408 *
1409 * Here the buck output is sifted according to formula:
1410 *
1411 * Vout_o = Vo - (Vpu - Vo)*R2/R1
1412 * Linear_step = step_orig*(R1+R2)/R1
1413 *
1414 * where:
1415 * Vout_o is adjusted voltage output at vsel reg value 0
1416 * Vo is original voltage output at vsel reg value 0
1417 * Vpu is the pull-up voltage V FB-pull-up in the picture
1418 * R1 and R2 are resistor values.
1419 *
1420 * As a real world example for buck8 and a specific GPU:
1421 * VLDO = 1.6V (used as FB-pull-up)
1422 * R1 = 1000ohms
1423 * R2 = 150ohms
1424 * VSEL 0x0 => 0.8V – (VLDO – 0.8) * R2 / R1 = 0.68V
1425 * Linear Step = 10mV * (R1 + R2) / R1 = 11.5mV
1426 */
1427static int setup_feedback_loop(struct device *dev, struct device_node *np,
1428 struct bd718xx_regulator_data *reg_data,
1429 unsigned int num_reg_data, int fb_uv)
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001430{
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001431 int i, r1, r2, ret;
1432
1433 /*
1434 * We do adjust the values in the global desc based on DT settings.
1435 * This may not be best approach as it can cause problems if more than
1436 * one PMIC is controlled from same processor. I don't see such use-case
1437 * for BD718x7 now - so we spare some bits.
1438 *
1439 * If this will point out to be a problem - then we can allocate new
1440 * bd718xx_regulator_data array at probe and just use the global
1441 * array as a template where we copy initial values. Then we can
1442 * use allocated descs for regultor registration and do IC specific
1443 * modifications to this copy while leaving other PMICs untouched. But
1444 * that means allocating new array for each PMIC - and currently I see
1445 * no need for that.
1446 */
1447
1448 for (i = 0; i < num_reg_data; i++) {
1449 struct regulator_desc *desc = &reg_data[i].desc;
1450 int j;
1451
1452 if (!of_node_name_eq(np, desc->of_match))
1453 continue;
1454
1455 pr_info("Looking at node '%s'\n", desc->of_match);
1456
1457 /* The feedback loop connection does not make sense for LDOs */
1458 if (desc->id >= BD718XX_LDO1)
1459 return -EINVAL;
1460
1461 ret = of_property_read_u32(np, "rohm,feedback-pull-up-r1-ohms",
1462 &r1);
1463 if (ret)
1464 return ret;
1465
1466 if (!r1)
1467 return -EINVAL;
1468
1469 ret = of_property_read_u32(np, "rohm,feedback-pull-up-r2-ohms",
1470 &r2);
1471 if (ret)
1472 return ret;
1473
1474 if (desc->n_linear_ranges && desc->linear_ranges) {
1475 struct linear_range *new;
1476
1477 new = devm_kzalloc(dev, desc->n_linear_ranges *
1478 sizeof(struct linear_range),
1479 GFP_KERNEL);
1480 if (!new)
1481 return -ENOMEM;
1482
1483 for (j = 0; j < desc->n_linear_ranges; j++) {
1484 int min = desc->linear_ranges[j].min;
1485 int step = desc->linear_ranges[j].step;
1486
1487 min -= (fb_uv - min)*r2/r1;
1488 step = step * (r1 + r2);
1489 step /= r1;
1490
1491 new[j].min = min;
1492 new[j].step = step;
1493
1494 dev_dbg(dev, "%s: old range min %d, step %d\n",
1495 desc->name, desc->linear_ranges[j].min,
1496 desc->linear_ranges[j].step);
1497 dev_dbg(dev, "new range min %d, step %d\n", min,
1498 step);
1499 }
1500 desc->linear_ranges = new;
1501 }
1502 dev_dbg(dev, "regulator '%s' has FB pull-up configured\n",
1503 desc->name);
1504
1505 return 0;
1506 }
1507
1508 return -ENODEV;
1509}
1510
1511static int get_special_regulators(struct device *dev,
1512 struct bd718xx_regulator_data *reg_data,
1513 unsigned int num_reg_data, int *info)
1514{
1515 int ret;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001516 struct device_node *np;
1517 struct device_node *nproot = dev->of_node;
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001518 int uv;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001519
1520 *info = 0;
1521
1522 nproot = of_get_child_by_name(nproot, "regulators");
1523 if (!nproot) {
1524 dev_err(dev, "failed to find regulators node\n");
1525 return -ENODEV;
1526 }
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001527 for_each_child_of_node(nproot, np) {
1528 if (of_property_read_bool(np, "rohm,no-regulator-enable-control"))
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001529 mark_hw_controlled(dev, np, reg_data, num_reg_data,
1530 info);
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001531 ret = of_property_read_u32(np, "rohm,fb-pull-up-microvolt",
1532 &uv);
1533 if (ret) {
1534 if (ret == -EINVAL)
1535 continue;
1536 else
1537 goto err_out;
1538 }
1539
1540 ret = setup_feedback_loop(dev, np, reg_data, num_reg_data, uv);
1541 if (ret)
1542 goto err_out;
1543 }
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001544
1545 of_node_put(nproot);
1546 return 0;
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001547
1548err_out:
1549 of_node_put(np);
1550 of_node_put(nproot);
1551
1552 return ret;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001553}
1554
Matti Vaittinendd2be632018-09-14 11:32:26 +03001555static int bd718xx_probe(struct platform_device *pdev)
Matti Vaittinenba087992018-05-30 11:43:43 +03001556{
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001557 struct regmap *regmap;
Matti Vaittinenba087992018-05-30 11:43:43 +03001558 struct regulator_config config = { 0 };
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001559 int i, j, err, omit_enable;
Matti Vaittinen049369d2019-02-14 11:39:36 +02001560 bool use_snvs;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001561 struct bd718xx_regulator_data *reg_data;
Axel Linb389cea2020-01-08 09:42:55 +08001562 unsigned int num_reg_data;
Matti Vaittinen1b1c26b2020-01-20 15:42:38 +02001563 enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001564 const struct regulator_ops **swops, **hwops;
Matti Vaittinenba087992018-05-30 11:43:43 +03001565
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001566 regmap = dev_get_regmap(pdev->dev.parent, NULL);
1567 if (!regmap) {
Matti Vaittinenba087992018-05-30 11:43:43 +03001568 dev_err(&pdev->dev, "No MFD driver data\n");
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001569 return -EINVAL;
Matti Vaittinenba087992018-05-30 11:43:43 +03001570 }
Axel Linbcb047e2018-10-04 15:25:58 +08001571
Linus Torvaldsaf32f3a2020-02-03 14:51:57 +00001572 switch (chip) {
Axel Linb389cea2020-01-08 09:42:55 +08001573 case ROHM_CHIP_TYPE_BD71837:
1574 reg_data = bd71837_regulators;
1575 num_reg_data = ARRAY_SIZE(bd71837_regulators);
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001576 swops = &bd71837_swcontrol_ops[0];
1577 hwops = &bd71837_hwcontrol_ops[0];
Axel Linb389cea2020-01-08 09:42:55 +08001578 break;
1579 case ROHM_CHIP_TYPE_BD71847:
1580 reg_data = bd71847_regulators;
1581 num_reg_data = ARRAY_SIZE(bd71847_regulators);
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001582 swops = &bd71847_swcontrol_ops[0];
1583 hwops = &bd71847_hwcontrol_ops[0];
Axel Linb389cea2020-01-08 09:42:55 +08001584 break;
1585 default:
Matti Vaittinen494edd22018-09-14 11:27:46 +03001586 dev_err(&pdev->dev, "Unsupported chip type\n");
1587 err = -EINVAL;
1588 goto err;
1589 }
1590
Matti Vaittinenba087992018-05-30 11:43:43 +03001591 /* Register LOCK release */
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001592 err = regmap_update_bits(regmap, BD718XX_REG_REGLOCK,
Matti Vaittinenba087992018-05-30 11:43:43 +03001593 (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
1594 if (err) {
Axel Linbcb047e2018-10-04 15:25:58 +08001595 dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err);
Matti Vaittinenba087992018-05-30 11:43:43 +03001596 goto err;
1597 } else {
Axel Linbcb047e2018-10-04 15:25:58 +08001598 dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n",
Matti Vaittinen494edd22018-09-14 11:27:46 +03001599 BD718XX_REG_REGLOCK);
Matti Vaittinenba087992018-05-30 11:43:43 +03001600 }
1601
Matti Vaittinen049369d2019-02-14 11:39:36 +02001602 use_snvs = of_property_read_bool(pdev->dev.parent->of_node,
1603 "rohm,reset-snvs-powered");
1604
1605 /*
Matti Vaittinene770b182018-11-07 15:41:26 +02001606 * Change the next stage from poweroff to be READY instead of SNVS
1607 * for all reset types because OTP loading at READY will clear SEL
1608 * bit allowing HW defaults for power rails to be used
1609 */
Matti Vaittinen049369d2019-02-14 11:39:36 +02001610 if (!use_snvs) {
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001611 err = regmap_update_bits(regmap, BD718XX_REG_TRANS_COND1,
Matti Vaittinen049369d2019-02-14 11:39:36 +02001612 BD718XX_ON_REQ_POWEROFF_MASK |
1613 BD718XX_SWRESET_POWEROFF_MASK |
1614 BD718XX_WDOG_POWEROFF_MASK |
1615 BD718XX_KEY_L_POWEROFF_MASK,
1616 BD718XX_POWOFF_TO_RDY);
1617 if (err) {
1618 dev_err(&pdev->dev, "Failed to change reset target\n");
1619 goto err;
1620 } else {
1621 dev_dbg(&pdev->dev,
1622 "Changed all resets from SVNS to READY\n");
1623 }
Matti Vaittinene770b182018-11-07 15:41:26 +02001624 }
1625
Matti Vaittinendf9db252020-09-03 21:38:19 +03001626 config.dev = pdev->dev.parent;
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001627 config.regmap = regmap;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001628 /*
1629 * There are cases when we want to leave the enable-control for
1630 * the HW state machine and use this driver only for voltage control.
1631 * One special case is when we use PMIC_STBY_REQ line from SoC to PMIC
1632 * in order to set the system to SUSPEND state.
1633 *
1634 * If regulator is taken under SW control the regulator state will not
1635 * be affected by PMIC state machine - Eg. regulator is likely to stay
1636 * on even in SUSPEND
1637 */
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001638 err = get_special_regulators(pdev->dev.parent, reg_data, num_reg_data,
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001639 &omit_enable);
Matti Vaittinend2ad9812020-11-10 10:20:17 +02001640 if (err)
1641 return err;
Matti Vaittinendf9db252020-09-03 21:38:19 +03001642
Axel Linb389cea2020-01-08 09:42:55 +08001643 for (i = 0; i < num_reg_data; i++) {
Matti Vaittinen823f18f2018-08-29 15:36:10 +03001644
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001645 struct regulator_desc *desc;
Matti Vaittinenba087992018-05-30 11:43:43 +03001646 struct regulator_dev *rdev;
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001647 struct bd718xx_regulator_data *r;
1648 int no_enable_control = omit_enable & (1 << i);
Matti Vaittinenba087992018-05-30 11:43:43 +03001649
Axel Linb389cea2020-01-08 09:42:55 +08001650 r = &reg_data[i];
Matti Vaittinen494edd22018-09-14 11:27:46 +03001651 desc = &r->desc;
Matti Vaittinenba087992018-05-30 11:43:43 +03001652
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001653 if (no_enable_control)
1654 desc->ops = hwops[i];
1655 else
1656 desc->ops = swops[i];
Matti Vaittinenba087992018-05-30 11:43:43 +03001657
1658 rdev = devm_regulator_register(&pdev->dev, desc, &config);
1659 if (IS_ERR(rdev)) {
Axel Linbcb047e2018-10-04 15:25:58 +08001660 dev_err(&pdev->dev,
Matti Vaittinenba087992018-05-30 11:43:43 +03001661 "failed to register %s regulator\n",
1662 desc->name);
1663 err = PTR_ERR(rdev);
1664 goto err;
1665 }
Matti Vaittinen049369d2019-02-14 11:39:36 +02001666
1667 /*
1668 * Regulator register gets the regulator constraints and
Matti Vaittinenba087992018-05-30 11:43:43 +03001669 * applies them (set_machine_constraints). This should have
1670 * turned the control register(s) to correct values and we
1671 * can now switch the control from PMIC state machine to the
1672 * register interface
Matti Vaittinen049369d2019-02-14 11:39:36 +02001673 *
1674 * At poweroff transition PMIC HW disables EN bit for
1675 * regulators but leaves SEL bit untouched. So if state
1676 * transition from POWEROFF is done to SNVS - then all power
1677 * rails controlled by SW (having SEL bit set) stay disabled
1678 * as EN is cleared. This will result boot failure if any
1679 * crucial systems are powered by these rails. We don't
1680 * enable SW control for crucial regulators if snvs state is
1681 * used
Matti Vaittinenba087992018-05-30 11:43:43 +03001682 */
Matti Vaittinen1d848d62020-09-03 21:39:02 +03001683 if (!no_enable_control && (!use_snvs ||
1684 !rdev->constraints->always_on ||
1685 !rdev->constraints->boot_on)) {
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001686 err = regmap_update_bits(regmap, r->init.reg,
Matti Vaittinen049369d2019-02-14 11:39:36 +02001687 r->init.mask, r->init.val);
1688 if (err) {
1689 dev_err(&pdev->dev,
1690 "Failed to take control for (%s)\n",
1691 desc->name);
1692 goto err;
1693 }
Matti Vaittinenba087992018-05-30 11:43:43 +03001694 }
Matti Vaittinen494edd22018-09-14 11:27:46 +03001695 for (j = 0; j < r->additional_init_amnt; j++) {
Matti Vaittinen907dfdc2021-01-07 14:23:55 +02001696 err = regmap_update_bits(regmap,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001697 r->additional_inits[j].reg,
1698 r->additional_inits[j].mask,
1699 r->additional_inits[j].val);
1700 if (err) {
Axel Linbcb047e2018-10-04 15:25:58 +08001701 dev_err(&pdev->dev,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001702 "Buck (%s) initialization failed\n",
1703 desc->name);
1704 goto err;
1705 }
1706 }
Matti Vaittinenba087992018-05-30 11:43:43 +03001707 }
1708
Matti Vaittinenba087992018-05-30 11:43:43 +03001709err:
1710 return err;
1711}
1712
Matti Vaittinen1b1c26b2020-01-20 15:42:38 +02001713static const struct platform_device_id bd718x7_pmic_id[] = {
1714 { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 },
1715 { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 },
1716 { },
1717};
1718MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id);
1719
Matti Vaittinendd2be632018-09-14 11:32:26 +03001720static struct platform_driver bd718xx_regulator = {
Matti Vaittinenba087992018-05-30 11:43:43 +03001721 .driver = {
Matti Vaittinen494edd22018-09-14 11:27:46 +03001722 .name = "bd718xx-pmic",
Matti Vaittinenba087992018-05-30 11:43:43 +03001723 },
Matti Vaittinendd2be632018-09-14 11:32:26 +03001724 .probe = bd718xx_probe,
Matti Vaittinen1b1c26b2020-01-20 15:42:38 +02001725 .id_table = bd718x7_pmic_id,
Matti Vaittinenba087992018-05-30 11:43:43 +03001726};
1727
Matti Vaittinendd2be632018-09-14 11:32:26 +03001728module_platform_driver(bd718xx_regulator);
Matti Vaittinenba087992018-05-30 11:43:43 +03001729
1730MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
Matti Vaittinendd2be632018-09-14 11:32:26 +03001731MODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver");
Matti Vaittinenba087992018-05-30 11:43:43 +03001732MODULE_LICENSE("GPL");
Guido Günther95bddd82019-09-30 22:26:00 +02001733MODULE_ALIAS("platform:bd718xx-pmic");