vfio/mdev: Remove mdev_parent_ops
[linux-block.git] / drivers / regulator / stpmic1_regulator.c
CommitLineData
ca55b718 1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) STMicroelectronics 2018
3// Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
4
5#include <linux/interrupt.h>
6#include <linux/mfd/stpmic1.h>
7#include <linux/module.h>
8#include <linux/of_irq.h>
9#include <linux/platform_device.h>
10#include <linux/regmap.h>
11#include <linux/regulator/driver.h>
12#include <linux/regulator/machine.h>
13#include <linux/regulator/of_regulator.h>
14
b9058da8
PPL
15#include <dt-bindings/mfd/st,stpmic1.h>
16
ca55b718 17/**
ec84a7df 18 * struct stpmic1 regulator description: this structure is used as driver data
ca55b718 19 * @desc: regulator framework description
20 * @mask_reset_reg: mask reset register address
21 * @mask_reset_mask: mask rank and mask reset register mask
22 * @icc_reg: icc register address
23 * @icc_mask: icc register mask
24 */
25struct stpmic1_regulator_cfg {
26 struct regulator_desc desc;
27 u8 mask_reset_reg;
28 u8 mask_reset_mask;
29 u8 icc_reg;
30 u8 icc_mask;
31};
32
ca55b718 33static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode);
34static unsigned int stpmic1_get_mode(struct regulator_dev *rdev);
89a6a5e5
MV
35static int stpmic1_set_icc(struct regulator_dev *rdev, int lim, int severity,
36 bool enable);
ca55b718 37static unsigned int stpmic1_map_mode(unsigned int mode);
38
39enum {
40 STPMIC1_BUCK1 = 0,
41 STPMIC1_BUCK2 = 1,
42 STPMIC1_BUCK3 = 2,
43 STPMIC1_BUCK4 = 3,
44 STPMIC1_LDO1 = 4,
45 STPMIC1_LDO2 = 5,
46 STPMIC1_LDO3 = 6,
47 STPMIC1_LDO4 = 7,
48 STPMIC1_LDO5 = 8,
49 STPMIC1_LDO6 = 9,
50 STPMIC1_VREF_DDR = 10,
51 STPMIC1_BOOST = 11,
52 STPMIC1_VBUS_OTG = 12,
53 STPMIC1_SW_OUT = 13,
54};
55
56/* Enable time worst case is 5000mV/(2250uV/uS) */
57#define PMIC_ENABLE_TIME_US 2200
9ebde17c
PP
58/* Ramp delay worst case is (2250uV/uS) */
59#define PMIC_RAMP_DELAY 2200
ca55b718 60
60ab7f41 61static const struct linear_range buck1_ranges[] = {
48593a99
PPL
62 REGULATOR_LINEAR_RANGE(725000, 0, 4, 0),
63 REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000),
64 REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0),
ca55b718 65};
66
60ab7f41 67static const struct linear_range buck2_ranges[] = {
ca55b718 68 REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0),
69 REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0),
70 REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0),
71 REGULATOR_LINEAR_RANGE(1150000, 22, 23, 0),
72 REGULATOR_LINEAR_RANGE(1200000, 24, 25, 0),
73 REGULATOR_LINEAR_RANGE(1250000, 26, 27, 0),
74 REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
75 REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
76 REGULATOR_LINEAR_RANGE(1400000, 32, 33, 0),
77 REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
78 REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0),
79};
80
60ab7f41 81static const struct linear_range buck3_ranges[] = {
ca55b718 82 REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0),
83 REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0),
84 REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0),
85 REGULATOR_LINEAR_RANGE(1300000, 28, 31, 0),
86 REGULATOR_LINEAR_RANGE(1400000, 32, 35, 0),
87 REGULATOR_LINEAR_RANGE(1500000, 36, 55, 100000),
88 REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0),
ca55b718 89};
90
60ab7f41 91static const struct linear_range buck4_ranges[] = {
ca55b718 92 REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000),
93 REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
94 REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
95 REGULATOR_LINEAR_RANGE(1400000, 32, 33, 0),
96 REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
97 REGULATOR_LINEAR_RANGE(1500000, 36, 60, 100000),
98 REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0),
ca55b718 99};
100
60ab7f41 101static const struct linear_range ldo1_ranges[] = {
ca55b718 102 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
103 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
104 REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
ca55b718 105};
106
60ab7f41 107static const struct linear_range ldo2_ranges[] = {
ca55b718 108 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
109 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
110 REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
ca55b718 111};
112
60ab7f41 113static const struct linear_range ldo3_ranges[] = {
ca55b718 114 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
115 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
116 REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
117 /* with index 31 LDO3 is in DDR mode */
118 REGULATOR_LINEAR_RANGE(500000, 31, 31, 0),
119};
120
60ab7f41 121static const struct linear_range ldo5_ranges[] = {
ca55b718 122 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
123 REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000),
124 REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0),
125};
126
60ab7f41 127static const struct linear_range ldo6_ranges[] = {
ca55b718 128 REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000),
129 REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
130};
131
7c027c66 132static const struct regulator_ops stpmic1_ldo_ops = {
ca55b718 133 .list_voltage = regulator_list_voltage_linear_range,
134 .map_voltage = regulator_map_voltage_linear_range,
135 .is_enabled = regulator_is_enabled_regmap,
136 .enable = regulator_enable_regmap,
137 .disable = regulator_disable_regmap,
138 .get_voltage_sel = regulator_get_voltage_sel_regmap,
139 .set_voltage_sel = regulator_set_voltage_sel_regmap,
ca55b718 140 .set_over_current_protection = stpmic1_set_icc,
141};
142
7c027c66 143static const struct regulator_ops stpmic1_ldo3_ops = {
ca55b718 144 .list_voltage = regulator_list_voltage_linear_range,
145 .map_voltage = regulator_map_voltage_iterate,
146 .is_enabled = regulator_is_enabled_regmap,
147 .enable = regulator_enable_regmap,
148 .disable = regulator_disable_regmap,
149 .get_voltage_sel = regulator_get_voltage_sel_regmap,
150 .set_voltage_sel = regulator_set_voltage_sel_regmap,
ca55b718 151 .get_bypass = regulator_get_bypass_regmap,
152 .set_bypass = regulator_set_bypass_regmap,
153 .set_over_current_protection = stpmic1_set_icc,
154};
155
7c027c66 156static const struct regulator_ops stpmic1_ldo4_fixed_regul_ops = {
ca55b718 157 .is_enabled = regulator_is_enabled_regmap,
158 .enable = regulator_enable_regmap,
159 .disable = regulator_disable_regmap,
ca55b718 160 .set_over_current_protection = stpmic1_set_icc,
161};
162
7c027c66 163static const struct regulator_ops stpmic1_buck_ops = {
ca55b718 164 .list_voltage = regulator_list_voltage_linear_range,
165 .map_voltage = regulator_map_voltage_linear_range,
166 .is_enabled = regulator_is_enabled_regmap,
167 .enable = regulator_enable_regmap,
168 .disable = regulator_disable_regmap,
169 .get_voltage_sel = regulator_get_voltage_sel_regmap,
170 .set_voltage_sel = regulator_set_voltage_sel_regmap,
171 .set_pull_down = regulator_set_pull_down_regmap,
172 .set_mode = stpmic1_set_mode,
173 .get_mode = stpmic1_get_mode,
174 .set_over_current_protection = stpmic1_set_icc,
175};
176
7c027c66 177static const struct regulator_ops stpmic1_vref_ddr_ops = {
ca55b718 178 .is_enabled = regulator_is_enabled_regmap,
179 .enable = regulator_enable_regmap,
180 .disable = regulator_disable_regmap,
ca55b718 181};
182
e6fff62a
PPL
183static const struct regulator_ops stpmic1_boost_regul_ops = {
184 .is_enabled = regulator_is_enabled_regmap,
185 .enable = regulator_enable_regmap,
186 .disable = regulator_disable_regmap,
187 .set_over_current_protection = stpmic1_set_icc,
188};
189
7c027c66 190static const struct regulator_ops stpmic1_switch_regul_ops = {
ca55b718 191 .is_enabled = regulator_is_enabled_regmap,
192 .enable = regulator_enable_regmap,
193 .disable = regulator_disable_regmap,
194 .set_over_current_protection = stpmic1_set_icc,
e6fff62a 195 .set_active_discharge = regulator_set_active_discharge_regmap,
ca55b718 196};
197
198#define REG_LDO(ids, base) { \
199 .name = #ids, \
200 .id = STPMIC1_##ids, \
201 .n_voltages = 32, \
202 .ops = &stpmic1_ldo_ops, \
203 .linear_ranges = base ## _ranges, \
204 .n_linear_ranges = ARRAY_SIZE(base ## _ranges), \
205 .type = REGULATOR_VOLTAGE, \
206 .owner = THIS_MODULE, \
207 .vsel_reg = ids##_ACTIVE_CR, \
208 .vsel_mask = LDO_VOLTAGE_MASK, \
209 .enable_reg = ids##_ACTIVE_CR, \
210 .enable_mask = LDO_ENABLE_MASK, \
211 .enable_val = 1, \
212 .disable_val = 0, \
213 .enable_time = PMIC_ENABLE_TIME_US, \
9ebde17c 214 .ramp_delay = PMIC_RAMP_DELAY, \
ca55b718 215 .supply_name = #base, \
216}
217
218#define REG_LDO3(ids, base) { \
219 .name = #ids, \
220 .id = STPMIC1_##ids, \
221 .n_voltages = 32, \
222 .ops = &stpmic1_ldo3_ops, \
223 .linear_ranges = ldo3_ranges, \
224 .n_linear_ranges = ARRAY_SIZE(ldo3_ranges), \
225 .type = REGULATOR_VOLTAGE, \
226 .owner = THIS_MODULE, \
227 .vsel_reg = LDO3_ACTIVE_CR, \
228 .vsel_mask = LDO_VOLTAGE_MASK, \
229 .enable_reg = LDO3_ACTIVE_CR, \
230 .enable_mask = LDO_ENABLE_MASK, \
231 .enable_val = 1, \
232 .disable_val = 0, \
233 .enable_time = PMIC_ENABLE_TIME_US, \
9ebde17c 234 .ramp_delay = PMIC_RAMP_DELAY, \
ca55b718 235 .bypass_reg = LDO3_ACTIVE_CR, \
236 .bypass_mask = LDO_BYPASS_MASK, \
237 .bypass_val_on = LDO_BYPASS_MASK, \
238 .bypass_val_off = 0, \
ca55b718 239 .supply_name = #base, \
240}
241
242#define REG_LDO4(ids, base) { \
243 .name = #ids, \
244 .id = STPMIC1_##ids, \
245 .n_voltages = 1, \
246 .ops = &stpmic1_ldo4_fixed_regul_ops, \
247 .type = REGULATOR_VOLTAGE, \
248 .owner = THIS_MODULE, \
249 .min_uV = 3300000, \
250 .fixed_uV = 3300000, \
251 .enable_reg = LDO4_ACTIVE_CR, \
252 .enable_mask = LDO_ENABLE_MASK, \
253 .enable_val = 1, \
254 .disable_val = 0, \
255 .enable_time = PMIC_ENABLE_TIME_US, \
9ebde17c 256 .ramp_delay = PMIC_RAMP_DELAY, \
ca55b718 257 .supply_name = #base, \
258}
259
260#define REG_BUCK(ids, base) { \
261 .name = #ids, \
262 .id = STPMIC1_##ids, \
263 .ops = &stpmic1_buck_ops, \
264 .n_voltages = 64, \
265 .linear_ranges = base ## _ranges, \
266 .n_linear_ranges = ARRAY_SIZE(base ## _ranges), \
267 .type = REGULATOR_VOLTAGE, \
268 .owner = THIS_MODULE, \
269 .vsel_reg = ids##_ACTIVE_CR, \
270 .vsel_mask = BUCK_VOLTAGE_MASK, \
271 .enable_reg = ids##_ACTIVE_CR, \
272 .enable_mask = BUCK_ENABLE_MASK, \
273 .enable_val = 1, \
274 .disable_val = 0, \
275 .enable_time = PMIC_ENABLE_TIME_US, \
9ebde17c 276 .ramp_delay = PMIC_RAMP_DELAY, \
ca55b718 277 .of_map_mode = stpmic1_map_mode, \
278 .pull_down_reg = ids##_PULL_DOWN_REG, \
279 .pull_down_mask = ids##_PULL_DOWN_MASK, \
280 .supply_name = #base, \
281}
282
283#define REG_VREF_DDR(ids, base) { \
284 .name = #ids, \
285 .id = STPMIC1_##ids, \
286 .n_voltages = 1, \
287 .ops = &stpmic1_vref_ddr_ops, \
288 .type = REGULATOR_VOLTAGE, \
289 .owner = THIS_MODULE, \
290 .min_uV = 500000, \
291 .fixed_uV = 500000, \
292 .enable_reg = VREF_DDR_ACTIVE_CR, \
293 .enable_mask = BUCK_ENABLE_MASK, \
294 .enable_val = 1, \
295 .disable_val = 0, \
296 .enable_time = PMIC_ENABLE_TIME_US, \
ca55b718 297 .supply_name = #base, \
298}
299
e6fff62a
PPL
300#define REG_BOOST(ids, base) { \
301 .name = #ids, \
302 .id = STPMIC1_##ids, \
303 .n_voltages = 1, \
304 .ops = &stpmic1_boost_regul_ops, \
305 .type = REGULATOR_VOLTAGE, \
306 .owner = THIS_MODULE, \
307 .min_uV = 0, \
308 .fixed_uV = 5000000, \
309 .enable_reg = BST_SW_CR, \
310 .enable_mask = BOOST_ENABLED, \
311 .enable_val = BOOST_ENABLED, \
312 .disable_val = 0, \
313 .enable_time = PMIC_ENABLE_TIME_US, \
314 .supply_name = #base, \
315}
316
317#define REG_VBUS_OTG(ids, base) { \
318 .name = #ids, \
319 .id = STPMIC1_##ids, \
320 .n_voltages = 1, \
321 .ops = &stpmic1_switch_regul_ops, \
322 .type = REGULATOR_VOLTAGE, \
323 .owner = THIS_MODULE, \
324 .min_uV = 0, \
325 .fixed_uV = 5000000, \
326 .enable_reg = BST_SW_CR, \
327 .enable_mask = USBSW_OTG_SWITCH_ENABLED, \
328 .enable_val = USBSW_OTG_SWITCH_ENABLED, \
329 .disable_val = 0, \
330 .enable_time = PMIC_ENABLE_TIME_US, \
331 .supply_name = #base, \
332 .active_discharge_reg = BST_SW_CR, \
333 .active_discharge_mask = VBUS_OTG_DISCHARGE, \
334 .active_discharge_on = VBUS_OTG_DISCHARGE, \
335}
336
337#define REG_SW_OUT(ids, base) { \
ca55b718 338 .name = #ids, \
339 .id = STPMIC1_##ids, \
340 .n_voltages = 1, \
341 .ops = &stpmic1_switch_regul_ops, \
342 .type = REGULATOR_VOLTAGE, \
343 .owner = THIS_MODULE, \
344 .min_uV = 0, \
345 .fixed_uV = 5000000, \
e6fff62a
PPL
346 .enable_reg = BST_SW_CR, \
347 .enable_mask = SWIN_SWOUT_ENABLED, \
348 .enable_val = SWIN_SWOUT_ENABLED, \
ca55b718 349 .disable_val = 0, \
350 .enable_time = PMIC_ENABLE_TIME_US, \
351 .supply_name = #base, \
e6fff62a
PPL
352 .active_discharge_reg = BST_SW_CR, \
353 .active_discharge_mask = SW_OUT_DISCHARGE, \
354 .active_discharge_on = SW_OUT_DISCHARGE, \
ca55b718 355}
356
7c027c66 357static const struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
ca55b718 358 [STPMIC1_BUCK1] = {
359 .desc = REG_BUCK(BUCK1, buck1),
360 .icc_reg = BUCKS_ICCTO_CR,
361 .icc_mask = BIT(0),
362 .mask_reset_reg = BUCKS_MASK_RESET_CR,
363 .mask_reset_mask = BIT(0),
364 },
365 [STPMIC1_BUCK2] = {
366 .desc = REG_BUCK(BUCK2, buck2),
367 .icc_reg = BUCKS_ICCTO_CR,
368 .icc_mask = BIT(1),
369 .mask_reset_reg = BUCKS_MASK_RESET_CR,
370 .mask_reset_mask = BIT(1),
371 },
372 [STPMIC1_BUCK3] = {
373 .desc = REG_BUCK(BUCK3, buck3),
374 .icc_reg = BUCKS_ICCTO_CR,
375 .icc_mask = BIT(2),
376 .mask_reset_reg = BUCKS_MASK_RESET_CR,
377 .mask_reset_mask = BIT(2),
378 },
379 [STPMIC1_BUCK4] = {
380 .desc = REG_BUCK(BUCK4, buck4),
381 .icc_reg = BUCKS_ICCTO_CR,
382 .icc_mask = BIT(3),
383 .mask_reset_reg = BUCKS_MASK_RESET_CR,
384 .mask_reset_mask = BIT(3),
385 },
386 [STPMIC1_LDO1] = {
387 .desc = REG_LDO(LDO1, ldo1),
388 .icc_reg = LDOS_ICCTO_CR,
389 .icc_mask = BIT(0),
390 .mask_reset_reg = LDOS_MASK_RESET_CR,
391 .mask_reset_mask = BIT(0),
392 },
393 [STPMIC1_LDO2] = {
394 .desc = REG_LDO(LDO2, ldo2),
395 .icc_reg = LDOS_ICCTO_CR,
396 .icc_mask = BIT(1),
397 .mask_reset_reg = LDOS_MASK_RESET_CR,
398 .mask_reset_mask = BIT(1),
399 },
400 [STPMIC1_LDO3] = {
401 .desc = REG_LDO3(LDO3, ldo3),
402 .icc_reg = LDOS_ICCTO_CR,
403 .icc_mask = BIT(2),
404 .mask_reset_reg = LDOS_MASK_RESET_CR,
405 .mask_reset_mask = BIT(2),
406 },
407 [STPMIC1_LDO4] = {
408 .desc = REG_LDO4(LDO4, ldo4),
409 .icc_reg = LDOS_ICCTO_CR,
410 .icc_mask = BIT(3),
411 .mask_reset_reg = LDOS_MASK_RESET_CR,
412 .mask_reset_mask = BIT(3),
413 },
414 [STPMIC1_LDO5] = {
415 .desc = REG_LDO(LDO5, ldo5),
416 .icc_reg = LDOS_ICCTO_CR,
417 .icc_mask = BIT(4),
418 .mask_reset_reg = LDOS_MASK_RESET_CR,
419 .mask_reset_mask = BIT(4),
420 },
421 [STPMIC1_LDO6] = {
422 .desc = REG_LDO(LDO6, ldo6),
423 .icc_reg = LDOS_ICCTO_CR,
424 .icc_mask = BIT(5),
425 .mask_reset_reg = LDOS_MASK_RESET_CR,
426 .mask_reset_mask = BIT(5),
427 },
428 [STPMIC1_VREF_DDR] = {
429 .desc = REG_VREF_DDR(VREF_DDR, vref_ddr),
430 .mask_reset_reg = LDOS_MASK_RESET_CR,
431 .mask_reset_mask = BIT(6),
432 },
433 [STPMIC1_BOOST] = {
e6fff62a 434 .desc = REG_BOOST(BOOST, boost),
ca55b718 435 .icc_reg = BUCKS_ICCTO_CR,
436 .icc_mask = BIT(6),
437 },
438 [STPMIC1_VBUS_OTG] = {
e6fff62a 439 .desc = REG_VBUS_OTG(VBUS_OTG, pwr_sw1),
ca55b718 440 .icc_reg = BUCKS_ICCTO_CR,
441 .icc_mask = BIT(4),
442 },
443 [STPMIC1_SW_OUT] = {
e6fff62a 444 .desc = REG_SW_OUT(SW_OUT, pwr_sw2),
ca55b718 445 .icc_reg = BUCKS_ICCTO_CR,
446 .icc_mask = BIT(5),
447 },
448};
449
450static unsigned int stpmic1_map_mode(unsigned int mode)
451{
452 switch (mode) {
453 case STPMIC1_BUCK_MODE_NORMAL:
454 return REGULATOR_MODE_NORMAL;
455 case STPMIC1_BUCK_MODE_LP:
456 return REGULATOR_MODE_STANDBY;
457 default:
c18fb34a 458 return REGULATOR_MODE_INVALID;
ca55b718 459 }
460}
461
462static unsigned int stpmic1_get_mode(struct regulator_dev *rdev)
463{
464 int value;
8c44e448 465 struct regmap *regmap = rdev_get_regmap(rdev);
ca55b718 466
8c44e448 467 regmap_read(regmap, rdev->desc->enable_reg, &value);
ca55b718 468
469 if (value & STPMIC1_BUCK_MODE_LP)
470 return REGULATOR_MODE_STANDBY;
471
472 return REGULATOR_MODE_NORMAL;
473}
474
475static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode)
476{
477 int value;
8c44e448 478 struct regmap *regmap = rdev_get_regmap(rdev);
ca55b718 479
480 switch (mode) {
481 case REGULATOR_MODE_NORMAL:
482 value = STPMIC1_BUCK_MODE_NORMAL;
483 break;
484 case REGULATOR_MODE_STANDBY:
485 value = STPMIC1_BUCK_MODE_LP;
486 break;
487 default:
488 return -EINVAL;
489 }
490
8c44e448 491 return regmap_update_bits(regmap, rdev->desc->enable_reg,
ca55b718 492 STPMIC1_BUCK_MODE_LP, value);
493}
494
89a6a5e5
MV
495static int stpmic1_set_icc(struct regulator_dev *rdev, int lim, int severity,
496 bool enable)
ca55b718 497{
8c44e448 498 struct stpmic1_regulator_cfg *cfg = rdev_get_drvdata(rdev);
ef541f73 499 struct regmap *regmap = rdev_get_regmap(rdev);
ca55b718 500
89a6a5e5
MV
501 /*
502 * The code seems like one bit in a register controls whether OCP is
503 * enabled. So we might be able to turn it off here is if that
504 * was requested. I won't support this because I don't have the HW.
505 * Feel free to try and implement if you have the HW and need kernel
506 * to disable this.
507 *
508 * Also, I don't know if limit can be configured or if we support
509 * error/warning instead of protect. So I just keep existing logic
510 * and assume no.
511 */
512 if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
513 return -EINVAL;
514
ca55b718 515 /* enable switch off in case of over current */
8c44e448
PPL
516 return regmap_update_bits(regmap, cfg->icc_reg, cfg->icc_mask,
517 cfg->icc_mask);
ca55b718 518}
519
520static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
521{
522 struct regulator_dev *rdev = (struct regulator_dev *)data;
523
ca55b718 524 /* Send an overcurrent notification */
525 regulator_notifier_call_chain(rdev,
526 REGULATOR_EVENT_OVER_CURRENT,
527 NULL);
528
ca55b718 529 return IRQ_HANDLED;
530}
531
ca55b718 532#define MATCH(_name, _id) \
533 [STPMIC1_##_id] = { \
534 .name = #_name, \
535 .desc = &stpmic1_regulator_cfgs[STPMIC1_##_id].desc, \
536 }
537
8c44e448 538static struct of_regulator_match stpmic1_matches[] = {
ca55b718 539 MATCH(buck1, BUCK1),
540 MATCH(buck2, BUCK2),
541 MATCH(buck3, BUCK3),
542 MATCH(buck4, BUCK4),
543 MATCH(ldo1, LDO1),
544 MATCH(ldo2, LDO2),
545 MATCH(ldo3, LDO3),
546 MATCH(ldo4, LDO4),
547 MATCH(ldo5, LDO5),
548 MATCH(ldo6, LDO6),
549 MATCH(vref_ddr, VREF_DDR),
550 MATCH(boost, BOOST),
551 MATCH(pwr_sw1, VBUS_OTG),
552 MATCH(pwr_sw2, SW_OUT),
553};
554
8c44e448
PPL
555static int stpmic1_regulator_register(struct platform_device *pdev, int id,
556 struct of_regulator_match *match,
557 const struct stpmic1_regulator_cfg *cfg)
ca55b718 558{
559 struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent);
560 struct regulator_dev *rdev;
561 struct regulator_config config = {};
8c44e448
PPL
562 int ret = 0;
563 int irq;
ca55b718 564
565 config.dev = &pdev->dev;
8c44e448
PPL
566 config.init_data = match->init_data;
567 config.of_node = match->of_node;
ca55b718 568 config.regmap = pmic_dev->regmap;
8c44e448 569 config.driver_data = (void *)cfg;
ca55b718 570
8c44e448 571 rdev = devm_regulator_register(&pdev->dev, &cfg->desc, &config);
ca55b718 572 if (IS_ERR(rdev)) {
573 dev_err(&pdev->dev, "failed to register %s regulator\n",
8c44e448
PPL
574 cfg->desc.name);
575 return PTR_ERR(rdev);
ca55b718 576 }
577
8c44e448
PPL
578 /* set mask reset */
579 if (of_get_property(config.of_node, "st,mask-reset", NULL) &&
580 cfg->mask_reset_reg != 0) {
581 ret = regmap_update_bits(pmic_dev->regmap,
582 cfg->mask_reset_reg,
583 cfg->mask_reset_mask,
584 cfg->mask_reset_mask);
585 if (ret) {
586 dev_err(&pdev->dev, "set mask reset failed\n");
587 return ret;
588 }
589 }
590
591 /* setup an irq handler for over-current detection */
592 irq = of_irq_get(config.of_node, 0);
593 if (irq > 0) {
594 ret = devm_request_threaded_irq(&pdev->dev,
595 irq, NULL,
596 stpmic1_curlim_irq_handler,
597 IRQF_ONESHOT | IRQF_SHARED,
598 pdev->name, rdev);
599 if (ret) {
600 dev_err(&pdev->dev, "Request IRQ failed\n");
601 return ret;
602 }
603 }
604 return 0;
ca55b718 605}
606
607static int stpmic1_regulator_probe(struct platform_device *pdev)
608{
ca55b718 609 int i, ret;
610
8c44e448
PPL
611 ret = of_regulator_match(&pdev->dev, pdev->dev.of_node, stpmic1_matches,
612 ARRAY_SIZE(stpmic1_matches));
ca55b718 613 if (ret < 0) {
614 dev_err(&pdev->dev,
615 "Error in PMIC regulator device tree node");
616 return ret;
617 }
618
ca55b718 619 for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) {
8c44e448
PPL
620 ret = stpmic1_regulator_register(pdev, i, &stpmic1_matches[i],
621 &stpmic1_regulator_cfgs[i]);
622 if (ret < 0)
ca55b718 623 return ret;
ca55b718 624 }
625
626 dev_dbg(&pdev->dev, "stpmic1_regulator driver probed\n");
627
628 return 0;
629}
630
631static const struct of_device_id of_pmic_regulator_match[] = {
632 { .compatible = "st,stpmic1-regulators" },
633 { },
634};
635
636MODULE_DEVICE_TABLE(of, of_pmic_regulator_match);
637
638static struct platform_driver stpmic1_regulator_driver = {
639 .driver = {
640 .name = "stpmic1-regulator",
641 .of_match_table = of_match_ptr(of_pmic_regulator_match),
642 },
643 .probe = stpmic1_regulator_probe,
644};
645
646module_platform_driver(stpmic1_regulator_driver);
647
648MODULE_DESCRIPTION("STPMIC1 PMIC voltage regulator driver");
649MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
650MODULE_LICENSE("GPL v2");