blob: 7b311389f925418c00919a58e9fe49259e057f66 [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
Matti Vaittinenba087992018-05-30 11:43:43 +030018/*
19 * BUCK1/2/3/4
20 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting
21 * 00: 10.00mV/usec 10mV 1uS
22 * 01: 5.00mV/usec 10mV 2uS
23 * 10: 2.50mV/usec 10mV 4uS
24 * 11: 1.25mV/usec 10mV 8uS
25 */
Matti Vaittinendd2be632018-09-14 11:32:26 +030026static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
Matti Vaittinenba087992018-05-30 11:43:43 +030027 int ramp_delay)
28{
Axel Lin0a245f02019-04-07 17:03:02 +080029 int id = rdev_get_id(rdev);
30 unsigned int ramp_value;
Matti Vaittinenba087992018-05-30 11:43:43 +030031
Axel Linbcb047e2018-10-04 15:25:58 +080032 dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1,
Matti Vaittinenba087992018-05-30 11:43:43 +030033 ramp_delay);
34 switch (ramp_delay) {
35 case 1 ... 1250:
36 ramp_value = BUCK_RAMPRATE_1P25MV;
37 break;
38 case 1251 ... 2500:
39 ramp_value = BUCK_RAMPRATE_2P50MV;
40 break;
41 case 2501 ... 5000:
42 ramp_value = BUCK_RAMPRATE_5P00MV;
43 break;
44 case 5001 ... 10000:
45 ramp_value = BUCK_RAMPRATE_10P00MV;
46 break;
47 default:
48 ramp_value = BUCK_RAMPRATE_10P00MV;
Axel Linbcb047e2018-10-04 15:25:58 +080049 dev_err(&rdev->dev,
Matti Vaittinenba087992018-05-30 11:43:43 +030050 "%s: ramp_delay: %d not supported, setting 10000mV//us\n",
51 rdev->desc->name, ramp_delay);
52 }
53
Axel Linbcb047e2018-10-04 15:25:58 +080054 return regmap_update_bits(rdev->regmap, BD718XX_REG_BUCK1_CTRL + id,
Matti Vaittinenba087992018-05-30 11:43:43 +030055 BUCK_RAMPRATE_MASK, ramp_value << 6);
56}
57
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +030058/*
59 * On BD71837 (not on BD71847, BD71850, ...)
60 * Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed.
Matti Vaittinenba087992018-05-30 11:43:43 +030061 * Bucks 5 to 8 and LDOs can use PFM and must be disabled when voltage
62 * is changed. Hence we return -EBUSY for these if voltage is changed
63 * when BUCK/LDO is enabled.
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +030064 *
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +030065 * On BD71847, BD71850, ... The LDO voltage can be changed when LDO is
66 * enabled. But if voltage is increased the LDO power-good monitoring
67 * must be disabled for the duration of changing + 1mS to ensure voltage
68 * has reached the higher level before HW does next under voltage detection
69 * cycle.
Matti Vaittinenba087992018-05-30 11:43:43 +030070 */
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +030071static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
Matti Vaittinenba087992018-05-30 11:43:43 +030072 unsigned int sel)
73{
Axel Linffdc4982018-06-27 20:40:14 +080074 if (regulator_is_enabled_regmap(rdev))
75 return -EBUSY;
Matti Vaittinenba087992018-05-30 11:43:43 +030076
Axel Linffdc4982018-06-27 20:40:14 +080077 return regulator_set_voltage_sel_regmap(rdev, sel);
Matti Vaittinenba087992018-05-30 11:43:43 +030078}
79
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +030080static void voltage_change_done(struct regulator_dev *rdev, unsigned int sel,
81 unsigned int *mask)
82{
83 int ret;
84
85 if (*mask) {
86 /*
87 * Let's allow scheduling as we use I2C anyways. We just need to
88 * guarantee minimum of 1ms sleep - it shouldn't matter if we
89 * exceed it due to the scheduling.
90 */
91 msleep(1);
92 /*
93 * Note for next hacker. The PWRGOOD should not be masked on
94 * BD71847 so we will just unconditionally enable detection
95 * when voltage is set.
96 * If someone want's to disable PWRGOOD he must implement
97 * caching and restoring the old value here. I am not
98 * aware of such use-cases so for the sake of the simplicity
99 * we just always enable PWRGOOD here.
100 */
101 ret = regmap_update_bits(rdev->regmap, BD718XX_REG_MVRFLTMASK2,
102 *mask, 0);
103 if (ret)
104 dev_err(&rdev->dev,
105 "Failed to re-enable voltage monitoring (%d)\n",
106 ret);
107 }
108}
109
110static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel,
111 unsigned int *mask)
112{
113 int ret;
114
115 *mask = 0;
116 if (regulator_is_enabled_regmap(rdev)) {
117 int now, new;
118
119 now = rdev->desc->ops->get_voltage_sel(rdev);
120 if (now < 0)
121 return now;
122
123 now = rdev->desc->ops->list_voltage(rdev, now);
124 if (now < 0)
125 return now;
126
127 new = rdev->desc->ops->list_voltage(rdev, sel);
128 if (new < 0)
129 return new;
130
131 /*
132 * If we increase LDO voltage when LDO is enabled we need to
133 * disable the power-good detection until voltage has reached
134 * the new level. According to HW colleagues the maximum time
135 * it takes is 1000us. I assume that on systems with light load
136 * this might be less - and we could probably use DT to give
137 * system specific delay value if performance matters.
138 *
139 * Well, knowing we use I2C here and can add scheduling delays
140 * I don't think it is worth the hassle and I just add fixed
141 * 1ms sleep here (and allow scheduling). If this turns out to
142 * be a problem we can change it to delay and make the delay
143 * time configurable.
144 */
145 if (new > now) {
146 int ldo_offset = rdev->desc->id - BD718XX_LDO1;
147
148 *mask = BD718XX_LDO1_VRMON80 << ldo_offset;
149 ret = regmap_update_bits(rdev->regmap,
150 BD718XX_REG_MVRFLTMASK2,
151 *mask, *mask);
152 if (ret) {
153 dev_err(&rdev->dev,
154 "Failed to stop voltage monitoring\n");
155 return ret;
156 }
157 }
158 }
159
160 return 0;
161}
162
163static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
164 unsigned int sel)
165{
166 int ret;
167 int mask;
168
169 ret = voltage_change_prepare(rdev, sel, &mask);
170 if (ret)
171 return ret;
172
173 ret = regulator_set_voltage_sel_regmap(rdev, sel);
174 voltage_change_done(rdev, sel, &mask);
175
176 return ret;
177}
178
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300179static int bd718xx_set_voltage_sel_pickable_restricted(
180 struct regulator_dev *rdev, unsigned int sel)
181{
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300182 int ret;
183 int mask;
184
185 ret = voltage_change_prepare(rdev, sel, &mask);
186 if (ret)
187 return ret;
188
189 ret = regulator_set_voltage_sel_pickable_regmap(rdev, sel);
190 voltage_change_done(rdev, sel, &mask);
191
192 return ret;
193}
194
195static int bd71837_set_voltage_sel_pickable_restricted(
196 struct regulator_dev *rdev, unsigned int sel)
197{
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300198 if (regulator_is_enabled_regmap(rdev))
199 return -EBUSY;
200
201 return regulator_set_voltage_sel_pickable_regmap(rdev, sel);
202}
203
Axel Lin704c5c02019-01-24 18:02:08 +0800204static const struct regulator_ops bd718xx_pickable_range_ldo_ops = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300205 .enable = regulator_enable_regmap,
206 .disable = regulator_disable_regmap,
207 .is_enabled = regulator_is_enabled_regmap,
208 .list_voltage = regulator_list_voltage_pickable_linear_range,
209 .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
210 .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300211
212};
213
214static const struct regulator_ops bd71837_pickable_range_ldo_ops = {
215 .enable = regulator_enable_regmap,
216 .disable = regulator_disable_regmap,
217 .is_enabled = regulator_is_enabled_regmap,
218 .list_voltage = regulator_list_voltage_pickable_linear_range,
219 .set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted,
220 .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300221};
222
Axel Lin704c5c02019-01-24 18:02:08 +0800223static const struct regulator_ops bd718xx_pickable_range_buck_ops = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300224 .enable = regulator_enable_regmap,
225 .disable = regulator_disable_regmap,
226 .is_enabled = regulator_is_enabled_regmap,
227 .list_voltage = regulator_list_voltage_pickable_linear_range,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300228 .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap,
229 .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
230 .set_voltage_time_sel = regulator_set_voltage_time_sel,
231};
232
233static const struct regulator_ops bd71837_pickable_range_buck_ops = {
234 .enable = regulator_enable_regmap,
235 .disable = regulator_disable_regmap,
236 .is_enabled = regulator_is_enabled_regmap,
237 .list_voltage = regulator_list_voltage_pickable_linear_range,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300238 .set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300239 .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
240 .set_voltage_time_sel = regulator_set_voltage_time_sel,
241};
242
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300243static const struct regulator_ops bd71837_ldo_regulator_ops = {
244 .enable = regulator_enable_regmap,
245 .disable = regulator_disable_regmap,
246 .is_enabled = regulator_is_enabled_regmap,
247 .list_voltage = regulator_list_voltage_linear_range,
248 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
249 .get_voltage_sel = regulator_get_voltage_sel_regmap,
250};
251
Axel Lin704c5c02019-01-24 18:02:08 +0800252static const struct regulator_ops bd718xx_ldo_regulator_ops = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300253 .enable = regulator_enable_regmap,
254 .disable = regulator_disable_regmap,
255 .is_enabled = regulator_is_enabled_regmap,
256 .list_voltage = regulator_list_voltage_linear_range,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300257 .set_voltage_sel = bd718xx_set_voltage_sel_restricted,
Matti Vaittinenba087992018-05-30 11:43:43 +0300258 .get_voltage_sel = regulator_get_voltage_sel_regmap,
259};
260
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300261static const struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
262 .enable = regulator_enable_regmap,
263 .disable = regulator_disable_regmap,
264 .is_enabled = regulator_is_enabled_regmap,
265 .list_voltage = regulator_list_voltage_table,
266 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
267 .get_voltage_sel = regulator_get_voltage_sel_regmap,
268};
269
Axel Lin704c5c02019-01-24 18:02:08 +0800270static const struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300271 .enable = regulator_enable_regmap,
272 .disable = regulator_disable_regmap,
273 .is_enabled = regulator_is_enabled_regmap,
274 .list_voltage = regulator_list_voltage_table,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300275 .set_voltage_sel = bd718xx_set_voltage_sel_restricted,
Matti Vaittinenba087992018-05-30 11:43:43 +0300276 .get_voltage_sel = regulator_get_voltage_sel_regmap,
277};
278
Axel Lin704c5c02019-01-24 18:02:08 +0800279static const struct regulator_ops bd718xx_buck_regulator_ops = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300280 .enable = regulator_enable_regmap,
281 .disable = regulator_disable_regmap,
282 .is_enabled = regulator_is_enabled_regmap,
283 .list_voltage = regulator_list_voltage_linear_range,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300284 .set_voltage_sel = regulator_set_voltage_sel_regmap,
285 .get_voltage_sel = regulator_get_voltage_sel_regmap,
286 .set_voltage_time_sel = regulator_set_voltage_time_sel,
287};
288
289static const struct regulator_ops bd71837_buck_regulator_ops = {
290 .enable = regulator_enable_regmap,
291 .disable = regulator_disable_regmap,
292 .is_enabled = regulator_is_enabled_regmap,
293 .list_voltage = regulator_list_voltage_linear_range,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +0300294 .set_voltage_sel = bd71837_set_voltage_sel_restricted,
Matti Vaittinenba087992018-05-30 11:43:43 +0300295 .get_voltage_sel = regulator_get_voltage_sel_regmap,
296 .set_voltage_time_sel = regulator_set_voltage_time_sel,
297};
298
Axel Lin704c5c02019-01-24 18:02:08 +0800299static const struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300300 .enable = regulator_enable_regmap,
301 .disable = regulator_disable_regmap,
302 .is_enabled = regulator_is_enabled_regmap,
303 .list_voltage = regulator_list_voltage_table,
Axel Lin2e612862018-11-10 11:50:03 +0800304 .map_voltage = regulator_map_voltage_ascend,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300305 .set_voltage_sel = regulator_set_voltage_sel_regmap,
306 .get_voltage_sel = regulator_get_voltage_sel_regmap,
307 .set_voltage_time_sel = regulator_set_voltage_time_sel,
308};
309
310static const struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
311 .enable = regulator_enable_regmap,
312 .disable = regulator_disable_regmap,
313 .is_enabled = regulator_is_enabled_regmap,
314 .list_voltage = regulator_list_voltage_table,
315 .map_voltage = regulator_map_voltage_ascend,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300316 .set_voltage_sel = bd718xx_set_voltage_sel_restricted,
Matti Vaittinenba087992018-05-30 11:43:43 +0300317 .get_voltage_sel = regulator_get_voltage_sel_regmap,
318 .set_voltage_time_sel = regulator_set_voltage_time_sel,
319};
320
Axel Lin704c5c02019-01-24 18:02:08 +0800321static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300322 .enable = regulator_enable_regmap,
323 .disable = regulator_disable_regmap,
324 .is_enabled = regulator_is_enabled_regmap,
325 .list_voltage = regulator_list_voltage_linear_range,
326 .set_voltage_sel = regulator_set_voltage_sel_regmap,
327 .get_voltage_sel = regulator_get_voltage_sel_regmap,
328 .set_voltage_time_sel = regulator_set_voltage_time_sel,
Matti Vaittinendd2be632018-09-14 11:32:26 +0300329 .set_ramp_delay = bd718xx_buck1234_set_ramp_delay,
Matti Vaittinenba087992018-05-30 11:43:43 +0300330};
331
332/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300333 * BD71837 BUCK1/2/3/4
334 * BD71847 BUCK1/2
Matti Vaittinenba087992018-05-30 11:43:43 +0300335 * 0.70 to 1.30V (10mV step)
336 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300337static const struct linear_range bd718xx_dvs_buck_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300338 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
339 REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
340};
341
342/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300343 * BD71837 BUCK5
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300344 * 0.7V to 1.35V (range 0)
345 * and
346 * 0.675 to 1.325 (range 1)
Matti Vaittinenba087992018-05-30 11:43:43 +0300347 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300348static const struct linear_range bd71837_buck5_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300349 /* Ranges when VOLT_SEL bit is 0 */
Matti Vaittinenba087992018-05-30 11:43:43 +0300350 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
351 REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
352 REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300353 /* Ranges when VOLT_SEL bit is 1 */
354 REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
355 REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
356 REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300357};
358
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300359/*
360 * Range selector for first 3 linear ranges is 0x0
361 * and 0x1 for last 3 ranges.
362 */
363static const unsigned int bd71837_buck5_volt_range_sel[] = {
364 0x0, 0x0, 0x0, 0x80, 0x80, 0x80
Matti Vaittinen494edd22018-09-14 11:27:46 +0300365};
366
Matti Vaittinenba087992018-05-30 11:43:43 +0300367/*
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300368 * BD71847 BUCK3
369 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300370static const struct linear_range bd71847_buck3_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300371 /* Ranges when VOLT_SEL bits are 00 */
372 REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
373 REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
374 REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
375 /* Ranges when VOLT_SEL bits are 01 */
376 REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000),
377 /* Ranges when VOLT_SEL bits are 11 */
378 REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
379 REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
380 REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
381};
382
383static const unsigned int bd71847_buck3_volt_range_sel[] = {
384 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
385};
386
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300387static const struct linear_range bd71847_buck4_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300388 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
389 REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
390};
391
392static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
393
394/*
Matti Vaittinenba087992018-05-30 11:43:43 +0300395 * BUCK6
396 * 3.0V to 3.3V (step 100mV)
397 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300398static const struct linear_range bd71837_buck6_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300399 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
400};
401
402/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300403 * BD71837 BUCK7
404 * BD71847 BUCK5
Matti Vaittinenba087992018-05-30 11:43:43 +0300405 * 000 = 1.605V
406 * 001 = 1.695V
407 * 010 = 1.755V
408 * 011 = 1.8V (Initial)
409 * 100 = 1.845V
410 * 101 = 1.905V
411 * 110 = 1.95V
412 * 111 = 1.995V
413 */
Matti Vaittinen494edd22018-09-14 11:27:46 +0300414static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300415 1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
416};
417
418/*
419 * BUCK8
420 * 0.8V to 1.40V (step 10mV)
421 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300422static const struct linear_range bd718xx_4th_nodvs_buck_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300423 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300424};
425
426/*
427 * LDO1
428 * 3.0 to 3.3V (100mV step)
429 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300430static const struct linear_range bd718xx_ldo1_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300431 REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300432 REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300433};
434
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300435static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 };
436
Matti Vaittinenba087992018-05-30 11:43:43 +0300437/*
438 * LDO2
439 * 0.8 or 0.9V
440 */
Axel Linadb78a82018-06-27 20:40:13 +0800441static const unsigned int ldo_2_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300442 900000, 800000
443};
444
445/*
446 * LDO3
447 * 1.8 to 3.3V (100mV step)
448 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300449static const struct linear_range bd718xx_ldo3_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300450 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
451};
452
453/*
454 * LDO4
455 * 0.9 to 1.8V (100mV step)
456 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300457static const struct linear_range bd718xx_ldo4_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300458 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300459};
460
461/*
Matti Vaittinen494edd22018-09-14 11:27:46 +0300462 * LDO5 for BD71837
Matti Vaittinenba087992018-05-30 11:43:43 +0300463 * 1.8 to 3.3V (100mV step)
464 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300465static const struct linear_range bd71837_ldo5_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300466 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
467};
468
469/*
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300470 * LDO5 for BD71837
471 * 1.8 to 3.3V (100mV step)
472 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300473static const struct linear_range bd71847_ldo5_volts[] = {
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300474 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
475 REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
476};
477
478static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
479
480/*
Matti Vaittinenba087992018-05-30 11:43:43 +0300481 * LDO6
482 * 0.9 to 1.8V (100mV step)
483 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300484static const struct linear_range bd718xx_ldo6_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300485 REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
Matti Vaittinenba087992018-05-30 11:43:43 +0300486};
487
488/*
489 * LDO7
490 * 1.8 to 3.3V (100mV step)
491 */
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300492static const struct linear_range bd71837_ldo7_volts[] = {
Matti Vaittinenba087992018-05-30 11:43:43 +0300493 REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
494};
495
Matti Vaittinenba087992018-05-30 11:43:43 +0300496struct reg_init {
497 unsigned int reg;
498 unsigned int mask;
Matti Vaittinen494edd22018-09-14 11:27:46 +0300499 unsigned int val;
500};
501struct bd718xx_regulator_data {
502 struct regulator_desc desc;
Matti Vaittinen21b72152020-01-20 15:44:45 +0200503 const struct rohm_dvs_config dvs;
Matti Vaittinen494edd22018-09-14 11:27:46 +0300504 const struct reg_init init;
505 const struct reg_init *additional_inits;
506 int additional_init_amnt;
507};
508
509/*
510 * There is a HW quirk in BD71837. The shutdown sequence timings for
511 * bucks/LDOs which are controlled via register interface are changed.
512 * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
513 * beginning of shut-down sequence. As bucks 6 and 7 are parent
514 * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
515 * monitoring to errorneously detect under voltage and force PMIC to
516 * emergency state instead of poweroff. In order to avoid this we
517 * disable voltage monitoring for LDO5 and LDO6
518 */
519static const struct reg_init bd71837_ldo5_inits[] = {
520 {
521 .reg = BD718XX_REG_MVRFLTMASK2,
522 .mask = BD718XX_LDO5_VRMON80,
523 .val = BD718XX_LDO5_VRMON80,
524 },
525};
526
527static const struct reg_init bd71837_ldo6_inits[] = {
528 {
529 .reg = BD718XX_REG_MVRFLTMASK2,
530 .mask = BD718XX_LDO6_VRMON80,
531 .val = BD718XX_LDO6_VRMON80,
532 },
533};
534
Matti Vaittinen21b72152020-01-20 15:44:45 +0200535static int buck_set_hw_dvs_levels(struct device_node *np,
Matti Vaittinen049369d2019-02-14 11:39:36 +0200536 const struct regulator_desc *desc,
537 struct regulator_config *cfg)
538{
Matti Vaittinen21b72152020-01-20 15:44:45 +0200539 struct bd718xx_regulator_data *data;
Matti Vaittinen049369d2019-02-14 11:39:36 +0200540
Matti Vaittinen21b72152020-01-20 15:44:45 +0200541 data = container_of(desc, struct bd718xx_regulator_data, desc);
Matti Vaittinen049369d2019-02-14 11:39:36 +0200542
Matti Vaittinen21b72152020-01-20 15:44:45 +0200543 return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
Matti Vaittinen049369d2019-02-14 11:39:36 +0200544}
545
Matti Vaittinen494edd22018-09-14 11:27:46 +0300546static const struct bd718xx_regulator_data bd71847_regulators[] = {
547 {
548 .desc = {
549 .name = "buck1",
550 .of_match = of_match_ptr("BUCK1"),
551 .regulators_node = of_match_ptr("regulators"),
552 .id = BD718XX_BUCK1,
553 .ops = &bd718xx_dvs_buck_regulator_ops,
554 .type = REGULATOR_VOLTAGE,
555 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
556 .linear_ranges = bd718xx_dvs_buck_volts,
557 .n_linear_ranges =
558 ARRAY_SIZE(bd718xx_dvs_buck_volts),
559 .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
560 .vsel_mask = DVS_BUCK_RUN_MASK,
561 .enable_reg = BD718XX_REG_BUCK1_CTRL,
562 .enable_mask = BD718XX_BUCK_EN,
563 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200564 .of_parse_cb = buck_set_hw_dvs_levels,
565 },
566 .dvs = {
567 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
568 ROHM_DVS_LEVEL_SUSPEND,
569 .run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
570 .run_mask = DVS_BUCK_RUN_MASK,
571 .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
572 .idle_mask = DVS_BUCK_RUN_MASK,
573 .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
574 .suspend_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300575 },
576 .init = {
577 .reg = BD718XX_REG_BUCK1_CTRL,
578 .mask = BD718XX_BUCK_SEL,
579 .val = BD718XX_BUCK_SEL,
580 },
581 },
582 {
583 .desc = {
584 .name = "buck2",
585 .of_match = of_match_ptr("BUCK2"),
586 .regulators_node = of_match_ptr("regulators"),
587 .id = BD718XX_BUCK2,
588 .ops = &bd718xx_dvs_buck_regulator_ops,
589 .type = REGULATOR_VOLTAGE,
590 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
591 .linear_ranges = bd718xx_dvs_buck_volts,
592 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
593 .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
594 .vsel_mask = DVS_BUCK_RUN_MASK,
595 .enable_reg = BD718XX_REG_BUCK2_CTRL,
596 .enable_mask = BD718XX_BUCK_EN,
597 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200598 .of_parse_cb = buck_set_hw_dvs_levels,
599 },
600 .dvs = {
601 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
602 .run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
603 .run_mask = DVS_BUCK_RUN_MASK,
604 .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
605 .idle_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300606 },
607 .init = {
608 .reg = BD718XX_REG_BUCK2_CTRL,
609 .mask = BD718XX_BUCK_SEL,
610 .val = BD718XX_BUCK_SEL,
611 },
612 },
613 {
614 .desc = {
615 .name = "buck3",
616 .of_match = of_match_ptr("BUCK3"),
617 .regulators_node = of_match_ptr("regulators"),
618 .id = BD718XX_BUCK3,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300619 .ops = &bd718xx_pickable_range_buck_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300620 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300621 .n_voltages = BD71847_BUCK3_VOLTAGE_NUM,
622 .linear_ranges = bd71847_buck3_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300623 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300624 ARRAY_SIZE(bd71847_buck3_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300625 .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
626 .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300627 .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
628 .vsel_range_mask = BD71847_BUCK3_RANGE_MASK,
629 .linear_range_selectors = bd71847_buck3_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300630 .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
631 .enable_mask = BD718XX_BUCK_EN,
632 .owner = THIS_MODULE,
633 },
634 .init = {
635 .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
636 .mask = BD718XX_BUCK_SEL,
637 .val = BD718XX_BUCK_SEL,
638 },
639 },
640 {
641 .desc = {
642 .name = "buck4",
643 .of_match = of_match_ptr("BUCK4"),
644 .regulators_node = of_match_ptr("regulators"),
645 .id = BD718XX_BUCK4,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300646 .ops = &bd718xx_pickable_range_buck_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300647 .type = REGULATOR_VOLTAGE,
648 .n_voltages = BD71847_BUCK4_VOLTAGE_NUM,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300649 .linear_ranges = bd71847_buck4_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300650 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300651 ARRAY_SIZE(bd71847_buck4_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300652 .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
653 .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
654 .vsel_mask = BD71847_BUCK4_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300655 .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
656 .vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
657 .linear_range_selectors = bd71847_buck4_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300658 .enable_mask = BD718XX_BUCK_EN,
659 .owner = THIS_MODULE,
660 },
661 .init = {
662 .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
663 .mask = BD718XX_BUCK_SEL,
664 .val = BD718XX_BUCK_SEL,
665 },
666 },
667 {
668 .desc = {
669 .name = "buck5",
670 .of_match = of_match_ptr("BUCK5"),
Matti Vaittinendd2be632018-09-14 11:32:26 +0300671 .regulators_node = of_match_ptr("regulators"),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300672 .id = BD718XX_BUCK5,
673 .ops = &bd718xx_buck_regulator_nolinear_ops,
674 .type = REGULATOR_VOLTAGE,
675 .volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
676 .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
677 .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
678 .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
679 .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
680 .enable_mask = BD718XX_BUCK_EN,
681 .owner = THIS_MODULE,
682 },
683 .init = {
684 .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
685 .mask = BD718XX_BUCK_SEL,
686 .val = BD718XX_BUCK_SEL,
687 },
688 },
689 {
690 .desc = {
691 .name = "buck6",
692 .of_match = of_match_ptr("BUCK6"),
693 .regulators_node = of_match_ptr("regulators"),
694 .id = BD718XX_BUCK6,
695 .ops = &bd718xx_buck_regulator_ops,
696 .type = REGULATOR_VOLTAGE,
Matti Vaittinendd2be632018-09-14 11:32:26 +0300697 .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300698 .linear_ranges = bd718xx_4th_nodvs_buck_volts,
699 .n_linear_ranges =
700 ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
701 .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
702 .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
703 .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
704 .enable_mask = BD718XX_BUCK_EN,
705 .owner = THIS_MODULE,
706 },
707 .init = {
708 .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
709 .mask = BD718XX_BUCK_SEL,
710 .val = BD718XX_BUCK_SEL,
711 },
712 },
713 {
714 .desc = {
715 .name = "ldo1",
716 .of_match = of_match_ptr("LDO1"),
717 .regulators_node = of_match_ptr("regulators"),
718 .id = BD718XX_LDO1,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300719 .ops = &bd718xx_pickable_range_ldo_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300720 .type = REGULATOR_VOLTAGE,
721 .n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
722 .linear_ranges = bd718xx_ldo1_volts,
723 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
724 .vsel_reg = BD718XX_REG_LDO1_VOLT,
725 .vsel_mask = BD718XX_LDO1_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300726 .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
727 .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
728 .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300729 .enable_reg = BD718XX_REG_LDO1_VOLT,
730 .enable_mask = BD718XX_LDO_EN,
731 .owner = THIS_MODULE,
732 },
733 .init = {
734 .reg = BD718XX_REG_LDO1_VOLT,
735 .mask = BD718XX_LDO_SEL,
736 .val = BD718XX_LDO_SEL,
737 },
738 },
739 {
740 .desc = {
741 .name = "ldo2",
742 .of_match = of_match_ptr("LDO2"),
743 .regulators_node = of_match_ptr("regulators"),
744 .id = BD718XX_LDO2,
745 .ops = &bd718xx_ldo_regulator_nolinear_ops,
746 .type = REGULATOR_VOLTAGE,
747 .volt_table = &ldo_2_volts[0],
748 .vsel_reg = BD718XX_REG_LDO2_VOLT,
749 .vsel_mask = BD718XX_LDO2_MASK,
750 .n_voltages = ARRAY_SIZE(ldo_2_volts),
751 .enable_reg = BD718XX_REG_LDO2_VOLT,
752 .enable_mask = BD718XX_LDO_EN,
753 .owner = THIS_MODULE,
754 },
755 .init = {
756 .reg = BD718XX_REG_LDO2_VOLT,
757 .mask = BD718XX_LDO_SEL,
758 .val = BD718XX_LDO_SEL,
759 },
760 },
761 {
762 .desc = {
763 .name = "ldo3",
764 .of_match = of_match_ptr("LDO3"),
765 .regulators_node = of_match_ptr("regulators"),
766 .id = BD718XX_LDO3,
767 .ops = &bd718xx_ldo_regulator_ops,
768 .type = REGULATOR_VOLTAGE,
769 .n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
770 .linear_ranges = bd718xx_ldo3_volts,
771 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
772 .vsel_reg = BD718XX_REG_LDO3_VOLT,
773 .vsel_mask = BD718XX_LDO3_MASK,
774 .enable_reg = BD718XX_REG_LDO3_VOLT,
775 .enable_mask = BD718XX_LDO_EN,
776 .owner = THIS_MODULE,
777 },
778 .init = {
779 .reg = BD718XX_REG_LDO3_VOLT,
780 .mask = BD718XX_LDO_SEL,
781 .val = BD718XX_LDO_SEL,
782 },
783 },
784 {
785 .desc = {
786 .name = "ldo4",
787 .of_match = of_match_ptr("LDO4"),
788 .regulators_node = of_match_ptr("regulators"),
789 .id = BD718XX_LDO4,
790 .ops = &bd718xx_ldo_regulator_ops,
791 .type = REGULATOR_VOLTAGE,
792 .n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
793 .linear_ranges = bd718xx_ldo4_volts,
794 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
795 .vsel_reg = BD718XX_REG_LDO4_VOLT,
796 .vsel_mask = BD718XX_LDO4_MASK,
797 .enable_reg = BD718XX_REG_LDO4_VOLT,
798 .enable_mask = BD718XX_LDO_EN,
799 .owner = THIS_MODULE,
800 },
801 .init = {
802 .reg = BD718XX_REG_LDO4_VOLT,
803 .mask = BD718XX_LDO_SEL,
804 .val = BD718XX_LDO_SEL,
805 },
806 },
807 {
808 .desc = {
809 .name = "ldo5",
810 .of_match = of_match_ptr("LDO5"),
811 .regulators_node = of_match_ptr("regulators"),
812 .id = BD718XX_LDO5,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300813 .ops = &bd718xx_pickable_range_ldo_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300814 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300815 .n_voltages = BD71847_LDO5_VOLTAGE_NUM,
816 .linear_ranges = bd71847_ldo5_volts,
817 .n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300818 .vsel_reg = BD718XX_REG_LDO5_VOLT,
819 .vsel_mask = BD71847_LDO5_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300820 .vsel_range_reg = BD718XX_REG_LDO5_VOLT,
821 .vsel_range_mask = BD71847_LDO5_RANGE_MASK,
822 .linear_range_selectors = bd71847_ldo5_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300823 .enable_reg = BD718XX_REG_LDO5_VOLT,
824 .enable_mask = BD718XX_LDO_EN,
825 .owner = THIS_MODULE,
826 },
827 .init = {
828 .reg = BD718XX_REG_LDO5_VOLT,
829 .mask = BD718XX_LDO_SEL,
830 .val = BD718XX_LDO_SEL,
831 },
832 },
833 {
834 .desc = {
835 .name = "ldo6",
836 .of_match = of_match_ptr("LDO6"),
837 .regulators_node = of_match_ptr("regulators"),
838 .id = BD718XX_LDO6,
839 .ops = &bd718xx_ldo_regulator_ops,
840 .type = REGULATOR_VOLTAGE,
841 .n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
842 .linear_ranges = bd718xx_ldo6_volts,
843 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
844 /* LDO6 is supplied by buck5 */
845 .supply_name = "buck5",
846 .vsel_reg = BD718XX_REG_LDO6_VOLT,
847 .vsel_mask = BD718XX_LDO6_MASK,
848 .enable_reg = BD718XX_REG_LDO6_VOLT,
849 .enable_mask = BD718XX_LDO_EN,
850 .owner = THIS_MODULE,
851 },
852 .init = {
853 .reg = BD718XX_REG_LDO6_VOLT,
854 .mask = BD718XX_LDO_SEL,
855 .val = BD718XX_LDO_SEL,
856 },
857 },
858};
859
860static const struct bd718xx_regulator_data bd71837_regulators[] = {
861 {
862 .desc = {
863 .name = "buck1",
864 .of_match = of_match_ptr("BUCK1"),
865 .regulators_node = of_match_ptr("regulators"),
866 .id = BD718XX_BUCK1,
867 .ops = &bd718xx_dvs_buck_regulator_ops,
868 .type = REGULATOR_VOLTAGE,
869 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
870 .linear_ranges = bd718xx_dvs_buck_volts,
871 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
872 .vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
873 .vsel_mask = DVS_BUCK_RUN_MASK,
874 .enable_reg = BD718XX_REG_BUCK1_CTRL,
875 .enable_mask = BD718XX_BUCK_EN,
876 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200877 .of_parse_cb = buck_set_hw_dvs_levels,
878 },
879 .dvs = {
880 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
881 ROHM_DVS_LEVEL_SUSPEND,
882 .run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
883 .run_mask = DVS_BUCK_RUN_MASK,
884 .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
885 .idle_mask = DVS_BUCK_RUN_MASK,
886 .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
887 .suspend_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300888 },
889 .init = {
890 .reg = BD718XX_REG_BUCK1_CTRL,
891 .mask = BD718XX_BUCK_SEL,
892 .val = BD718XX_BUCK_SEL,
893 },
894 },
895 {
896 .desc = {
897 .name = "buck2",
898 .of_match = of_match_ptr("BUCK2"),
899 .regulators_node = of_match_ptr("regulators"),
900 .id = BD718XX_BUCK2,
901 .ops = &bd718xx_dvs_buck_regulator_ops,
902 .type = REGULATOR_VOLTAGE,
903 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
904 .linear_ranges = bd718xx_dvs_buck_volts,
905 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
906 .vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
907 .vsel_mask = DVS_BUCK_RUN_MASK,
908 .enable_reg = BD718XX_REG_BUCK2_CTRL,
909 .enable_mask = BD718XX_BUCK_EN,
910 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200911 .of_parse_cb = buck_set_hw_dvs_levels,
912 },
913 .dvs = {
914 .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
915 .run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
916 .run_mask = DVS_BUCK_RUN_MASK,
917 .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
918 .idle_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300919 },
920 .init = {
921 .reg = BD718XX_REG_BUCK2_CTRL,
922 .mask = BD718XX_BUCK_SEL,
923 .val = BD718XX_BUCK_SEL,
924 },
925 },
926 {
927 .desc = {
928 .name = "buck3",
929 .of_match = of_match_ptr("BUCK3"),
930 .regulators_node = of_match_ptr("regulators"),
931 .id = BD718XX_BUCK3,
932 .ops = &bd718xx_dvs_buck_regulator_ops,
933 .type = REGULATOR_VOLTAGE,
934 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
935 .linear_ranges = bd718xx_dvs_buck_volts,
936 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
937 .vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
938 .vsel_mask = DVS_BUCK_RUN_MASK,
939 .enable_reg = BD71837_REG_BUCK3_CTRL,
940 .enable_mask = BD718XX_BUCK_EN,
941 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200942 .of_parse_cb = buck_set_hw_dvs_levels,
943 },
944 .dvs = {
945 .level_map = ROHM_DVS_LEVEL_RUN,
946 .run_reg = BD71837_REG_BUCK3_VOLT_RUN,
947 .run_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300948 },
949 .init = {
950 .reg = BD71837_REG_BUCK3_CTRL,
951 .mask = BD718XX_BUCK_SEL,
952 .val = BD718XX_BUCK_SEL,
953 },
954 },
955 {
956 .desc = {
957 .name = "buck4",
958 .of_match = of_match_ptr("BUCK4"),
959 .regulators_node = of_match_ptr("regulators"),
960 .id = BD718XX_BUCK4,
961 .ops = &bd718xx_dvs_buck_regulator_ops,
962 .type = REGULATOR_VOLTAGE,
963 .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
964 .linear_ranges = bd718xx_dvs_buck_volts,
965 .n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
966 .vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
967 .vsel_mask = DVS_BUCK_RUN_MASK,
968 .enable_reg = BD71837_REG_BUCK4_CTRL,
969 .enable_mask = BD718XX_BUCK_EN,
970 .owner = THIS_MODULE,
Matti Vaittinen21b72152020-01-20 15:44:45 +0200971 .of_parse_cb = buck_set_hw_dvs_levels,
972 },
973 .dvs = {
974 .level_map = ROHM_DVS_LEVEL_RUN,
975 .run_reg = BD71837_REG_BUCK4_VOLT_RUN,
976 .run_mask = DVS_BUCK_RUN_MASK,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300977 },
978 .init = {
979 .reg = BD71837_REG_BUCK4_CTRL,
980 .mask = BD718XX_BUCK_SEL,
981 .val = BD718XX_BUCK_SEL,
982 },
983 },
984 {
985 .desc = {
986 .name = "buck5",
987 .of_match = of_match_ptr("BUCK5"),
988 .regulators_node = of_match_ptr("regulators"),
989 .id = BD718XX_BUCK5,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +0300990 .ops = &bd71837_pickable_range_buck_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300991 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300992 .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
993 .linear_ranges = bd71837_buck5_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +0300994 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300995 ARRAY_SIZE(bd71837_buck5_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +0300996 .vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +0300997 .vsel_mask = BD71837_BUCK5_MASK,
998 .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
999 .vsel_range_mask = BD71837_BUCK5_RANGE_MASK,
1000 .linear_range_selectors = bd71837_buck5_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001001 .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
1002 .enable_mask = BD718XX_BUCK_EN,
1003 .owner = THIS_MODULE,
1004 },
1005 .init = {
1006 .reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
1007 .mask = BD718XX_BUCK_SEL,
1008 .val = BD718XX_BUCK_SEL,
1009 },
1010 },
1011 {
1012 .desc = {
1013 .name = "buck6",
1014 .of_match = of_match_ptr("BUCK6"),
1015 .regulators_node = of_match_ptr("regulators"),
1016 .id = BD718XX_BUCK6,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +03001017 .ops = &bd71837_buck_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001018 .type = REGULATOR_VOLTAGE,
1019 .n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001020 .linear_ranges = bd71837_buck6_volts,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001021 .n_linear_ranges =
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001022 ARRAY_SIZE(bd71837_buck6_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +03001023 .vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
1024 .vsel_mask = BD71837_BUCK6_MASK,
1025 .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
1026 .enable_mask = BD718XX_BUCK_EN,
1027 .owner = THIS_MODULE,
1028 },
1029 .init = {
1030 .reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
1031 .mask = BD718XX_BUCK_SEL,
1032 .val = BD718XX_BUCK_SEL,
1033 },
1034 },
1035 {
1036 .desc = {
1037 .name = "buck7",
1038 .of_match = of_match_ptr("BUCK7"),
1039 .regulators_node = of_match_ptr("regulators"),
1040 .id = BD718XX_BUCK7,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +03001041 .ops = &bd71837_buck_regulator_nolinear_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001042 .type = REGULATOR_VOLTAGE,
1043 .volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
1044 .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
1045 .vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
1046 .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
1047 .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
1048 .enable_mask = BD718XX_BUCK_EN,
1049 .owner = THIS_MODULE,
1050 },
1051 .init = {
1052 .reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
1053 .mask = BD718XX_BUCK_SEL,
1054 .val = BD718XX_BUCK_SEL,
1055 },
1056 },
1057 {
1058 .desc = {
1059 .name = "buck8",
1060 .of_match = of_match_ptr("BUCK8"),
1061 .regulators_node = of_match_ptr("regulators"),
1062 .id = BD718XX_BUCK8,
Matti Vaittinenf0ca7b22020-04-28 12:29:30 +03001063 .ops = &bd71837_buck_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001064 .type = REGULATOR_VOLTAGE,
Matti Vaittinendd2be632018-09-14 11:32:26 +03001065 .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001066 .linear_ranges = bd718xx_4th_nodvs_buck_volts,
1067 .n_linear_ranges =
1068 ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
1069 .vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
1070 .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
1071 .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
1072 .enable_mask = BD718XX_BUCK_EN,
1073 .owner = THIS_MODULE,
1074 },
1075 .init = {
1076 .reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
1077 .mask = BD718XX_BUCK_SEL,
1078 .val = BD718XX_BUCK_SEL,
1079 },
1080 },
1081 {
1082 .desc = {
1083 .name = "ldo1",
1084 .of_match = of_match_ptr("LDO1"),
1085 .regulators_node = of_match_ptr("regulators"),
1086 .id = BD718XX_LDO1,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001087 .ops = &bd71837_pickable_range_ldo_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001088 .type = REGULATOR_VOLTAGE,
1089 .n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
1090 .linear_ranges = bd718xx_ldo1_volts,
1091 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
1092 .vsel_reg = BD718XX_REG_LDO1_VOLT,
1093 .vsel_mask = BD718XX_LDO1_MASK,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001094 .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
1095 .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
1096 .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001097 .enable_reg = BD718XX_REG_LDO1_VOLT,
1098 .enable_mask = BD718XX_LDO_EN,
1099 .owner = THIS_MODULE,
1100 },
1101 .init = {
1102 .reg = BD718XX_REG_LDO1_VOLT,
1103 .mask = BD718XX_LDO_SEL,
1104 .val = BD718XX_LDO_SEL,
1105 },
1106 },
1107 {
1108 .desc = {
1109 .name = "ldo2",
1110 .of_match = of_match_ptr("LDO2"),
1111 .regulators_node = of_match_ptr("regulators"),
1112 .id = BD718XX_LDO2,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001113 .ops = &bd71837_ldo_regulator_nolinear_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001114 .type = REGULATOR_VOLTAGE,
1115 .volt_table = &ldo_2_volts[0],
1116 .vsel_reg = BD718XX_REG_LDO2_VOLT,
1117 .vsel_mask = BD718XX_LDO2_MASK,
1118 .n_voltages = ARRAY_SIZE(ldo_2_volts),
1119 .enable_reg = BD718XX_REG_LDO2_VOLT,
1120 .enable_mask = BD718XX_LDO_EN,
1121 .owner = THIS_MODULE,
1122 },
1123 .init = {
1124 .reg = BD718XX_REG_LDO2_VOLT,
1125 .mask = BD718XX_LDO_SEL,
1126 .val = BD718XX_LDO_SEL,
1127 },
1128 },
1129 {
1130 .desc = {
1131 .name = "ldo3",
1132 .of_match = of_match_ptr("LDO3"),
1133 .regulators_node = of_match_ptr("regulators"),
1134 .id = BD718XX_LDO3,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001135 .ops = &bd71837_ldo_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001136 .type = REGULATOR_VOLTAGE,
1137 .n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
1138 .linear_ranges = bd718xx_ldo3_volts,
1139 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
1140 .vsel_reg = BD718XX_REG_LDO3_VOLT,
1141 .vsel_mask = BD718XX_LDO3_MASK,
1142 .enable_reg = BD718XX_REG_LDO3_VOLT,
1143 .enable_mask = BD718XX_LDO_EN,
1144 .owner = THIS_MODULE,
1145 },
1146 .init = {
1147 .reg = BD718XX_REG_LDO3_VOLT,
1148 .mask = BD718XX_LDO_SEL,
1149 .val = BD718XX_LDO_SEL,
1150 },
1151 },
1152 {
1153 .desc = {
1154 .name = "ldo4",
1155 .of_match = of_match_ptr("LDO4"),
1156 .regulators_node = of_match_ptr("regulators"),
1157 .id = BD718XX_LDO4,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001158 .ops = &bd71837_ldo_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001159 .type = REGULATOR_VOLTAGE,
1160 .n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
1161 .linear_ranges = bd718xx_ldo4_volts,
1162 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
1163 .vsel_reg = BD718XX_REG_LDO4_VOLT,
1164 .vsel_mask = BD718XX_LDO4_MASK,
1165 .enable_reg = BD718XX_REG_LDO4_VOLT,
1166 .enable_mask = BD718XX_LDO_EN,
1167 .owner = THIS_MODULE,
1168 },
1169 .init = {
1170 .reg = BD718XX_REG_LDO4_VOLT,
1171 .mask = BD718XX_LDO_SEL,
1172 .val = BD718XX_LDO_SEL,
1173 },
1174 },
1175 {
1176 .desc = {
1177 .name = "ldo5",
1178 .of_match = of_match_ptr("LDO5"),
1179 .regulators_node = of_match_ptr("regulators"),
1180 .id = BD718XX_LDO5,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001181 .ops = &bd71837_ldo_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001182 .type = REGULATOR_VOLTAGE,
Matti Vaittinena4bfc2c2018-09-14 11:33:11 +03001183 .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
1184 .linear_ranges = bd71837_ldo5_volts,
1185 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts),
Matti Vaittinen494edd22018-09-14 11:27:46 +03001186 /* LDO5 is supplied by buck6 */
1187 .supply_name = "buck6",
1188 .vsel_reg = BD718XX_REG_LDO5_VOLT,
1189 .vsel_mask = BD71837_LDO5_MASK,
1190 .enable_reg = BD718XX_REG_LDO5_VOLT,
1191 .enable_mask = BD718XX_LDO_EN,
1192 .owner = THIS_MODULE,
1193 },
1194 .init = {
1195 .reg = BD718XX_REG_LDO5_VOLT,
1196 .mask = BD718XX_LDO_SEL,
1197 .val = BD718XX_LDO_SEL,
1198 },
1199 .additional_inits = bd71837_ldo5_inits,
1200 .additional_init_amnt = ARRAY_SIZE(bd71837_ldo5_inits),
1201 },
1202 {
1203 .desc = {
1204 .name = "ldo6",
1205 .of_match = of_match_ptr("LDO6"),
1206 .regulators_node = of_match_ptr("regulators"),
1207 .id = BD718XX_LDO6,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001208 .ops = &bd71837_ldo_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001209 .type = REGULATOR_VOLTAGE,
1210 .n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
1211 .linear_ranges = bd718xx_ldo6_volts,
1212 .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
1213 /* LDO6 is supplied by buck7 */
1214 .supply_name = "buck7",
1215 .vsel_reg = BD718XX_REG_LDO6_VOLT,
1216 .vsel_mask = BD718XX_LDO6_MASK,
1217 .enable_reg = BD718XX_REG_LDO6_VOLT,
1218 .enable_mask = BD718XX_LDO_EN,
1219 .owner = THIS_MODULE,
1220 },
1221 .init = {
1222 .reg = BD718XX_REG_LDO6_VOLT,
1223 .mask = BD718XX_LDO_SEL,
1224 .val = BD718XX_LDO_SEL,
1225 },
1226 .additional_inits = bd71837_ldo6_inits,
1227 .additional_init_amnt = ARRAY_SIZE(bd71837_ldo6_inits),
1228 },
1229 {
1230 .desc = {
1231 .name = "ldo7",
1232 .of_match = of_match_ptr("LDO7"),
1233 .regulators_node = of_match_ptr("regulators"),
1234 .id = BD718XX_LDO7,
Matti Vaittinen9bcbaba2020-05-13 17:39:21 +03001235 .ops = &bd71837_ldo_regulator_ops,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001236 .type = REGULATOR_VOLTAGE,
1237 .n_voltages = BD71837_LDO7_VOLTAGE_NUM,
1238 .linear_ranges = bd71837_ldo7_volts,
1239 .n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts),
1240 .vsel_reg = BD71837_REG_LDO7_VOLT,
1241 .vsel_mask = BD71837_LDO7_MASK,
1242 .enable_reg = BD71837_REG_LDO7_VOLT,
1243 .enable_mask = BD718XX_LDO_EN,
1244 .owner = THIS_MODULE,
1245 },
1246 .init = {
1247 .reg = BD71837_REG_LDO7_VOLT,
1248 .mask = BD718XX_LDO_SEL,
1249 .val = BD718XX_LDO_SEL,
1250 },
1251 },
1252};
1253
Matti Vaittinendd2be632018-09-14 11:32:26 +03001254static int bd718xx_probe(struct platform_device *pdev)
Matti Vaittinenba087992018-05-30 11:43:43 +03001255{
Axel Linbcb047e2018-10-04 15:25:58 +08001256 struct bd718xx *mfd;
Matti Vaittinenba087992018-05-30 11:43:43 +03001257 struct regulator_config config = { 0 };
Matti Vaittinen494edd22018-09-14 11:27:46 +03001258 int i, j, err;
Matti Vaittinen049369d2019-02-14 11:39:36 +02001259 bool use_snvs;
Axel Linb389cea2020-01-08 09:42:55 +08001260 const struct bd718xx_regulator_data *reg_data;
1261 unsigned int num_reg_data;
Matti Vaittinen1b1c26b2020-01-20 15:42:38 +02001262 enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
Matti Vaittinenba087992018-05-30 11:43:43 +03001263
Axel Linbcb047e2018-10-04 15:25:58 +08001264 mfd = dev_get_drvdata(pdev->dev.parent);
1265 if (!mfd) {
Matti Vaittinenba087992018-05-30 11:43:43 +03001266 dev_err(&pdev->dev, "No MFD driver data\n");
1267 err = -EINVAL;
1268 goto err;
1269 }
Axel Linbcb047e2018-10-04 15:25:58 +08001270
Linus Torvaldsaf32f3a2020-02-03 14:51:57 +00001271 switch (chip) {
Axel Linb389cea2020-01-08 09:42:55 +08001272 case ROHM_CHIP_TYPE_BD71837:
1273 reg_data = bd71837_regulators;
1274 num_reg_data = ARRAY_SIZE(bd71837_regulators);
1275 break;
1276 case ROHM_CHIP_TYPE_BD71847:
1277 reg_data = bd71847_regulators;
1278 num_reg_data = ARRAY_SIZE(bd71847_regulators);
1279 break;
1280 default:
Matti Vaittinen494edd22018-09-14 11:27:46 +03001281 dev_err(&pdev->dev, "Unsupported chip type\n");
1282 err = -EINVAL;
1283 goto err;
1284 }
1285
Matti Vaittinenba087992018-05-30 11:43:43 +03001286 /* Register LOCK release */
Matti Vaittinen2a6a7aa2019-06-03 10:24:32 +03001287 err = regmap_update_bits(mfd->chip.regmap, BD718XX_REG_REGLOCK,
Matti Vaittinenba087992018-05-30 11:43:43 +03001288 (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
1289 if (err) {
Axel Linbcb047e2018-10-04 15:25:58 +08001290 dev_err(&pdev->dev, "Failed to unlock PMIC (%d)\n", err);
Matti Vaittinenba087992018-05-30 11:43:43 +03001291 goto err;
1292 } else {
Axel Linbcb047e2018-10-04 15:25:58 +08001293 dev_dbg(&pdev->dev, "Unlocked lock register 0x%x\n",
Matti Vaittinen494edd22018-09-14 11:27:46 +03001294 BD718XX_REG_REGLOCK);
Matti Vaittinenba087992018-05-30 11:43:43 +03001295 }
1296
Matti Vaittinen049369d2019-02-14 11:39:36 +02001297 use_snvs = of_property_read_bool(pdev->dev.parent->of_node,
1298 "rohm,reset-snvs-powered");
1299
1300 /*
Matti Vaittinene770b182018-11-07 15:41:26 +02001301 * Change the next stage from poweroff to be READY instead of SNVS
1302 * for all reset types because OTP loading at READY will clear SEL
1303 * bit allowing HW defaults for power rails to be used
1304 */
Matti Vaittinen049369d2019-02-14 11:39:36 +02001305 if (!use_snvs) {
Matti Vaittinen2a6a7aa2019-06-03 10:24:32 +03001306 err = regmap_update_bits(mfd->chip.regmap,
1307 BD718XX_REG_TRANS_COND1,
Matti Vaittinen049369d2019-02-14 11:39:36 +02001308 BD718XX_ON_REQ_POWEROFF_MASK |
1309 BD718XX_SWRESET_POWEROFF_MASK |
1310 BD718XX_WDOG_POWEROFF_MASK |
1311 BD718XX_KEY_L_POWEROFF_MASK,
1312 BD718XX_POWOFF_TO_RDY);
1313 if (err) {
1314 dev_err(&pdev->dev, "Failed to change reset target\n");
1315 goto err;
1316 } else {
1317 dev_dbg(&pdev->dev,
1318 "Changed all resets from SVNS to READY\n");
1319 }
Matti Vaittinene770b182018-11-07 15:41:26 +02001320 }
1321
Axel Linb389cea2020-01-08 09:42:55 +08001322 for (i = 0; i < num_reg_data; i++) {
Matti Vaittinen823f18f2018-08-29 15:36:10 +03001323
Matti Vaittinen494edd22018-09-14 11:27:46 +03001324 const struct regulator_desc *desc;
Matti Vaittinenba087992018-05-30 11:43:43 +03001325 struct regulator_dev *rdev;
Matti Vaittinen494edd22018-09-14 11:27:46 +03001326 const struct bd718xx_regulator_data *r;
Matti Vaittinenba087992018-05-30 11:43:43 +03001327
Axel Linb389cea2020-01-08 09:42:55 +08001328 r = &reg_data[i];
Matti Vaittinen494edd22018-09-14 11:27:46 +03001329 desc = &r->desc;
Matti Vaittinenba087992018-05-30 11:43:43 +03001330
Matti Vaittinenba087992018-05-30 11:43:43 +03001331 config.dev = pdev->dev.parent;
Matti Vaittinen2a6a7aa2019-06-03 10:24:32 +03001332 config.regmap = mfd->chip.regmap;
Matti Vaittinenba087992018-05-30 11:43:43 +03001333
1334 rdev = devm_regulator_register(&pdev->dev, desc, &config);
1335 if (IS_ERR(rdev)) {
Axel Linbcb047e2018-10-04 15:25:58 +08001336 dev_err(&pdev->dev,
Matti Vaittinenba087992018-05-30 11:43:43 +03001337 "failed to register %s regulator\n",
1338 desc->name);
1339 err = PTR_ERR(rdev);
1340 goto err;
1341 }
Matti Vaittinen049369d2019-02-14 11:39:36 +02001342
1343 /*
1344 * Regulator register gets the regulator constraints and
Matti Vaittinenba087992018-05-30 11:43:43 +03001345 * applies them (set_machine_constraints). This should have
1346 * turned the control register(s) to correct values and we
1347 * can now switch the control from PMIC state machine to the
1348 * register interface
Matti Vaittinen049369d2019-02-14 11:39:36 +02001349 *
1350 * At poweroff transition PMIC HW disables EN bit for
1351 * regulators but leaves SEL bit untouched. So if state
1352 * transition from POWEROFF is done to SNVS - then all power
1353 * rails controlled by SW (having SEL bit set) stay disabled
1354 * as EN is cleared. This will result boot failure if any
1355 * crucial systems are powered by these rails. We don't
1356 * enable SW control for crucial regulators if snvs state is
1357 * used
Matti Vaittinenba087992018-05-30 11:43:43 +03001358 */
Matti Vaittinen049369d2019-02-14 11:39:36 +02001359 if (!use_snvs || !rdev->constraints->always_on ||
1360 !rdev->constraints->boot_on) {
Matti Vaittinen2a6a7aa2019-06-03 10:24:32 +03001361 err = regmap_update_bits(mfd->chip.regmap, r->init.reg,
Matti Vaittinen049369d2019-02-14 11:39:36 +02001362 r->init.mask, r->init.val);
1363 if (err) {
1364 dev_err(&pdev->dev,
1365 "Failed to take control for (%s)\n",
1366 desc->name);
1367 goto err;
1368 }
Matti Vaittinenba087992018-05-30 11:43:43 +03001369 }
Matti Vaittinen494edd22018-09-14 11:27:46 +03001370 for (j = 0; j < r->additional_init_amnt; j++) {
Matti Vaittinen2a6a7aa2019-06-03 10:24:32 +03001371 err = regmap_update_bits(mfd->chip.regmap,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001372 r->additional_inits[j].reg,
1373 r->additional_inits[j].mask,
1374 r->additional_inits[j].val);
1375 if (err) {
Axel Linbcb047e2018-10-04 15:25:58 +08001376 dev_err(&pdev->dev,
Matti Vaittinen494edd22018-09-14 11:27:46 +03001377 "Buck (%s) initialization failed\n",
1378 desc->name);
1379 goto err;
1380 }
1381 }
Matti Vaittinenba087992018-05-30 11:43:43 +03001382 }
1383
Matti Vaittinenba087992018-05-30 11:43:43 +03001384err:
1385 return err;
1386}
1387
Matti Vaittinen1b1c26b2020-01-20 15:42:38 +02001388static const struct platform_device_id bd718x7_pmic_id[] = {
1389 { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 },
1390 { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 },
1391 { },
1392};
1393MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id);
1394
Matti Vaittinendd2be632018-09-14 11:32:26 +03001395static struct platform_driver bd718xx_regulator = {
Matti Vaittinenba087992018-05-30 11:43:43 +03001396 .driver = {
Matti Vaittinen494edd22018-09-14 11:27:46 +03001397 .name = "bd718xx-pmic",
Matti Vaittinenba087992018-05-30 11:43:43 +03001398 },
Matti Vaittinendd2be632018-09-14 11:32:26 +03001399 .probe = bd718xx_probe,
Matti Vaittinen1b1c26b2020-01-20 15:42:38 +02001400 .id_table = bd718x7_pmic_id,
Matti Vaittinenba087992018-05-30 11:43:43 +03001401};
1402
Matti Vaittinendd2be632018-09-14 11:32:26 +03001403module_platform_driver(bd718xx_regulator);
Matti Vaittinenba087992018-05-30 11:43:43 +03001404
1405MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
Matti Vaittinendd2be632018-09-14 11:32:26 +03001406MODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver");
Matti Vaittinenba087992018-05-30 11:43:43 +03001407MODULE_LICENSE("GPL");
Guido Günther95bddd82019-09-30 22:26:00 +02001408MODULE_ALIAS("platform:bd718xx-pmic");