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