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