blob: 73e0ab2baeaa61ee0aadc129a602b92650c0116f [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);
35static int stpmic1_set_icc(struct regulator_dev *rdev);
pascal pailletca55b712018-10-08 16:29:40 +000036static 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
Pascal Paillet9ebde172019-11-13 17:15:29 +010057/* Ramp delay worst case is (2250uV/uS) */
58#define PMIC_RAMP_DELAY 2200
pascal pailletca55b712018-10-08 16:29:40 +000059
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030060static const struct linear_range buck1_ranges[] = {
Pascal PAILLET-LME48593a92019-02-19 10:04:34 +000061 REGULATOR_LINEAR_RANGE(725000, 0, 4, 0),
62 REGULATOR_LINEAR_RANGE(725000, 5, 36, 25000),
63 REGULATOR_LINEAR_RANGE(1500000, 37, 63, 0),
pascal pailletca55b712018-10-08 16:29:40 +000064};
65
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030066static const struct linear_range buck2_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +000067 REGULATOR_LINEAR_RANGE(1000000, 0, 17, 0),
68 REGULATOR_LINEAR_RANGE(1050000, 18, 19, 0),
69 REGULATOR_LINEAR_RANGE(1100000, 20, 21, 0),
70 REGULATOR_LINEAR_RANGE(1150000, 22, 23, 0),
71 REGULATOR_LINEAR_RANGE(1200000, 24, 25, 0),
72 REGULATOR_LINEAR_RANGE(1250000, 26, 27, 0),
73 REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
74 REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
75 REGULATOR_LINEAR_RANGE(1400000, 32, 33, 0),
76 REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
77 REGULATOR_LINEAR_RANGE(1500000, 36, 63, 0),
78};
79
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030080static const struct linear_range buck3_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +000081 REGULATOR_LINEAR_RANGE(1000000, 0, 19, 0),
82 REGULATOR_LINEAR_RANGE(1100000, 20, 23, 0),
83 REGULATOR_LINEAR_RANGE(1200000, 24, 27, 0),
84 REGULATOR_LINEAR_RANGE(1300000, 28, 31, 0),
85 REGULATOR_LINEAR_RANGE(1400000, 32, 35, 0),
86 REGULATOR_LINEAR_RANGE(1500000, 36, 55, 100000),
87 REGULATOR_LINEAR_RANGE(3400000, 56, 63, 0),
pascal pailletca55b712018-10-08 16:29:40 +000088};
89
Matti Vaittinen60ab7f42020-05-08 18:43:36 +030090static const struct linear_range buck4_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +000091 REGULATOR_LINEAR_RANGE(600000, 0, 27, 25000),
92 REGULATOR_LINEAR_RANGE(1300000, 28, 29, 0),
93 REGULATOR_LINEAR_RANGE(1350000, 30, 31, 0),
94 REGULATOR_LINEAR_RANGE(1400000, 32, 33, 0),
95 REGULATOR_LINEAR_RANGE(1450000, 34, 35, 0),
96 REGULATOR_LINEAR_RANGE(1500000, 36, 60, 100000),
97 REGULATOR_LINEAR_RANGE(3900000, 61, 63, 0),
pascal pailletca55b712018-10-08 16:29:40 +000098};
99
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300100static const struct linear_range ldo1_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000101 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
102 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
103 REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
pascal pailletca55b712018-10-08 16:29:40 +0000104};
105
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300106static const struct linear_range ldo2_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000107 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
108 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
109 REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
pascal pailletca55b712018-10-08 16:29:40 +0000110};
111
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300112static const struct linear_range ldo3_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000113 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
114 REGULATOR_LINEAR_RANGE(1700000, 8, 24, 100000),
115 REGULATOR_LINEAR_RANGE(3300000, 25, 30, 0),
116 /* with index 31 LDO3 is in DDR mode */
117 REGULATOR_LINEAR_RANGE(500000, 31, 31, 0),
118};
119
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300120static const struct linear_range ldo5_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000121 REGULATOR_LINEAR_RANGE(1700000, 0, 7, 0),
122 REGULATOR_LINEAR_RANGE(1700000, 8, 30, 100000),
123 REGULATOR_LINEAR_RANGE(3900000, 31, 31, 0),
124};
125
Matti Vaittinen60ab7f42020-05-08 18:43:36 +0300126static const struct linear_range ldo6_ranges[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000127 REGULATOR_LINEAR_RANGE(900000, 0, 24, 100000),
128 REGULATOR_LINEAR_RANGE(3300000, 25, 31, 0),
129};
130
Axel Lin7c027c62019-01-23 20:26:39 +0800131static const struct regulator_ops stpmic1_ldo_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000132 .list_voltage = regulator_list_voltage_linear_range,
133 .map_voltage = regulator_map_voltage_linear_range,
134 .is_enabled = regulator_is_enabled_regmap,
135 .enable = regulator_enable_regmap,
136 .disable = regulator_disable_regmap,
137 .get_voltage_sel = regulator_get_voltage_sel_regmap,
138 .set_voltage_sel = regulator_set_voltage_sel_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000139 .set_over_current_protection = stpmic1_set_icc,
140};
141
Axel Lin7c027c62019-01-23 20:26:39 +0800142static const struct regulator_ops stpmic1_ldo3_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000143 .list_voltage = regulator_list_voltage_linear_range,
144 .map_voltage = regulator_map_voltage_iterate,
145 .is_enabled = regulator_is_enabled_regmap,
146 .enable = regulator_enable_regmap,
147 .disable = regulator_disable_regmap,
148 .get_voltage_sel = regulator_get_voltage_sel_regmap,
149 .set_voltage_sel = regulator_set_voltage_sel_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000150 .get_bypass = regulator_get_bypass_regmap,
151 .set_bypass = regulator_set_bypass_regmap,
152 .set_over_current_protection = stpmic1_set_icc,
153};
154
Axel Lin7c027c62019-01-23 20:26:39 +0800155static const struct regulator_ops stpmic1_ldo4_fixed_regul_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000156 .is_enabled = regulator_is_enabled_regmap,
157 .enable = regulator_enable_regmap,
158 .disable = regulator_disable_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000159 .set_over_current_protection = stpmic1_set_icc,
160};
161
Axel Lin7c027c62019-01-23 20:26:39 +0800162static const struct regulator_ops stpmic1_buck_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000163 .list_voltage = regulator_list_voltage_linear_range,
164 .map_voltage = regulator_map_voltage_linear_range,
165 .is_enabled = regulator_is_enabled_regmap,
166 .enable = regulator_enable_regmap,
167 .disable = regulator_disable_regmap,
168 .get_voltage_sel = regulator_get_voltage_sel_regmap,
169 .set_voltage_sel = regulator_set_voltage_sel_regmap,
170 .set_pull_down = regulator_set_pull_down_regmap,
171 .set_mode = stpmic1_set_mode,
172 .get_mode = stpmic1_get_mode,
173 .set_over_current_protection = stpmic1_set_icc,
174};
175
Axel Lin7c027c62019-01-23 20:26:39 +0800176static const struct regulator_ops stpmic1_vref_ddr_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000177 .is_enabled = regulator_is_enabled_regmap,
178 .enable = regulator_enable_regmap,
179 .disable = regulator_disable_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000180};
181
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000182static const struct regulator_ops stpmic1_boost_regul_ops = {
183 .is_enabled = regulator_is_enabled_regmap,
184 .enable = regulator_enable_regmap,
185 .disable = regulator_disable_regmap,
186 .set_over_current_protection = stpmic1_set_icc,
187};
188
Axel Lin7c027c62019-01-23 20:26:39 +0800189static const struct regulator_ops stpmic1_switch_regul_ops = {
pascal pailletca55b712018-10-08 16:29:40 +0000190 .is_enabled = regulator_is_enabled_regmap,
191 .enable = regulator_enable_regmap,
192 .disable = regulator_disable_regmap,
193 .set_over_current_protection = stpmic1_set_icc,
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000194 .set_active_discharge = regulator_set_active_discharge_regmap,
pascal pailletca55b712018-10-08 16:29:40 +0000195};
196
197#define REG_LDO(ids, base) { \
198 .name = #ids, \
199 .id = STPMIC1_##ids, \
200 .n_voltages = 32, \
201 .ops = &stpmic1_ldo_ops, \
202 .linear_ranges = base ## _ranges, \
203 .n_linear_ranges = ARRAY_SIZE(base ## _ranges), \
204 .type = REGULATOR_VOLTAGE, \
205 .owner = THIS_MODULE, \
206 .vsel_reg = ids##_ACTIVE_CR, \
207 .vsel_mask = LDO_VOLTAGE_MASK, \
208 .enable_reg = ids##_ACTIVE_CR, \
209 .enable_mask = LDO_ENABLE_MASK, \
210 .enable_val = 1, \
211 .disable_val = 0, \
212 .enable_time = PMIC_ENABLE_TIME_US, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100213 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000214 .supply_name = #base, \
215}
216
217#define REG_LDO3(ids, base) { \
218 .name = #ids, \
219 .id = STPMIC1_##ids, \
220 .n_voltages = 32, \
221 .ops = &stpmic1_ldo3_ops, \
222 .linear_ranges = ldo3_ranges, \
223 .n_linear_ranges = ARRAY_SIZE(ldo3_ranges), \
224 .type = REGULATOR_VOLTAGE, \
225 .owner = THIS_MODULE, \
226 .vsel_reg = LDO3_ACTIVE_CR, \
227 .vsel_mask = LDO_VOLTAGE_MASK, \
228 .enable_reg = LDO3_ACTIVE_CR, \
229 .enable_mask = LDO_ENABLE_MASK, \
230 .enable_val = 1, \
231 .disable_val = 0, \
232 .enable_time = PMIC_ENABLE_TIME_US, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100233 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000234 .bypass_reg = LDO3_ACTIVE_CR, \
235 .bypass_mask = LDO_BYPASS_MASK, \
236 .bypass_val_on = LDO_BYPASS_MASK, \
237 .bypass_val_off = 0, \
pascal pailletca55b712018-10-08 16:29:40 +0000238 .supply_name = #base, \
239}
240
241#define REG_LDO4(ids, base) { \
242 .name = #ids, \
243 .id = STPMIC1_##ids, \
244 .n_voltages = 1, \
245 .ops = &stpmic1_ldo4_fixed_regul_ops, \
246 .type = REGULATOR_VOLTAGE, \
247 .owner = THIS_MODULE, \
248 .min_uV = 3300000, \
249 .fixed_uV = 3300000, \
250 .enable_reg = LDO4_ACTIVE_CR, \
251 .enable_mask = LDO_ENABLE_MASK, \
252 .enable_val = 1, \
253 .disable_val = 0, \
254 .enable_time = PMIC_ENABLE_TIME_US, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100255 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000256 .supply_name = #base, \
257}
258
259#define REG_BUCK(ids, base) { \
260 .name = #ids, \
261 .id = STPMIC1_##ids, \
262 .ops = &stpmic1_buck_ops, \
263 .n_voltages = 64, \
264 .linear_ranges = base ## _ranges, \
265 .n_linear_ranges = ARRAY_SIZE(base ## _ranges), \
266 .type = REGULATOR_VOLTAGE, \
267 .owner = THIS_MODULE, \
268 .vsel_reg = ids##_ACTIVE_CR, \
269 .vsel_mask = BUCK_VOLTAGE_MASK, \
270 .enable_reg = ids##_ACTIVE_CR, \
271 .enable_mask = BUCK_ENABLE_MASK, \
272 .enable_val = 1, \
273 .disable_val = 0, \
274 .enable_time = PMIC_ENABLE_TIME_US, \
Pascal Paillet9ebde172019-11-13 17:15:29 +0100275 .ramp_delay = PMIC_RAMP_DELAY, \
pascal pailletca55b712018-10-08 16:29:40 +0000276 .of_map_mode = stpmic1_map_mode, \
277 .pull_down_reg = ids##_PULL_DOWN_REG, \
278 .pull_down_mask = ids##_PULL_DOWN_MASK, \
279 .supply_name = #base, \
280}
281
282#define REG_VREF_DDR(ids, base) { \
283 .name = #ids, \
284 .id = STPMIC1_##ids, \
285 .n_voltages = 1, \
286 .ops = &stpmic1_vref_ddr_ops, \
287 .type = REGULATOR_VOLTAGE, \
288 .owner = THIS_MODULE, \
289 .min_uV = 500000, \
290 .fixed_uV = 500000, \
291 .enable_reg = VREF_DDR_ACTIVE_CR, \
292 .enable_mask = BUCK_ENABLE_MASK, \
293 .enable_val = 1, \
294 .disable_val = 0, \
295 .enable_time = PMIC_ENABLE_TIME_US, \
pascal pailletca55b712018-10-08 16:29:40 +0000296 .supply_name = #base, \
297}
298
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000299#define REG_BOOST(ids, base) { \
300 .name = #ids, \
301 .id = STPMIC1_##ids, \
302 .n_voltages = 1, \
303 .ops = &stpmic1_boost_regul_ops, \
304 .type = REGULATOR_VOLTAGE, \
305 .owner = THIS_MODULE, \
306 .min_uV = 0, \
307 .fixed_uV = 5000000, \
308 .enable_reg = BST_SW_CR, \
309 .enable_mask = BOOST_ENABLED, \
310 .enable_val = BOOST_ENABLED, \
311 .disable_val = 0, \
312 .enable_time = PMIC_ENABLE_TIME_US, \
313 .supply_name = #base, \
314}
315
316#define REG_VBUS_OTG(ids, base) { \
pascal pailletca55b712018-10-08 16:29:40 +0000317 .name = #ids, \
318 .id = STPMIC1_##ids, \
319 .n_voltages = 1, \
320 .ops = &stpmic1_switch_regul_ops, \
321 .type = REGULATOR_VOLTAGE, \
322 .owner = THIS_MODULE, \
323 .min_uV = 0, \
324 .fixed_uV = 5000000, \
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000325 .enable_reg = BST_SW_CR, \
326 .enable_mask = USBSW_OTG_SWITCH_ENABLED, \
327 .enable_val = USBSW_OTG_SWITCH_ENABLED, \
pascal pailletca55b712018-10-08 16:29:40 +0000328 .disable_val = 0, \
329 .enable_time = PMIC_ENABLE_TIME_US, \
330 .supply_name = #base, \
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000331 .active_discharge_reg = BST_SW_CR, \
332 .active_discharge_mask = VBUS_OTG_DISCHARGE, \
333 .active_discharge_on = VBUS_OTG_DISCHARGE, \
334}
335
336#define REG_SW_OUT(ids, base) { \
337 .name = #ids, \
338 .id = STPMIC1_##ids, \
339 .n_voltages = 1, \
340 .ops = &stpmic1_switch_regul_ops, \
341 .type = REGULATOR_VOLTAGE, \
342 .owner = THIS_MODULE, \
343 .min_uV = 0, \
344 .fixed_uV = 5000000, \
345 .enable_reg = BST_SW_CR, \
346 .enable_mask = SWIN_SWOUT_ENABLED, \
347 .enable_val = SWIN_SWOUT_ENABLED, \
348 .disable_val = 0, \
349 .enable_time = PMIC_ENABLE_TIME_US, \
350 .supply_name = #base, \
351 .active_discharge_reg = BST_SW_CR, \
352 .active_discharge_mask = SW_OUT_DISCHARGE, \
353 .active_discharge_on = SW_OUT_DISCHARGE, \
pascal pailletca55b712018-10-08 16:29:40 +0000354}
355
Axel Lin7c027c62019-01-23 20:26:39 +0800356static const struct stpmic1_regulator_cfg stpmic1_regulator_cfgs[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000357 [STPMIC1_BUCK1] = {
358 .desc = REG_BUCK(BUCK1, buck1),
359 .icc_reg = BUCKS_ICCTO_CR,
360 .icc_mask = BIT(0),
361 .mask_reset_reg = BUCKS_MASK_RESET_CR,
362 .mask_reset_mask = BIT(0),
363 },
364 [STPMIC1_BUCK2] = {
365 .desc = REG_BUCK(BUCK2, buck2),
366 .icc_reg = BUCKS_ICCTO_CR,
367 .icc_mask = BIT(1),
368 .mask_reset_reg = BUCKS_MASK_RESET_CR,
369 .mask_reset_mask = BIT(1),
370 },
371 [STPMIC1_BUCK3] = {
372 .desc = REG_BUCK(BUCK3, buck3),
373 .icc_reg = BUCKS_ICCTO_CR,
374 .icc_mask = BIT(2),
375 .mask_reset_reg = BUCKS_MASK_RESET_CR,
376 .mask_reset_mask = BIT(2),
377 },
378 [STPMIC1_BUCK4] = {
379 .desc = REG_BUCK(BUCK4, buck4),
380 .icc_reg = BUCKS_ICCTO_CR,
381 .icc_mask = BIT(3),
382 .mask_reset_reg = BUCKS_MASK_RESET_CR,
383 .mask_reset_mask = BIT(3),
384 },
385 [STPMIC1_LDO1] = {
386 .desc = REG_LDO(LDO1, ldo1),
387 .icc_reg = LDOS_ICCTO_CR,
388 .icc_mask = BIT(0),
389 .mask_reset_reg = LDOS_MASK_RESET_CR,
390 .mask_reset_mask = BIT(0),
391 },
392 [STPMIC1_LDO2] = {
393 .desc = REG_LDO(LDO2, ldo2),
394 .icc_reg = LDOS_ICCTO_CR,
395 .icc_mask = BIT(1),
396 .mask_reset_reg = LDOS_MASK_RESET_CR,
397 .mask_reset_mask = BIT(1),
398 },
399 [STPMIC1_LDO3] = {
400 .desc = REG_LDO3(LDO3, ldo3),
401 .icc_reg = LDOS_ICCTO_CR,
402 .icc_mask = BIT(2),
403 .mask_reset_reg = LDOS_MASK_RESET_CR,
404 .mask_reset_mask = BIT(2),
405 },
406 [STPMIC1_LDO4] = {
407 .desc = REG_LDO4(LDO4, ldo4),
408 .icc_reg = LDOS_ICCTO_CR,
409 .icc_mask = BIT(3),
410 .mask_reset_reg = LDOS_MASK_RESET_CR,
411 .mask_reset_mask = BIT(3),
412 },
413 [STPMIC1_LDO5] = {
414 .desc = REG_LDO(LDO5, ldo5),
415 .icc_reg = LDOS_ICCTO_CR,
416 .icc_mask = BIT(4),
417 .mask_reset_reg = LDOS_MASK_RESET_CR,
418 .mask_reset_mask = BIT(4),
419 },
420 [STPMIC1_LDO6] = {
421 .desc = REG_LDO(LDO6, ldo6),
422 .icc_reg = LDOS_ICCTO_CR,
423 .icc_mask = BIT(5),
424 .mask_reset_reg = LDOS_MASK_RESET_CR,
425 .mask_reset_mask = BIT(5),
426 },
427 [STPMIC1_VREF_DDR] = {
428 .desc = REG_VREF_DDR(VREF_DDR, vref_ddr),
429 .mask_reset_reg = LDOS_MASK_RESET_CR,
430 .mask_reset_mask = BIT(6),
431 },
432 [STPMIC1_BOOST] = {
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000433 .desc = REG_BOOST(BOOST, boost),
pascal pailletca55b712018-10-08 16:29:40 +0000434 .icc_reg = BUCKS_ICCTO_CR,
435 .icc_mask = BIT(6),
436 },
437 [STPMIC1_VBUS_OTG] = {
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000438 .desc = REG_VBUS_OTG(VBUS_OTG, pwr_sw1),
pascal pailletca55b712018-10-08 16:29:40 +0000439 .icc_reg = BUCKS_ICCTO_CR,
440 .icc_mask = BIT(4),
441 },
442 [STPMIC1_SW_OUT] = {
Pascal PAILLET-LMEe6fff622019-02-19 10:04:35 +0000443 .desc = REG_SW_OUT(SW_OUT, pwr_sw2),
pascal pailletca55b712018-10-08 16:29:40 +0000444 .icc_reg = BUCKS_ICCTO_CR,
445 .icc_mask = BIT(5),
446 },
447};
448
449static unsigned int stpmic1_map_mode(unsigned int mode)
450{
451 switch (mode) {
452 case STPMIC1_BUCK_MODE_NORMAL:
453 return REGULATOR_MODE_NORMAL;
454 case STPMIC1_BUCK_MODE_LP:
455 return REGULATOR_MODE_STANDBY;
456 default:
Axel Linc18fb342018-10-09 16:52:21 +0800457 return REGULATOR_MODE_INVALID;
pascal pailletca55b712018-10-08 16:29:40 +0000458 }
459}
460
461static unsigned int stpmic1_get_mode(struct regulator_dev *rdev)
462{
463 int value;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000464 struct regmap *regmap = rdev_get_regmap(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000465
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000466 regmap_read(regmap, rdev->desc->enable_reg, &value);
pascal pailletca55b712018-10-08 16:29:40 +0000467
468 if (value & STPMIC1_BUCK_MODE_LP)
469 return REGULATOR_MODE_STANDBY;
470
471 return REGULATOR_MODE_NORMAL;
472}
473
474static int stpmic1_set_mode(struct regulator_dev *rdev, unsigned int mode)
475{
476 int value;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000477 struct regmap *regmap = rdev_get_regmap(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000478
479 switch (mode) {
480 case REGULATOR_MODE_NORMAL:
481 value = STPMIC1_BUCK_MODE_NORMAL;
482 break;
483 case REGULATOR_MODE_STANDBY:
484 value = STPMIC1_BUCK_MODE_LP;
485 break;
486 default:
487 return -EINVAL;
488 }
489
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000490 return regmap_update_bits(regmap, rdev->desc->enable_reg,
pascal pailletca55b712018-10-08 16:29:40 +0000491 STPMIC1_BUCK_MODE_LP, value);
492}
493
494static int stpmic1_set_icc(struct regulator_dev *rdev)
495{
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000496 struct stpmic1_regulator_cfg *cfg = rdev_get_drvdata(rdev);
Axel Linef541f72019-02-14 09:59:56 +0800497 struct regmap *regmap = rdev_get_regmap(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000498
499 /* enable switch off in case of over current */
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000500 return regmap_update_bits(regmap, cfg->icc_reg, cfg->icc_mask,
501 cfg->icc_mask);
pascal pailletca55b712018-10-08 16:29:40 +0000502}
503
504static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
505{
506 struct regulator_dev *rdev = (struct regulator_dev *)data;
507
Pascal PAILLET-LMEdb6e6242018-11-30 09:55:51 +0000508 regulator_lock(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000509
510 /* Send an overcurrent notification */
511 regulator_notifier_call_chain(rdev,
512 REGULATOR_EVENT_OVER_CURRENT,
513 NULL);
514
Dmitry Osipenkof8702f92018-11-19 00:56:17 +0300515 regulator_unlock(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000516
517 return IRQ_HANDLED;
518}
519
pascal pailletca55b712018-10-08 16:29:40 +0000520#define MATCH(_name, _id) \
521 [STPMIC1_##_id] = { \
522 .name = #_name, \
523 .desc = &stpmic1_regulator_cfgs[STPMIC1_##_id].desc, \
524 }
525
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000526static struct of_regulator_match stpmic1_matches[] = {
pascal pailletca55b712018-10-08 16:29:40 +0000527 MATCH(buck1, BUCK1),
528 MATCH(buck2, BUCK2),
529 MATCH(buck3, BUCK3),
530 MATCH(buck4, BUCK4),
531 MATCH(ldo1, LDO1),
532 MATCH(ldo2, LDO2),
533 MATCH(ldo3, LDO3),
534 MATCH(ldo4, LDO4),
535 MATCH(ldo5, LDO5),
536 MATCH(ldo6, LDO6),
537 MATCH(vref_ddr, VREF_DDR),
538 MATCH(boost, BOOST),
539 MATCH(pwr_sw1, VBUS_OTG),
540 MATCH(pwr_sw2, SW_OUT),
541};
542
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000543static int stpmic1_regulator_register(struct platform_device *pdev, int id,
544 struct of_regulator_match *match,
545 const struct stpmic1_regulator_cfg *cfg)
pascal pailletca55b712018-10-08 16:29:40 +0000546{
547 struct stpmic1 *pmic_dev = dev_get_drvdata(pdev->dev.parent);
548 struct regulator_dev *rdev;
549 struct regulator_config config = {};
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000550 int ret = 0;
551 int irq;
pascal pailletca55b712018-10-08 16:29:40 +0000552
553 config.dev = &pdev->dev;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000554 config.init_data = match->init_data;
555 config.of_node = match->of_node;
pascal pailletca55b712018-10-08 16:29:40 +0000556 config.regmap = pmic_dev->regmap;
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000557 config.driver_data = (void *)cfg;
pascal pailletca55b712018-10-08 16:29:40 +0000558
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000559 rdev = devm_regulator_register(&pdev->dev, &cfg->desc, &config);
pascal pailletca55b712018-10-08 16:29:40 +0000560 if (IS_ERR(rdev)) {
561 dev_err(&pdev->dev, "failed to register %s regulator\n",
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000562 cfg->desc.name);
563 return PTR_ERR(rdev);
pascal pailletca55b712018-10-08 16:29:40 +0000564 }
565
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000566 /* set mask reset */
567 if (of_get_property(config.of_node, "st,mask-reset", NULL) &&
568 cfg->mask_reset_reg != 0) {
569 ret = regmap_update_bits(pmic_dev->regmap,
570 cfg->mask_reset_reg,
571 cfg->mask_reset_mask,
572 cfg->mask_reset_mask);
573 if (ret) {
574 dev_err(&pdev->dev, "set mask reset failed\n");
575 return ret;
576 }
577 }
578
579 /* setup an irq handler for over-current detection */
580 irq = of_irq_get(config.of_node, 0);
581 if (irq > 0) {
582 ret = devm_request_threaded_irq(&pdev->dev,
583 irq, NULL,
584 stpmic1_curlim_irq_handler,
585 IRQF_ONESHOT | IRQF_SHARED,
586 pdev->name, rdev);
587 if (ret) {
588 dev_err(&pdev->dev, "Request IRQ failed\n");
589 return ret;
590 }
591 }
592 return 0;
pascal pailletca55b712018-10-08 16:29:40 +0000593}
594
595static int stpmic1_regulator_probe(struct platform_device *pdev)
596{
pascal pailletca55b712018-10-08 16:29:40 +0000597 int i, ret;
598
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000599 ret = of_regulator_match(&pdev->dev, pdev->dev.of_node, stpmic1_matches,
600 ARRAY_SIZE(stpmic1_matches));
pascal pailletca55b712018-10-08 16:29:40 +0000601 if (ret < 0) {
602 dev_err(&pdev->dev,
603 "Error in PMIC regulator device tree node");
604 return ret;
605 }
606
pascal pailletca55b712018-10-08 16:29:40 +0000607 for (i = 0; i < ARRAY_SIZE(stpmic1_regulator_cfgs); i++) {
Pascal PAILLET-LME8c44e442019-02-19 10:04:32 +0000608 ret = stpmic1_regulator_register(pdev, i, &stpmic1_matches[i],
609 &stpmic1_regulator_cfgs[i]);
610 if (ret < 0)
pascal pailletca55b712018-10-08 16:29:40 +0000611 return ret;
pascal pailletca55b712018-10-08 16:29:40 +0000612 }
613
614 dev_dbg(&pdev->dev, "stpmic1_regulator driver probed\n");
615
616 return 0;
617}
618
619static const struct of_device_id of_pmic_regulator_match[] = {
620 { .compatible = "st,stpmic1-regulators" },
621 { },
622};
623
624MODULE_DEVICE_TABLE(of, of_pmic_regulator_match);
625
626static struct platform_driver stpmic1_regulator_driver = {
627 .driver = {
628 .name = "stpmic1-regulator",
629 .of_match_table = of_match_ptr(of_pmic_regulator_match),
630 },
631 .probe = stpmic1_regulator_probe,
632};
633
634module_platform_driver(stpmic1_regulator_driver);
635
636MODULE_DESCRIPTION("STPMIC1 PMIC voltage regulator driver");
637MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
638MODULE_LICENSE("GPL v2");