1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
4 */
5
6 #include <assert.h>
7 #include <drivers/stpmic1.h>
8 #include <drivers/stpmic1_regulator.h>
9 #include <kernel/panic.h>
10 #include <platform_config.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <trace.h>
14 #include <util.h>
15
16 #define VOLTAGE_INDEX_INVALID ((unsigned int)~0)
17
18 struct regul_struct {
19 const char *dt_node_name;
20 const uint16_t *voltage_table;
21 uint8_t voltage_table_size;
22 uint8_t control_reg;
23 uint8_t low_power_reg;
24 uint8_t enable_pos;
25 uint8_t pull_down_reg;
26 uint8_t pull_down_pos;
27 uint8_t mask_reset_reg;
28 uint8_t mask_reset_pos;
29 };
30
31 static struct i2c_handle_s *pmic_i2c_handle;
32 static uint16_t pmic_i2c_addr;
33
34 /* Voltage tables in mV */
35 static const uint16_t buck1_voltage_table[] = {
36 725,
37 725,
38 725,
39 725,
40 725,
41 725,
42 750,
43 775,
44 800,
45 825,
46 850,
47 875,
48 900,
49 925,
50 950,
51 975,
52 1000,
53 1025,
54 1050,
55 1075,
56 1100,
57 1125,
58 1150,
59 1175,
60 1200,
61 1225,
62 1250,
63 1275,
64 1300,
65 1325,
66 1350,
67 1375,
68 1400,
69 1425,
70 1450,
71 1475,
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,
97 1500,
98 1500,
99 1500,
100 };
101
102 static const uint16_t buck2_voltage_table[] = {
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 1000,
119 1000,
120 1000,
121 1050,
122 1050,
123 1100,
124 1100,
125 1150,
126 1150,
127 1200,
128 1200,
129 1250,
130 1250,
131 1300,
132 1300,
133 1350,
134 1350,
135 1400,
136 1400,
137 1450,
138 1450,
139 1500,
140 };
141
142 static const uint16_t buck3_voltage_table[] = {
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 1000,
161 1000,
162 1000,
163 1100,
164 1100,
165 1100,
166 1100,
167 1200,
168 1200,
169 1200,
170 1200,
171 1300,
172 1300,
173 1300,
174 1300,
175 1400,
176 1400,
177 1400,
178 1400,
179 1500,
180 1600,
181 1700,
182 1800,
183 1900,
184 2000,
185 2100,
186 2200,
187 2300,
188 2400,
189 2500,
190 2600,
191 2700,
192 2800,
193 2900,
194 3000,
195 3100,
196 3200,
197 3300,
198 3400,
199 };
200
201 static const uint16_t buck4_voltage_table[] = {
202 600,
203 625,
204 650,
205 675,
206 700,
207 725,
208 750,
209 775,
210 800,
211 825,
212 850,
213 875,
214 900,
215 925,
216 950,
217 975,
218 1000,
219 1025,
220 1050,
221 1075,
222 1100,
223 1125,
224 1150,
225 1175,
226 1200,
227 1225,
228 1250,
229 1275,
230 1300,
231 1300,
232 1350,
233 1350,
234 1400,
235 1400,
236 1450,
237 1450,
238 1500,
239 1600,
240 1700,
241 1800,
242 1900,
243 2000,
244 2100,
245 2200,
246 2300,
247 2400,
248 2500,
249 2600,
250 2700,
251 2800,
252 2900,
253 3000,
254 3100,
255 3200,
256 3300,
257 3400,
258 3500,
259 3600,
260 3700,
261 3800,
262 3900,
263 };
264
265 static const uint16_t ldo1_voltage_table[] = {
266 1700,
267 1700,
268 1700,
269 1700,
270 1700,
271 1700,
272 1700,
273 1700,
274 1700,
275 1800,
276 1900,
277 2000,
278 2100,
279 2200,
280 2300,
281 2400,
282 2500,
283 2600,
284 2700,
285 2800,
286 2900,
287 3000,
288 3100,
289 3200,
290 3300,
291 };
292
293 static const uint16_t ldo2_voltage_table[] = {
294 1700,
295 1700,
296 1700,
297 1700,
298 1700,
299 1700,
300 1700,
301 1700,
302 1700,
303 1800,
304 1900,
305 2000,
306 2100,
307 2200,
308 2300,
309 2400,
310 2500,
311 2600,
312 2700,
313 2800,
314 2900,
315 3000,
316 3100,
317 3200,
318 3300,
319 };
320
321 static const uint16_t ldo3_voltage_table[] = {
322 1700,
323 1700,
324 1700,
325 1700,
326 1700,
327 1700,
328 1700,
329 1700,
330 1700,
331 1800,
332 1900,
333 2000,
334 2100,
335 2200,
336 2300,
337 2400,
338 2500,
339 2600,
340 2700,
341 2800,
342 2900,
343 3000,
344 3100,
345 3200,
346 3300,
347 3300,
348 3300,
349 3300,
350 3300,
351 3300,
352 3300,
353 500, /* VOUT2/2 (Sink/source mode) */
354 0xFFFF, /* VREFDDR */
355 };
356
357 static const uint16_t ldo5_voltage_table[] = {
358 1700,
359 1700,
360 1700,
361 1700,
362 1700,
363 1700,
364 1700,
365 1700,
366 1700,
367 1800,
368 1900,
369 2000,
370 2100,
371 2200,
372 2300,
373 2400,
374 2500,
375 2600,
376 2700,
377 2800,
378 2900,
379 3000,
380 3100,
381 3200,
382 3300,
383 3400,
384 3500,
385 3600,
386 3700,
387 3800,
388 3900,
389 };
390
391 static const uint16_t ldo6_voltage_table[] = {
392 900,
393 1000,
394 1100,
395 1200,
396 1300,
397 1400,
398 1500,
399 1600,
400 1700,
401 1800,
402 1900,
403 2000,
404 2100,
405 2200,
406 2300,
407 2400,
408 2500,
409 2600,
410 2700,
411 2800,
412 2900,
413 3000,
414 3100,
415 3200,
416 3300,
417 };
418
419 static const uint16_t ldo4_voltage_table[] = {
420 3300,
421 };
422
423 static const uint16_t vref_ddr_voltage_table[] = {
424 3300,
425 };
426
427 static const uint16_t fixed_5v_voltage_table[] = {
428 5000,
429 };
430
431 /* Table of Regulators in PMIC SoC */
432 static const struct regul_struct regulators_table[] = {
433 {
434 .dt_node_name = "buck1",
435 .voltage_table = buck1_voltage_table,
436 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
437 .control_reg = BUCK1_CONTROL_REG,
438 .low_power_reg = BUCK1_PWRCTRL_REG,
439 .enable_pos = LDO_BUCK_ENABLE_POS,
440 .pull_down_reg = BUCK_PULL_DOWN_REG,
441 .pull_down_pos = BUCK1_PULL_DOWN_SHIFT,
442 .mask_reset_reg = MASK_RESET_BUCK_REG,
443 .mask_reset_pos = BUCK1_MASK_RESET_SHIFT,
444 },
445 {
446 .dt_node_name = "buck2",
447 .voltage_table = buck2_voltage_table,
448 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
449 .control_reg = BUCK2_CONTROL_REG,
450 .low_power_reg = BUCK2_PWRCTRL_REG,
451 .enable_pos = LDO_BUCK_ENABLE_POS,
452 .pull_down_reg = BUCK_PULL_DOWN_REG,
453 .pull_down_pos = BUCK2_PULL_DOWN_SHIFT,
454 .mask_reset_reg = MASK_RESET_BUCK_REG,
455 .mask_reset_pos = BUCK2_MASK_RESET_SHIFT,
456 },
457 {
458 .dt_node_name = "buck3",
459 .voltage_table = buck3_voltage_table,
460 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
461 .control_reg = BUCK3_CONTROL_REG,
462 .low_power_reg = BUCK3_PWRCTRL_REG,
463 .enable_pos = LDO_BUCK_ENABLE_POS,
464 .pull_down_reg = BUCK_PULL_DOWN_REG,
465 .pull_down_pos = BUCK3_PULL_DOWN_SHIFT,
466 .mask_reset_reg = MASK_RESET_BUCK_REG,
467 .mask_reset_pos = BUCK3_MASK_RESET_SHIFT,
468 },
469 {
470 .dt_node_name = "buck4",
471 .voltage_table = buck4_voltage_table,
472 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
473 .control_reg = BUCK4_CONTROL_REG,
474 .low_power_reg = BUCK4_PWRCTRL_REG,
475 .enable_pos = LDO_BUCK_ENABLE_POS,
476 .pull_down_reg = BUCK_PULL_DOWN_REG,
477 .pull_down_pos = BUCK4_PULL_DOWN_SHIFT,
478 .mask_reset_reg = MASK_RESET_BUCK_REG,
479 .mask_reset_pos = BUCK4_MASK_RESET_SHIFT,
480 },
481 {
482 .dt_node_name = "ldo1",
483 .voltage_table = ldo1_voltage_table,
484 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
485 .control_reg = LDO1_CONTROL_REG,
486 .low_power_reg = LDO1_PWRCTRL_REG,
487 .enable_pos = LDO_BUCK_ENABLE_POS,
488 .mask_reset_reg = MASK_RESET_LDO_REG,
489 .mask_reset_pos = LDO1_MASK_RESET_SHIFT,
490 },
491 {
492 .dt_node_name = "ldo2",
493 .voltage_table = ldo2_voltage_table,
494 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
495 .control_reg = LDO2_CONTROL_REG,
496 .low_power_reg = LDO2_PWRCTRL_REG,
497 .enable_pos = LDO_BUCK_ENABLE_POS,
498 .mask_reset_reg = MASK_RESET_LDO_REG,
499 .mask_reset_pos = LDO2_MASK_RESET_SHIFT,
500 },
501 {
502 .dt_node_name = "ldo3",
503 .voltage_table = ldo3_voltage_table,
504 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
505 .control_reg = LDO3_CONTROL_REG,
506 .low_power_reg = LDO3_PWRCTRL_REG,
507 .enable_pos = LDO_BUCK_ENABLE_POS,
508 .mask_reset_reg = MASK_RESET_LDO_REG,
509 .mask_reset_pos = LDO3_MASK_RESET_SHIFT,
510 },
511 {
512 .dt_node_name = "ldo4",
513 .voltage_table = ldo4_voltage_table,
514 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
515 .control_reg = LDO4_CONTROL_REG,
516 .low_power_reg = LDO4_PWRCTRL_REG,
517 .enable_pos = LDO_BUCK_ENABLE_POS,
518 .mask_reset_reg = MASK_RESET_LDO_REG,
519 .mask_reset_pos = LDO4_MASK_RESET_SHIFT,
520 },
521 {
522 .dt_node_name = "ldo5",
523 .voltage_table = ldo5_voltage_table,
524 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
525 .control_reg = LDO5_CONTROL_REG,
526 .low_power_reg = LDO5_PWRCTRL_REG,
527 .enable_pos = LDO_BUCK_ENABLE_POS,
528 .mask_reset_reg = MASK_RESET_LDO_REG,
529 .mask_reset_pos = LDO5_MASK_RESET_SHIFT,
530 },
531 {
532 .dt_node_name = "ldo6",
533 .voltage_table = ldo6_voltage_table,
534 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
535 .control_reg = LDO6_CONTROL_REG,
536 .low_power_reg = LDO6_PWRCTRL_REG,
537 .enable_pos = LDO_BUCK_ENABLE_POS,
538 .mask_reset_reg = MASK_RESET_LDO_REG,
539 .mask_reset_pos = LDO6_MASK_RESET_SHIFT,
540 },
541 {
542 .dt_node_name = "vref_ddr",
543 .voltage_table = vref_ddr_voltage_table,
544 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
545 .control_reg = VREF_DDR_CONTROL_REG,
546 .low_power_reg = VREF_DDR_PWRCTRL_REG,
547 .enable_pos = LDO_BUCK_ENABLE_POS,
548 .mask_reset_reg = MASK_RESET_LDO_REG,
549 .mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT,
550 },
551 {
552 .dt_node_name = "boost",
553 .voltage_table = fixed_5v_voltage_table,
554 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
555 .control_reg = USB_CONTROL_REG,
556 .enable_pos = BOOST_ENABLED_POS,
557 },
558 {
559 .dt_node_name = "pwr_sw1",
560 .voltage_table = fixed_5v_voltage_table,
561 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
562 .control_reg = USB_CONTROL_REG,
563 .enable_pos = USBSW_OTG_SWITCH_ENABLED_POS,
564 },
565 {
566 .dt_node_name = "pwr_sw2",
567 .voltage_table = fixed_5v_voltage_table,
568 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
569 .control_reg = USB_CONTROL_REG,
570 .enable_pos = SWIN_SWOUT_ENABLED_POS,
571 },
572 };
573
get_regulator_data(const char * name)574 static const struct regul_struct *get_regulator_data(const char *name)
575 {
576 unsigned int i = 0;
577
578 for (i = 0; i < ARRAY_SIZE(regulators_table); i++)
579 if (strcmp(name, regulators_table[i].dt_node_name) == 0)
580 return ®ulators_table[i];
581
582 DMSG("Regulator %s not found", name);
583 return NULL;
584 }
585
stpmic1_regulator_is_valid(const char * name)586 bool stpmic1_regulator_is_valid(const char *name)
587 {
588 return get_regulator_data(name);
589 }
590
stpmic1_regulator_levels_mv(const char * name,const uint16_t ** levels,size_t * levels_count)591 void stpmic1_regulator_levels_mv(const char *name,
592 const uint16_t **levels,
593 size_t *levels_count)
594 {
595 const struct regul_struct *regul = get_regulator_data(name);
596
597 assert(regul);
598
599 if (levels_count) {
600 *levels_count = regul->voltage_table_size;
601
602 /* Remove last cell 0xFFFF that is not a voltage level */
603 if (regul->voltage_table == ldo3_voltage_table)
604 (*levels_count)--;
605 }
606
607 if (levels)
608 *levels = regul->voltage_table;
609 }
610
voltage_to_index(const char * name,uint16_t millivolts)611 static size_t voltage_to_index(const char *name, uint16_t millivolts)
612 {
613 const struct regul_struct *regul = get_regulator_data(name);
614 unsigned int i = 0;
615
616 assert(regul->voltage_table);
617 for (i = 0; i < regul->voltage_table_size; i++)
618 if (regul->voltage_table[i] == millivolts)
619 return i;
620
621 return VOLTAGE_INDEX_INVALID;
622 }
623
stpmic1_powerctrl_on(void)624 int stpmic1_powerctrl_on(void)
625 {
626 return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
627 PWRCTRL_PIN_VALID);
628 }
629
stpmic1_switch_off(void)630 int stpmic1_switch_off(void)
631 {
632 return stpmic1_register_update(MAIN_CONTROL_REG, 1,
633 SOFTWARE_SWITCH_OFF_ENABLED);
634 }
635
stpmic1_regulator_enable(const char * name)636 int stpmic1_regulator_enable(const char *name)
637 {
638 const struct regul_struct *regul = get_regulator_data(name);
639
640 return stpmic1_register_update(regul->control_reg,
641 BIT(regul->enable_pos),
642 BIT(regul->enable_pos));
643 }
644
stpmic1_regulator_disable(const char * name)645 int stpmic1_regulator_disable(const char *name)
646 {
647 const struct regul_struct *regul = get_regulator_data(name);
648
649 return stpmic1_register_update(regul->control_reg, 0,
650 BIT(regul->enable_pos));
651 }
652
stpmic1_is_regulator_enabled(const char * name)653 bool stpmic1_is_regulator_enabled(const char *name)
654 {
655 const struct regul_struct *regul = get_regulator_data(name);
656 uint8_t val = 0;
657
658 if (stpmic1_register_read(regul->control_reg, &val))
659 panic();
660
661 return val & BIT(regul->enable_pos);
662 }
663
664 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
find_plat_mask(const char * name)665 static uint8_t find_plat_mask(const char *name)
666 {
667 if (!strncmp(name, "buck", 4))
668 return BUCK_VOLTAGE_MASK;
669
670 if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
671 return LDO_VOLTAGE_MASK;
672
673 return 0;
674 }
675
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)676 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
677 {
678 size_t voltage_index = voltage_to_index(name, millivolts);
679 const struct regul_struct *regul = get_regulator_data(name);
680 uint8_t mask = 0;
681
682 if (voltage_index == VOLTAGE_INDEX_INVALID)
683 return -1;
684
685 mask = find_plat_mask(name);
686 if (!mask)
687 return 0;
688
689 return stpmic1_register_update(regul->control_reg,
690 voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
691 mask);
692 }
693
stpmic1_regulator_mask_reset_set(const char * name)694 int stpmic1_regulator_mask_reset_set(const char *name)
695 {
696 const struct regul_struct *regul = get_regulator_data(name);
697
698 if (regul->control_reg == USB_CONTROL_REG) {
699 DMSG("No reset for USB control");
700 return -1;
701 }
702
703 return stpmic1_register_update(regul->mask_reset_reg,
704 BIT(regul->mask_reset_pos),
705 LDO_BUCK_RESET_MASK <<
706 regul->mask_reset_pos);
707 }
708
stpmic1_bo_enable_cfg(const char * name,struct stpmic1_bo_cfg * cfg)709 int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
710 {
711 const struct regul_struct *regul = get_regulator_data(name);
712
713 cfg->ctrl_reg = regul->control_reg;
714 cfg->enable_pos = regul->enable_pos;
715
716 return 0;
717 }
718
stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg * cfg)719 int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
720 {
721 return stpmic1_register_update(cfg->ctrl_reg,
722 BIT(cfg->enable_pos),
723 BIT(cfg->enable_pos));
724 }
725
726 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
stpmic1_bo_voltage_cfg(const char * name,uint16_t min_millivolt,struct stpmic1_bo_cfg * cfg)727 int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
728 struct stpmic1_bo_cfg *cfg)
729 {
730 size_t min_index = voltage_to_index(name, min_millivolt);
731 const struct regul_struct *regul = get_regulator_data(name);
732 uint8_t mask = 0;
733
734 if (min_index == VOLTAGE_INDEX_INVALID)
735 panic();
736
737 mask = find_plat_mask(name);
738 if (!mask)
739 return 1;
740
741 cfg->ctrl_reg = regul->control_reg;
742 cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
743 cfg->mask = mask;
744
745 return 0;
746 }
747
stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg * cfg)748 int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
749 {
750 uint8_t value = 0;
751
752 assert(cfg->ctrl_reg);
753
754 if (stpmic1_register_read(cfg->ctrl_reg, &value))
755 return -1;
756
757 if ((value & cfg->mask) >= cfg->min_value)
758 return 0;
759
760 return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
761 cfg->mask);
762 }
763
stpmic1_bo_pull_down_cfg(const char * name,struct stpmic1_bo_cfg * cfg)764 int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
765 {
766 const struct regul_struct *regul = get_regulator_data(name);
767
768 if (!regul->pull_down_reg) {
769 DMSG("No pull down for regu %s", name);
770 panic();
771 }
772
773 cfg->pd_reg = regul->pull_down_reg;
774 cfg->pd_value = BIT(regul->pull_down_pos);
775 cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
776
777 return 0;
778 }
779
stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg * cfg)780 int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
781 {
782 assert(cfg->pd_reg);
783
784 return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
785 cfg->pd_mask);
786 }
787
stpmic1_bo_mask_reset_cfg(const char * name,struct stpmic1_bo_cfg * cfg)788 int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
789 {
790 const struct regul_struct *regul = get_regulator_data(name);
791
792 if (!regul->mask_reset_reg) {
793 DMSG("No reset mask for regu %s", name);
794 panic();
795 }
796
797 cfg->mrst_reg = regul->mask_reset_reg;
798 cfg->mrst_value = BIT(regul->mask_reset_pos);
799 cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
800
801 return 0;
802 }
803
stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg * cfg)804 int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
805 {
806 assert(cfg->mrst_reg);
807
808 return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
809 cfg->mrst_mask);
810 }
811
stpmic1_regulator_voltage_get(const char * name)812 int stpmic1_regulator_voltage_get(const char *name)
813 {
814 const struct regul_struct *regul = get_regulator_data(name);
815 uint8_t value = 0;
816 uint8_t mask = 0;
817
818 mask = find_plat_mask(name);
819 if (!mask)
820 return 0;
821
822 if (stpmic1_register_read(regul->control_reg, &value))
823 return -1;
824
825 value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
826
827 if (value > regul->voltage_table_size)
828 return -1;
829
830 return regul->voltage_table[value];
831 }
832
stpmic1_lp_copy_reg(const char * name)833 int stpmic1_lp_copy_reg(const char *name)
834 {
835 const struct regul_struct *regul = get_regulator_data(name);
836 uint8_t val = 0;
837 int status = 0;
838
839 if (!regul->low_power_reg)
840 return -1;
841
842 status = stpmic1_register_read(regul->control_reg, &val);
843 if (status)
844 return status;
845
846 return stpmic1_register_write(regul->low_power_reg, val);
847 }
848
stpmic1_regu_has_lp_cfg(const char * name)849 bool stpmic1_regu_has_lp_cfg(const char *name)
850 {
851 return get_regulator_data(name)->low_power_reg;
852 }
853
stpmic1_lp_cfg(const char * name,struct stpmic1_lp_cfg * cfg)854 int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
855 {
856 const struct regul_struct *regul = get_regulator_data(name);
857
858 if (!regul->low_power_reg)
859 return -1;
860
861 cfg->ctrl_reg = regul->control_reg;
862 cfg->lp_reg = regul->low_power_reg;
863
864 return 0;
865 }
866
stpmic1_lp_load_unpg(struct stpmic1_lp_cfg * cfg)867 int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
868 {
869 uint8_t val = 0;
870 int status = 0;
871
872 assert(cfg->lp_reg);
873
874 status = stpmic1_register_read(cfg->ctrl_reg, &val);
875 if (!status)
876 status = stpmic1_register_write(cfg->lp_reg, val);
877
878 return status;
879 }
880
stpmic1_lp_reg_on_off(const char * name,uint8_t enable)881 int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
882 {
883 const struct regul_struct *regul = get_regulator_data(name);
884
885 if (!regul->low_power_reg)
886 return -1;
887
888 return stpmic1_register_update(regul->low_power_reg, enable,
889 LDO_BUCK_ENABLE_MASK);
890 }
891
stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg * cfg,int enable)892 int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
893 {
894 assert(cfg->lp_reg && (enable == 0 || enable == 1));
895
896 return stpmic1_register_update(cfg->lp_reg, enable,
897 LDO_BUCK_ENABLE_MASK);
898 }
899
stpmic1_lp_set_mode(const char * name,uint8_t hplp)900 int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
901 {
902 const struct regul_struct *regul = get_regulator_data(name);
903
904 assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
905
906 return stpmic1_register_update(regul->low_power_reg,
907 hplp << LDO_BUCK_HPLP_POS,
908 BIT(LDO_BUCK_HPLP_POS));
909 }
910
stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg * cfg,unsigned int mode)911 int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
912 {
913 assert(cfg->lp_reg && (mode == 0 || mode == 1));
914 return stpmic1_register_update(cfg->lp_reg,
915 mode << LDO_BUCK_HPLP_POS,
916 BIT(LDO_BUCK_HPLP_POS));
917 }
918
stpmic1_lp_set_voltage(const char * name,uint16_t millivolts)919 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
920 {
921 size_t voltage_index = voltage_to_index(name, millivolts);
922 const struct regul_struct *regul = get_regulator_data(name);
923 uint8_t mask = 0;
924
925 assert(voltage_index != VOLTAGE_INDEX_INVALID);
926
927 mask = find_plat_mask(name);
928 if (!mask)
929 return 0;
930
931 return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
932 mask);
933 }
934
935 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
stpmic1_lp_voltage_cfg(const char * name,uint16_t millivolts,struct stpmic1_lp_cfg * cfg)936 int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
937 struct stpmic1_lp_cfg *cfg)
938
939 {
940 size_t voltage_index = voltage_to_index(name, millivolts);
941 uint8_t mask = 0;
942
943 mask = find_plat_mask(name);
944 if (!mask)
945 return 1;
946
947 assert(voltage_index != VOLTAGE_INDEX_INVALID &&
948 cfg->lp_reg == get_regulator_data(name)->low_power_reg);
949
950 cfg->value = voltage_index << 2;
951 cfg->mask = mask;
952
953 return 0;
954 }
955
stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg * cfg)956 int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
957 {
958 assert(cfg->lp_reg);
959
960 return stpmic1_register_update(cfg->lp_reg, cfg->value, cfg->mask);
961 }
962
stpmic1_register_read(uint8_t register_id,uint8_t * value)963 int stpmic1_register_read(uint8_t register_id, uint8_t *value)
964 {
965 struct i2c_handle_s *i2c = pmic_i2c_handle;
966
967 return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
968 register_id, value,
969 false /* !write */);
970 }
971
stpmic1_register_write(uint8_t register_id,uint8_t value)972 int stpmic1_register_write(uint8_t register_id, uint8_t value)
973 {
974 struct i2c_handle_s *i2c = pmic_i2c_handle;
975 uint8_t val = value;
976
977 return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
978 register_id, &val,
979 true /* write */);
980 }
981
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)982 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
983 {
984 int status = 0;
985 uint8_t val = 0;
986
987 status = stpmic1_register_read(register_id, &val);
988 if (status)
989 return status;
990
991 val = (val & ~mask) | (value & mask);
992
993 return stpmic1_register_write(register_id, val);
994 }
995
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)996 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
997 {
998 pmic_i2c_handle = i2c_handle;
999 pmic_i2c_addr = i2c_addr;
1000 }
1001
stpmic1_dump_regulators(void)1002 void stpmic1_dump_regulators(void)
1003 {
1004 size_t i = 0;
1005 char __maybe_unused const *name = NULL;
1006
1007 for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
1008 if (!regulators_table[i].control_reg)
1009 continue;
1010
1011 name = regulators_table[i].dt_node_name;
1012 DMSG("PMIC regul %s: %sable, %dmV",
1013 name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
1014 stpmic1_regulator_voltage_get(name));
1015 }
1016 }
1017
stpmic1_get_version(unsigned long * version)1018 int stpmic1_get_version(unsigned long *version)
1019 {
1020 uint8_t read_val = 0;
1021
1022 if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
1023 return -1;
1024
1025 *version = read_val;
1026 return 0;
1027 }
1028