blob: 714d532326ec5d8be762f7a2b9f8de56b3d53f78 [file] [log] [blame]
Yann Gautiere4f559f2018-07-16 17:55:07 +02001/*
Yann Gautiered6a8522020-03-23 17:44:30 +01002 * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved
Yann Gautiere4f559f2018-07-16 17:55:07 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautiered6a8522020-03-23 17:44:30 +01007#include <errno.h>
Yann Gautiere4f559f2018-07-16 17:55:07 +02008#include <string.h>
9
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000010#include <common/debug.h>
Yann Gautier23684d02019-01-16 18:31:00 +010011#include <drivers/st/stpmic1.h>
Yann Gautierd82d4ff2019-02-14 11:15:03 +010012
13#define I2C_TIMEOUT_MS 25
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000014
Yann Gautiere4f559f2018-07-16 17:55:07 +020015struct regul_struct {
16 const char *dt_node_name;
17 const uint16_t *voltage_table;
18 uint8_t voltage_table_size;
19 uint8_t control_reg;
Pascal Paillet01619912021-03-10 14:37:03 +010020 uint8_t enable_mask;
Yann Gautiere4f559f2018-07-16 17:55:07 +020021 uint8_t low_power_reg;
Yann Gautier077f6822019-01-17 14:27:50 +010022 uint8_t pull_down_reg;
23 uint8_t pull_down;
24 uint8_t mask_reset_reg;
25 uint8_t mask_reset;
Yann Gautiere4f559f2018-07-16 17:55:07 +020026};
27
Yann Gautier23684d02019-01-16 18:31:00 +010028static struct i2c_handle_s *pmic_i2c_handle;
29static uint16_t pmic_i2c_addr;
Yann Gautiere4f559f2018-07-16 17:55:07 +020030
31/* Voltage tables in mV */
32static const uint16_t buck1_voltage_table[] = {
Yann Gautier077f6822019-01-17 14:27:50 +010033 725,
34 725,
35 725,
36 725,
37 725,
Yann Gautiere4f559f2018-07-16 17:55:07 +020038 725,
39 750,
40 775,
41 800,
42 825,
43 850,
44 875,
45 900,
46 925,
47 950,
48 975,
49 1000,
50 1025,
51 1050,
52 1075,
53 1100,
54 1125,
55 1150,
56 1175,
57 1200,
58 1225,
59 1250,
60 1275,
61 1300,
62 1325,
63 1350,
Yann Gautier077f6822019-01-17 14:27:50 +010064 1375,
65 1400,
66 1425,
67 1450,
68 1475,
69 1500,
70 1500,
71 1500,
72 1500,
73 1500,
74 1500,
75 1500,
76 1500,
77 1500,
78 1500,
79 1500,
80 1500,
81 1500,
82 1500,
83 1500,
84 1500,
85 1500,
86 1500,
87 1500,
88 1500,
89 1500,
90 1500,
91 1500,
92 1500,
93 1500,
94 1500,
95 1500,
96 1500,
Yann Gautiere4f559f2018-07-16 17:55:07 +020097};
98
99static const uint16_t buck2_voltage_table[] = {
100 1000,
101 1000,
102 1000,
103 1000,
104 1000,
105 1000,
106 1000,
107 1000,
108 1000,
109 1000,
110 1000,
111 1000,
112 1000,
113 1000,
114 1000,
115 1000,
116 1000,
117 1000,
118 1050,
119 1050,
120 1100,
121 1100,
122 1150,
123 1150,
124 1200,
125 1200,
126 1250,
127 1250,
128 1300,
129 1300,
130 1350,
131 1350,
132 1400,
133 1400,
134 1450,
135 1450,
136 1500,
137};
138
139static const uint16_t buck3_voltage_table[] = {
140 1000,
141 1000,
142 1000,
143 1000,
144 1000,
145 1000,
146 1000,
147 1000,
148 1000,
149 1000,
150 1000,
151 1000,
152 1000,
153 1000,
154 1000,
155 1000,
156 1000,
157 1000,
158 1000,
159 1000,
160 1100,
161 1100,
162 1100,
163 1100,
164 1200,
165 1200,
166 1200,
167 1200,
168 1300,
169 1300,
170 1300,
171 1300,
172 1400,
173 1400,
174 1400,
175 1400,
176 1500,
177 1600,
178 1700,
179 1800,
180 1900,
181 2000,
182 2100,
183 2200,
184 2300,
185 2400,
186 2500,
187 2600,
188 2700,
189 2800,
190 2900,
191 3000,
192 3100,
193 3200,
194 3300,
195 3400,
196};
197
198static const uint16_t buck4_voltage_table[] = {
199 600,
200 625,
201 650,
202 675,
203 700,
204 725,
205 750,
206 775,
207 800,
208 825,
209 850,
210 875,
211 900,
212 925,
213 950,
214 975,
215 1000,
216 1025,
217 1050,
218 1075,
219 1100,
220 1125,
221 1150,
222 1175,
223 1200,
224 1225,
225 1250,
226 1275,
227 1300,
228 1300,
229 1350,
230 1350,
231 1400,
232 1400,
233 1450,
234 1450,
235 1500,
236 1600,
237 1700,
238 1800,
239 1900,
240 2000,
241 2100,
242 2200,
243 2300,
244 2400,
245 2500,
246 2600,
247 2700,
248 2800,
249 2900,
250 3000,
251 3100,
252 3200,
253 3300,
254 3400,
255 3500,
256 3600,
257 3700,
258 3800,
259 3900,
260};
261
262static const uint16_t ldo1_voltage_table[] = {
263 1700,
264 1700,
265 1700,
266 1700,
267 1700,
268 1700,
269 1700,
270 1700,
271 1700,
272 1800,
273 1900,
274 2000,
275 2100,
276 2200,
277 2300,
278 2400,
279 2500,
280 2600,
281 2700,
282 2800,
283 2900,
284 3000,
285 3100,
286 3200,
287 3300,
288};
289
290static const uint16_t ldo2_voltage_table[] = {
291 1700,
292 1700,
293 1700,
294 1700,
295 1700,
296 1700,
297 1700,
298 1700,
299 1700,
300 1800,
301 1900,
302 2000,
303 2100,
304 2200,
305 2300,
306 2400,
307 2500,
308 2600,
309 2700,
310 2800,
311 2900,
312 3000,
313 3100,
314 3200,
315 3300,
316};
317
318static const uint16_t ldo3_voltage_table[] = {
319 1700,
320 1700,
321 1700,
322 1700,
323 1700,
324 1700,
325 1700,
326 1700,
327 1700,
328 1800,
329 1900,
330 2000,
331 2100,
332 2200,
333 2300,
334 2400,
335 2500,
336 2600,
337 2700,
338 2800,
339 2900,
340 3000,
341 3100,
342 3200,
343 3300,
344 3300,
345 3300,
346 3300,
347 3300,
348 3300,
349 3300,
Yann Gautier077f6822019-01-17 14:27:50 +0100350 500,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200351 0xFFFF, /* VREFDDR */
352};
353
354static const uint16_t ldo5_voltage_table[] = {
355 1700,
356 1700,
357 1700,
358 1700,
359 1700,
360 1700,
361 1700,
362 1700,
363 1700,
364 1800,
365 1900,
366 2000,
367 2100,
368 2200,
369 2300,
370 2400,
371 2500,
372 2600,
373 2700,
374 2800,
375 2900,
376 3000,
377 3100,
378 3200,
379 3300,
380 3400,
381 3500,
382 3600,
383 3700,
384 3800,
385 3900,
386};
387
388static const uint16_t ldo6_voltage_table[] = {
389 900,
390 1000,
391 1100,
392 1200,
393 1300,
394 1400,
395 1500,
396 1600,
397 1700,
398 1800,
399 1900,
400 2000,
401 2100,
402 2200,
403 2300,
404 2400,
405 2500,
406 2600,
407 2700,
408 2800,
409 2900,
410 3000,
411 3100,
412 3200,
413 3300,
414};
415
416static const uint16_t ldo4_voltage_table[] = {
417 3300,
418};
419
420static const uint16_t vref_ddr_voltage_table[] = {
421 3300,
422};
423
Etienne Carriere13fbfe02020-01-10 08:31:13 +0100424static const uint16_t fixed_5v_voltage_table[] = {
425 5000,
426};
427
Yann Gautiere4f559f2018-07-16 17:55:07 +0200428/* Table of Regulators in PMIC SoC */
429static const struct regul_struct regulators_table[] = {
430 {
431 .dt_node_name = "buck1",
432 .voltage_table = buck1_voltage_table,
433 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
434 .control_reg = BUCK1_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100435 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200436 .low_power_reg = BUCK1_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100437 .pull_down_reg = BUCK_PULL_DOWN_REG,
438 .pull_down = BUCK1_PULL_DOWN_SHIFT,
439 .mask_reset_reg = MASK_RESET_BUCK_REG,
440 .mask_reset = BUCK1_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200441 },
442 {
443 .dt_node_name = "buck2",
444 .voltage_table = buck2_voltage_table,
445 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
446 .control_reg = BUCK2_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100447 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200448 .low_power_reg = BUCK2_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100449 .pull_down_reg = BUCK_PULL_DOWN_REG,
450 .pull_down = BUCK2_PULL_DOWN_SHIFT,
451 .mask_reset_reg = MASK_RESET_BUCK_REG,
452 .mask_reset = BUCK2_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200453 },
454 {
455 .dt_node_name = "buck3",
456 .voltage_table = buck3_voltage_table,
457 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
458 .control_reg = BUCK3_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100459 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200460 .low_power_reg = BUCK3_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100461 .pull_down_reg = BUCK_PULL_DOWN_REG,
462 .pull_down = BUCK3_PULL_DOWN_SHIFT,
463 .mask_reset_reg = MASK_RESET_BUCK_REG,
464 .mask_reset = BUCK3_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200465 },
466 {
467 .dt_node_name = "buck4",
468 .voltage_table = buck4_voltage_table,
469 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
470 .control_reg = BUCK4_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100471 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200472 .low_power_reg = BUCK4_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100473 .pull_down_reg = BUCK_PULL_DOWN_REG,
474 .pull_down = BUCK4_PULL_DOWN_SHIFT,
475 .mask_reset_reg = MASK_RESET_BUCK_REG,
476 .mask_reset = BUCK4_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200477 },
478 {
479 .dt_node_name = "ldo1",
480 .voltage_table = ldo1_voltage_table,
481 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
482 .control_reg = LDO1_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100483 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200484 .low_power_reg = LDO1_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100485 .mask_reset_reg = MASK_RESET_LDO_REG,
486 .mask_reset = LDO1_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200487 },
488 {
489 .dt_node_name = "ldo2",
490 .voltage_table = ldo2_voltage_table,
491 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
492 .control_reg = LDO2_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100493 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200494 .low_power_reg = LDO2_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100495 .mask_reset_reg = MASK_RESET_LDO_REG,
496 .mask_reset = LDO2_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200497 },
498 {
499 .dt_node_name = "ldo3",
500 .voltage_table = ldo3_voltage_table,
501 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
502 .control_reg = LDO3_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100503 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200504 .low_power_reg = LDO3_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100505 .mask_reset_reg = MASK_RESET_LDO_REG,
506 .mask_reset = LDO3_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200507 },
508 {
509 .dt_node_name = "ldo4",
510 .voltage_table = ldo4_voltage_table,
511 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
512 .control_reg = LDO4_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100513 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200514 .low_power_reg = LDO4_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100515 .mask_reset_reg = MASK_RESET_LDO_REG,
516 .mask_reset = LDO4_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200517 },
518 {
519 .dt_node_name = "ldo5",
520 .voltage_table = ldo5_voltage_table,
521 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
522 .control_reg = LDO5_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100523 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200524 .low_power_reg = LDO5_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100525 .mask_reset_reg = MASK_RESET_LDO_REG,
526 .mask_reset = LDO5_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200527 },
528 {
529 .dt_node_name = "ldo6",
530 .voltage_table = ldo6_voltage_table,
531 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
532 .control_reg = LDO6_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100533 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200534 .low_power_reg = LDO6_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100535 .mask_reset_reg = MASK_RESET_LDO_REG,
536 .mask_reset = LDO6_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200537 },
538 {
539 .dt_node_name = "vref_ddr",
540 .voltage_table = vref_ddr_voltage_table,
541 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
542 .control_reg = VREF_DDR_CONTROL_REG,
Pascal Paillet01619912021-03-10 14:37:03 +0100543 .enable_mask = LDO_BUCK_ENABLE_MASK,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200544 .low_power_reg = VREF_DDR_PWRCTRL_REG,
Yann Gautier077f6822019-01-17 14:27:50 +0100545 .mask_reset_reg = MASK_RESET_LDO_REG,
546 .mask_reset = VREF_DDR_MASK_RESET,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200547 },
Etienne Carriere13fbfe02020-01-10 08:31:13 +0100548 {
549 .dt_node_name = "boost",
550 .voltage_table = fixed_5v_voltage_table,
551 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
552 .control_reg = USB_CONTROL_REG,
553 .enable_mask = BOOST_ENABLED,
554 },
555 {
556 .dt_node_name = "pwr_sw1",
557 .voltage_table = fixed_5v_voltage_table,
558 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
559 .control_reg = USB_CONTROL_REG,
560 .enable_mask = USBSW_OTG_SWITCH_ENABLED,
561 },
562 {
563 .dt_node_name = "pwr_sw2",
564 .voltage_table = fixed_5v_voltage_table,
565 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
566 .control_reg = USB_CONTROL_REG,
567 .enable_mask = SWIN_SWOUT_ENABLED,
568 },
Yann Gautiere4f559f2018-07-16 17:55:07 +0200569};
570
Yann Gautier23684d02019-01-16 18:31:00 +0100571#define MAX_REGUL ARRAY_SIZE(regulators_table)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200572
Yann Gautier23684d02019-01-16 18:31:00 +0100573static const struct regul_struct *get_regulator_data(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200574{
575 uint8_t i;
576
577 for (i = 0 ; i < MAX_REGUL ; i++) {
578 if (strncmp(name, regulators_table[i].dt_node_name,
579 strlen(regulators_table[i].dt_node_name)) == 0) {
580 return &regulators_table[i];
581 }
582 }
583
584 /* Regulator not found */
585 panic();
586 return NULL;
587}
588
Yann Gautier23684d02019-01-16 18:31:00 +0100589static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200590{
Yann Gautier23684d02019-01-16 18:31:00 +0100591 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200592 uint8_t i;
593
594 for (i = 0 ; i < regul->voltage_table_size ; i++) {
595 if (regul->voltage_table[i] == millivolts) {
596 return i;
597 }
598 }
599
600 /* Voltage not found */
601 panic();
602
603 return 0;
604}
605
Yann Gautier077f6822019-01-17 14:27:50 +0100606int stpmic1_powerctrl_on(void)
607{
608 return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
609 PWRCTRL_PIN_VALID);
610}
611
Yann Gautier23684d02019-01-16 18:31:00 +0100612int stpmic1_switch_off(void)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200613{
Yann Gautier23684d02019-01-16 18:31:00 +0100614 return stpmic1_register_update(MAIN_CONTROL_REG, 1,
615 SOFTWARE_SWITCH_OFF_ENABLED);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200616}
617
Yann Gautier23684d02019-01-16 18:31:00 +0100618int stpmic1_regulator_enable(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200619{
Yann Gautier23684d02019-01-16 18:31:00 +0100620 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200621
Pascal Paillet01619912021-03-10 14:37:03 +0100622 return stpmic1_register_update(regul->control_reg, regul->enable_mask,
623 regul->enable_mask);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200624}
625
Yann Gautier23684d02019-01-16 18:31:00 +0100626int stpmic1_regulator_disable(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200627{
Yann Gautier23684d02019-01-16 18:31:00 +0100628 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200629
Pascal Paillet01619912021-03-10 14:37:03 +0100630 return stpmic1_register_update(regul->control_reg, 0,
631 regul->enable_mask);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200632}
633
Nicolas Le Bayon16e56a72019-09-19 11:24:50 +0200634bool stpmic1_is_regulator_enabled(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200635{
636 uint8_t val;
Yann Gautier23684d02019-01-16 18:31:00 +0100637 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200638
Yann Gautier23684d02019-01-16 18:31:00 +0100639 if (stpmic1_register_read(regul->control_reg, &val) != 0) {
Yann Gautiere4f559f2018-07-16 17:55:07 +0200640 panic();
641 }
642
Nicolas Le Bayon16e56a72019-09-19 11:24:50 +0200643 return (val & regul->enable_mask) == regul->enable_mask;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200644}
645
Yann Gautier23684d02019-01-16 18:31:00 +0100646int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200647{
Yann Gautier23684d02019-01-16 18:31:00 +0100648 uint8_t voltage_index = voltage_to_index(name, millivolts);
649 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautier077f6822019-01-17 14:27:50 +0100650 uint8_t mask;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200651
Yann Gautier077f6822019-01-17 14:27:50 +0100652 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
653 if (strncmp(name, "buck", 4) == 0) {
654 mask = BUCK_VOLTAGE_MASK;
655 } else if ((strncmp(name, "ldo", 3) == 0) &&
656 (strncmp(name, "ldo4", 4) != 0)) {
657 mask = LDO_VOLTAGE_MASK;
658 } else {
659 return 0;
660 }
661
662 return stpmic1_register_update(regul->control_reg,
663 voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
664 mask);
665}
666
667int stpmic1_regulator_pull_down_set(const char *name)
668{
669 const struct regul_struct *regul = get_regulator_data(name);
670
671 if (regul->pull_down_reg != 0) {
672 return stpmic1_register_update(regul->pull_down_reg,
673 BIT(regul->pull_down),
674 LDO_BUCK_PULL_DOWN_MASK <<
675 regul->pull_down);
676 }
677
678 return 0;
679}
680
681int stpmic1_regulator_mask_reset_set(const char *name)
682{
683 const struct regul_struct *regul = get_regulator_data(name);
684
685 return stpmic1_register_update(regul->mask_reset_reg,
686 BIT(regul->mask_reset),
687 LDO_BUCK_RESET_MASK <<
688 regul->mask_reset);
689}
690
691int stpmic1_regulator_voltage_get(const char *name)
692{
693 const struct regul_struct *regul = get_regulator_data(name);
694 uint8_t value;
695 uint8_t mask;
Yann Gautiered6a8522020-03-23 17:44:30 +0100696 int status;
Yann Gautier077f6822019-01-17 14:27:50 +0100697
698 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
699 if (strncmp(name, "buck", 4) == 0) {
700 mask = BUCK_VOLTAGE_MASK;
701 } else if ((strncmp(name, "ldo", 3) == 0) &&
702 (strncmp(name, "ldo4", 4) != 0)) {
703 mask = LDO_VOLTAGE_MASK;
704 } else {
705 return 0;
706 }
707
Yann Gautiered6a8522020-03-23 17:44:30 +0100708 status = stpmic1_register_read(regul->control_reg, &value);
709 if (status < 0) {
710 return status;
711 }
Yann Gautier077f6822019-01-17 14:27:50 +0100712
713 value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
714
Yann Gautiered6a8522020-03-23 17:44:30 +0100715 if (value > regul->voltage_table_size) {
716 return -ERANGE;
717 }
Yann Gautier077f6822019-01-17 14:27:50 +0100718
719 return (int)regul->voltage_table[value];
Yann Gautiere4f559f2018-07-16 17:55:07 +0200720}
721
Yann Gautier23684d02019-01-16 18:31:00 +0100722int stpmic1_register_read(uint8_t register_id, uint8_t *value)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200723{
Yann Gautier23684d02019-01-16 18:31:00 +0100724 return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100725 (uint16_t)register_id,
726 I2C_MEMADD_SIZE_8BIT, value,
727 1, I2C_TIMEOUT_MS);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200728}
729
Yann Gautier23684d02019-01-16 18:31:00 +0100730int stpmic1_register_write(uint8_t register_id, uint8_t value)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200731{
732 int status;
733
Yann Gautier23684d02019-01-16 18:31:00 +0100734 status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200735 (uint16_t)register_id,
Yann Gautierd82d4ff2019-02-14 11:15:03 +0100736 I2C_MEMADD_SIZE_8BIT, &value,
737 1, I2C_TIMEOUT_MS);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200738
Yann Gautier077f6822019-01-17 14:27:50 +0100739#if ENABLE_ASSERTIONS
Yann Gautiere4f559f2018-07-16 17:55:07 +0200740 if (status != 0) {
741 return status;
742 }
743
744 if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
745 uint8_t readval;
746
Yann Gautier23684d02019-01-16 18:31:00 +0100747 status = stpmic1_register_read(register_id, &readval);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200748 if (status != 0) {
749 return status;
750 }
751
752 if (readval != value) {
Yann Gautiered6a8522020-03-23 17:44:30 +0100753 return -EIO;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200754 }
755 }
Yann Gautier077f6822019-01-17 14:27:50 +0100756#endif
Yann Gautiere4f559f2018-07-16 17:55:07 +0200757
Yann Gautier077f6822019-01-17 14:27:50 +0100758 return status;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200759}
760
Yann Gautier23684d02019-01-16 18:31:00 +0100761int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200762{
763 int status;
764 uint8_t val;
765
Yann Gautier23684d02019-01-16 18:31:00 +0100766 status = stpmic1_register_read(register_id, &val);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200767 if (status != 0) {
768 return status;
769 }
770
Yann Gautier077f6822019-01-17 14:27:50 +0100771 val = (val & ~mask) | (value & mask);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200772
Yann Gautier23684d02019-01-16 18:31:00 +0100773 return stpmic1_register_write(register_id, val);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200774}
775
Yann Gautier23684d02019-01-16 18:31:00 +0100776void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200777{
Yann Gautier23684d02019-01-16 18:31:00 +0100778 pmic_i2c_handle = i2c_handle;
779 pmic_i2c_addr = i2c_addr;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200780}
Yann Gautier077f6822019-01-17 14:27:50 +0100781
782void stpmic1_dump_regulators(void)
783{
784 uint32_t i;
785
786 for (i = 0U; i < MAX_REGUL; i++) {
787 const char *name __unused = regulators_table[i].dt_node_name;
788
789 VERBOSE("PMIC regul %s: %sable, %dmV",
790 name,
791 stpmic1_is_regulator_enabled(name) ? "en" : "dis",
792 stpmic1_regulator_voltage_get(name));
793 }
794}
795
796int stpmic1_get_version(unsigned long *version)
797{
Yann Gautier077f6822019-01-17 14:27:50 +0100798 uint8_t read_val;
Yann Gautiered6a8522020-03-23 17:44:30 +0100799 int status;
Yann Gautier077f6822019-01-17 14:27:50 +0100800
Yann Gautiered6a8522020-03-23 17:44:30 +0100801 status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
802 if (status < 0) {
803 return status;
Yann Gautier077f6822019-01-17 14:27:50 +0100804 }
805
806 *version = (unsigned long)read_val;
807
808 return 0;
809}