blob: 2d7597c76e4a1d26a8e8026690ea4a39f12a9dc4 [file] [log] [blame]
pascal pailletca55b712018-10-08 16:29:40 +00001// 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
Pascal PAILLET-LMEb9058da2019-02-19 10:04:31 +000015#include <dt-bindings/mfd/st,stpmic1.h>
16
pascal pailletca55b712018-10-08 16:29:40 +000017/**
Lee Jonesec84a7d2020-06-26 07:57:33 +010018 * struct stpmic1 regulator description: this structure is used as driver data
pascal pailletca55b712018-10-08 16:29:40 +000019 * @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
pascal pailletca55b712018-10-08 16:29:40 +000033static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode);
34static unsigned int stpmic1_get_mode(struct regulator_dev *rdev);
Matti Vaittinen89a6a5e2021-06-03 08:42:12 +030035static int stpmic1_set_icc(struct regulator_dev *rdev, int lim, int severity,
36 bool enable);
pascal pailletca55b712018-10-08 16:29:40 +000037static 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
Pascal Paillet9ebde172019-11-13 17:15:29 +010058/* Ramp delay worst case is (2250uV/uS) */
59#define PMIC_RAMP_DELAY 2200
pascal pailletca55b712018-10-08 16:29:40 +000060
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030061static const struct linear_range buck1_ranges[] = {
Pascal PAILLET-LME48593a92019-02-19 10:04:34 +000062 REGULATOR_LINEAR_RANGE(725000, 0, 4, 0),
63 REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000),
64 REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0),
pascal pailletca55b712018-10-08 16:29:40 +000065};
66
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030067static const struct linear_range buck2_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +000068 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
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030081static const struct linear_range buck3_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +000082 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),
pascal pailletca55b712018-10-08 16:29:40 +000089};
90
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030091static const struct linear_range buck4_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +000092 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),
pascal pailletca55b712018-10-08 16:29:40 +000099};
100
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300101static const struct linear_range ldo1_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000102 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
103 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
104 REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
pascal pailletca55b712018-10-08 16:29:40 +0000105};
106
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300107static const struct linear_range ldo2_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000108 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
109 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
110 REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
pascal pailletca55b712018-10-08 16:29:40 +0000111};
112
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300113static const struct linear_range ldo3_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000114 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
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300121static const struct linear_range ldo5_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000122 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
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300127static const struct linear_range ldo6_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000128 REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000),
129 REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
130};
131
Axel Lin7c027c62019-01-23 20:26:39 +0800132static const struct regulator_ops stpmic1_ldo_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000133 .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,
pascal pailletca55b712018-10-08 16:29:40 +0000140 .set_over_current_protection = stpmic1_set_icc,
141};
142
Axel Lin7c027c62019-01-23 20:26:39 +0800143static const struct regulator_ops stpmic1_ldo3_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000144 .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,
pascal pailletca55b712018-10-08 16:29:40 +0000151 .get_bypass = regulator_get_bypass_regmap,
152 .set_bypass = regulator_set_bypass_regmap,
153 .set_over_current_protection = stpmic1_set_icc,
154};
155
Axel Lin7c027c62019-01-23 20:26:39 +0800156static const struct regulator_ops stpmic1_ldo4_fixed_regul_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000157 .is_enabled = regulator_is_enabled_regmap,
158 .enable = regulator_enable_regmap,
159 .disable = regulator_disable_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000160 .set_over_current_protection = stpmic1_set_icc,
161};
162
Axel Lin7c027c62019-01-23 20:26:39 +0800163static const struct regulator_ops stpmic1_buck_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000164 .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
Axel Lin7c027c62019-01-23 20:26:39 +0800177static const struct regulator_ops stpmic1_vref_ddr_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000178 .is_enabled = regulator_is_enabled_regmap,
179 .enable = regulator_enable_regmap,
180 .disable = regulator_disable_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000181};
182
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000183static 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
Axel Lin7c027c62019-01-23 20:26:39 +0800190static const struct regulator_ops stpmic1_switch_regul_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000191 .is_enabled = regulator_is_enabled_regmap,
192 .enable = regulator_enable_regmap,
193 .disable = regulator_disable_regmap,
194 .set_over_current_protection = stpmic1_set_icc,
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000195 .set_active_discharge = regulator_set_active_discharge_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000196};
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, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100214 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000215 .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, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100234 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000235 .bypass_reg = LDO3_ACTIVE_CR, \
236 .bypass_mask = LDO_BYPASS_MASK, \
237 .bypass_val_on = LDO_BYPASS_MASK, \
238 .bypass_val_off = 0, \
pascal pailletca55b712018-10-08 16:29:40 +0000239 .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, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100256 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000257 .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, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100276 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000277 .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, \
pascal pailletca55b712018-10-08 16:29:40 +0000297 .supply_name = #base, \
298}
299
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000300#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) { \
pascal pailletca55b712018-10-08 16:29:40 +0000318 .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, \
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000326 .enable_reg = BST_SW_CR, \
327 .enable_mask = USBSW_OTG_SWITCH_ENABLED, \
328 .enable_val = USBSW_OTG_SWITCH_ENABLED, \
pascal pailletca55b712018-10-08 16:29:40 +0000329 .disable_val = 0, \
330 .enable_time = PMIC_ENABLE_TIME_US, \
331 .supply_name = #base, \
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000332 .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) { \
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, \
346 .enable_reg = BST_SW_CR, \
347 .enable_mask = SWIN_SWOUT_ENABLED, \
348 .enable_val = SWIN_SWOUT_ENABLED, \
349 .disable_val = 0, \
350 .enable_time = PMIC_ENABLE_TIME_US, \
351 .supply_name = #base, \
352 .active_discharge_reg = BST_SW_CR, \
353 .active_discharge_mask = SW_OUT_DISCHARGE, \
354 .active_discharge_on = SW_OUT_DISCHARGE, \
pascal pailletca55b712018-10-08 16:29:40 +0000355}
356
Axel Lin7c027c62019-01-23 20:26:39 +0800357static const struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000358 [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] = {
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000434 .desc = REG_BOOST(BOOST, boost),
pascal pailletca55b712018-10-08 16:29:40 +0000435 .icc_reg = BUCKS_ICCTO_CR,
436 .icc_mask = BIT(6),
437 },
438 [STPMIC1_VBUS_OTG] = {
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000439 .desc = REG_VBUS_OTG(VBUS_OTG, pwr_sw1),
pascal pailletca55b712018-10-08 16:29:40 +0000440 .icc_reg = BUCKS_ICCTO_CR,
441 .icc_mask = BIT(4),
442 },
443 [STPMIC1_SW_OUT] = {
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000444 .desc = REG_SW_OUT(SW_OUT, pwr_sw2),
pascal pailletca55b712018-10-08 16:29:40 +0000445 .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:
Axel Linc18fb342018-10-09 16:52:21 +0800458 return REGULATOR_MODE_INVALID;
pascal pailletca55b712018-10-08 16:29:40 +0000459 }
460}
461
462static unsigned int stpmic1_get_mode(struct regulator_dev *rdev)
463{
464 int value;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000465 struct regmap *regmap = rdev_get_regmap(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000466
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000467 regmap_read(regmap, rdev->desc->enable_reg, &value);
pascal pailletca55b712018-10-08 16:29:40 +0000468
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;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000478 struct regmap *regmap = rdev_get_regmap(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000479
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
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000491 return regmap_update_bits(regmap, rdev->desc->enable_reg,
pascal pailletca55b712018-10-08 16:29:40 +0000492 STPMIC1_BUCK_MODE_LP, value);
493}
494
Matti Vaittinen89a6a5e2021-06-03 08:42:12 +0300495static int stpmic1_set_icc(struct regulator_dev *rdev, int lim, int severity,
496 bool enable)
pascal pailletca55b712018-10-08 16:29:40 +0000497{
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000498 struct stpmic1_regulator_cfg *cfg = rdev_get_drvdata(rdev);
Axel Linef541f72019-02-14 09:59:56 +0800499 struct regmap *regmap = rdev_get_regmap(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000500
Matti Vaittinen89a6a5e2021-06-03 08:42:12 +0300501 /*
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
pascal pailletca55b712018-10-08 16:29:40 +0000515 /* enable switch off in case of over current */
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000516 return regmap_update_bits(regmap, cfg->icc_reg, cfg->icc_mask,
517 cfg->icc_mask);
pascal pailletca55b712018-10-08 16:29:40 +0000518}
519
520static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
521{
522 struct regulator_dev *rdev = (struct regulator_dev *)data;
523
pascal pailletca55b712018-10-08 16:29:40 +0000524 /* Send an overcurrent notification */
525 regulator_notifier_call_chain(rdev,
526 REGULATOR_EVENT_OVER_CURRENT,
527 NULL);
528
pascal pailletca55b712018-10-08 16:29:40 +0000529 return IRQ_HANDLED;
530}
531
pascal pailletca55b712018-10-08 16:29:40 +0000532#define MATCH(_name, _id) \
533 [STPMIC1_##_id] = { \
534 .name = #_name, \
535 .desc = &stpmic1_regulator_cfgs[STPMIC1_##_id].desc, \
536 }
537
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000538static struct of_regulator_match stpmic1_matches[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000539 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
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000555static int stpmic1_regulator_register(struct platform_device *pdev, int id,
556 struct of_regulator_match *match,
557 const struct stpmic1_regulator_cfg *cfg)
pascal pailletca55b712018-10-08 16:29:40 +0000558{
559 struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent);
560 struct regulator_dev *rdev;
561 struct regulator_config config = {};
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000562 int ret = 0;
563 int irq;
pascal pailletca55b712018-10-08 16:29:40 +0000564
565 config.dev = &pdev->dev;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000566 config.init_data = match->init_data;
567 config.of_node = match->of_node;
pascal pailletca55b712018-10-08 16:29:40 +0000568 config.regmap = pmic_dev->regmap;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000569 config.driver_data = (void *)cfg;
pascal pailletca55b712018-10-08 16:29:40 +0000570
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000571 rdev = devm_regulator_register(&pdev->dev, &cfg->desc, &config);
pascal pailletca55b712018-10-08 16:29:40 +0000572 if (IS_ERR(rdev)) {
573 dev_err(&pdev->dev, "failed to register %s regulator\n",
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000574 cfg->desc.name);
575 return PTR_ERR(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000576 }
577
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000578 /* 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;
pascal pailletca55b712018-10-08 16:29:40 +0000605}
606
607static int stpmic1_regulator_probe(struct platform_device *pdev)
608{
pascal pailletca55b712018-10-08 16:29:40 +0000609 int i, ret;
610
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000611 ret = of_regulator_match(&pdev->dev, pdev->dev.of_node, stpmic1_matches,
612 ARRAY_SIZE(stpmic1_matches));
pascal pailletca55b712018-10-08 16:29:40 +0000613 if (ret < 0) {
614 dev_err(&pdev->dev,
615 "Error in PMIC regulator device tree node");
616 return ret;
617 }
618
pascal pailletca55b712018-10-08 16:29:40 +0000619 for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) {
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000620 ret = stpmic1_regulator_register(pdev, i, &stpmic1_matches[i],
621 &stpmic1_regulator_cfgs[i]);
622 if (ret < 0)
pascal pailletca55b712018-10-08 16:29:40 +0000623 return ret;
pascal pailletca55b712018-10-08 16:29:40 +0000624 }
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");