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 if (levels)
603 *levels = regul->voltage_table;
604 }
605
voltage_to_index(const char * name,uint16_t millivolts)606 static size_t voltage_to_index(const char *name, uint16_t millivolts)
607 {
608 const struct regul_struct *regul = get_regulator_data(name);
609 unsigned int i = 0;
610
611 assert(regul->voltage_table);
612 for (i = 0; i < regul->voltage_table_size; i++)
613 if (regul->voltage_table[i] == millivolts)
614 return i;
615
616 return VOLTAGE_INDEX_INVALID;
617 }
618
stpmic1_powerctrl_on(void)619 int stpmic1_powerctrl_on(void)
620 {
621 return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
622 PWRCTRL_PIN_VALID);
623 }
624
stpmic1_switch_off(void)625 int stpmic1_switch_off(void)
626 {
627 return stpmic1_register_update(MAIN_CONTROL_REG, 1,
628 SOFTWARE_SWITCH_OFF_ENABLED);
629 }
630
stpmic1_regulator_enable(const char * name)631 int stpmic1_regulator_enable(const char *name)
632 {
633 const struct regul_struct *regul = get_regulator_data(name);
634
635 return stpmic1_register_update(regul->control_reg,
636 BIT(regul->enable_pos),
637 BIT(regul->enable_pos));
638 }
639
stpmic1_regulator_disable(const char * name)640 int stpmic1_regulator_disable(const char *name)
641 {
642 const struct regul_struct *regul = get_regulator_data(name);
643
644 return stpmic1_register_update(regul->control_reg, 0,
645 BIT(regul->enable_pos));
646 }
647
stpmic1_is_regulator_enabled(const char * name)648 bool stpmic1_is_regulator_enabled(const char *name)
649 {
650 const struct regul_struct *regul = get_regulator_data(name);
651 uint8_t val = 0;
652
653 if (stpmic1_register_read(regul->control_reg, &val))
654 panic();
655
656 return val & BIT(regul->enable_pos);
657 }
658
659 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
find_plat_mask(const char * name)660 static uint8_t find_plat_mask(const char *name)
661 {
662 if (!strncmp(name, "buck", 4))
663 return BUCK_VOLTAGE_MASK;
664
665 if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
666 return LDO_VOLTAGE_MASK;
667
668 return 0;
669 }
670
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)671 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
672 {
673 size_t voltage_index = voltage_to_index(name, millivolts);
674 const struct regul_struct *regul = get_regulator_data(name);
675 uint8_t mask = 0;
676
677 if (voltage_index == VOLTAGE_INDEX_INVALID)
678 return -1;
679
680 mask = find_plat_mask(name);
681 if (!mask)
682 return 0;
683
684 return stpmic1_register_update(regul->control_reg,
685 voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
686 mask);
687 }
688
stpmic1_regulator_mask_reset_set(const char * name)689 int stpmic1_regulator_mask_reset_set(const char *name)
690 {
691 const struct regul_struct *regul = get_regulator_data(name);
692
693 if (regul->control_reg == USB_CONTROL_REG) {
694 DMSG("No reset for USB control");
695 return -1;
696 }
697
698 return stpmic1_register_update(regul->mask_reset_reg,
699 BIT(regul->mask_reset_pos),
700 LDO_BUCK_RESET_MASK <<
701 regul->mask_reset_pos);
702 }
703
stpmic1_bo_enable_cfg(const char * name,struct stpmic1_bo_cfg * cfg)704 int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
705 {
706 const struct regul_struct *regul = get_regulator_data(name);
707
708 cfg->ctrl_reg = regul->control_reg;
709 cfg->enable_pos = regul->enable_pos;
710
711 return 0;
712 }
713
stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg * cfg)714 int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
715 {
716 return stpmic1_register_update(cfg->ctrl_reg,
717 BIT(cfg->enable_pos),
718 BIT(cfg->enable_pos));
719 }
720
721 /* 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)722 int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
723 struct stpmic1_bo_cfg *cfg)
724 {
725 size_t min_index = voltage_to_index(name, min_millivolt);
726 const struct regul_struct *regul = get_regulator_data(name);
727 uint8_t mask = 0;
728
729 if (min_index == VOLTAGE_INDEX_INVALID)
730 panic();
731
732 mask = find_plat_mask(name);
733 if (!mask)
734 return 1;
735
736 cfg->ctrl_reg = regul->control_reg;
737 cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
738 cfg->mask = mask;
739
740 return 0;
741 }
742
stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg * cfg)743 int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
744 {
745 uint8_t value = 0;
746
747 assert(cfg->ctrl_reg);
748
749 if (stpmic1_register_read(cfg->ctrl_reg, &value))
750 return -1;
751
752 if ((value & cfg->mask) >= cfg->min_value)
753 return 0;
754
755 return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
756 cfg->mask);
757 }
758
stpmic1_bo_pull_down_cfg(const char * name,struct stpmic1_bo_cfg * cfg)759 int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
760 {
761 const struct regul_struct *regul = get_regulator_data(name);
762
763 if (!regul->pull_down_reg) {
764 DMSG("No pull down for regu %s", name);
765 panic();
766 }
767
768 cfg->pd_reg = regul->pull_down_reg;
769 cfg->pd_value = BIT(regul->pull_down_pos);
770 cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
771
772 return 0;
773 }
774
stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg * cfg)775 int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
776 {
777 assert(cfg->pd_reg);
778
779 return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
780 cfg->pd_mask);
781 }
782
stpmic1_bo_mask_reset_cfg(const char * name,struct stpmic1_bo_cfg * cfg)783 int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
784 {
785 const struct regul_struct *regul = get_regulator_data(name);
786
787 if (!regul->mask_reset_reg) {
788 DMSG("No reset mask for regu %s", name);
789 panic();
790 }
791
792 cfg->mrst_reg = regul->mask_reset_reg;
793 cfg->mrst_value = BIT(regul->mask_reset_pos);
794 cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
795
796 return 0;
797 }
798
stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg * cfg)799 int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
800 {
801 assert(cfg->mrst_reg);
802
803 return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
804 cfg->mrst_mask);
805 }
806
stpmic1_regulator_voltage_get(const char * name)807 int stpmic1_regulator_voltage_get(const char *name)
808 {
809 const struct regul_struct *regul = get_regulator_data(name);
810 uint8_t value = 0;
811 uint8_t mask = 0;
812
813 mask = find_plat_mask(name);
814 if (!mask)
815 return 0;
816
817 if (stpmic1_register_read(regul->control_reg, &value))
818 return -1;
819
820 value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
821
822 if (value > regul->voltage_table_size)
823 return -1;
824
825 return regul->voltage_table[value];
826 }
827
stpmic1_lp_copy_reg(const char * name)828 int stpmic1_lp_copy_reg(const char *name)
829 {
830 const struct regul_struct *regul = get_regulator_data(name);
831 uint8_t val = 0;
832 int status = 0;
833
834 if (!regul->low_power_reg)
835 return -1;
836
837 status = stpmic1_register_read(regul->control_reg, &val);
838 if (status)
839 return status;
840
841 return stpmic1_register_write(regul->low_power_reg, val);
842 }
843
stpmic1_regu_has_lp_cfg(const char * name)844 bool stpmic1_regu_has_lp_cfg(const char *name)
845 {
846 return get_regulator_data(name)->low_power_reg;
847 }
848
stpmic1_lp_cfg(const char * name,struct stpmic1_lp_cfg * cfg)849 int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
850 {
851 const struct regul_struct *regul = get_regulator_data(name);
852
853 if (!regul->low_power_reg)
854 return -1;
855
856 cfg->ctrl_reg = regul->control_reg;
857 cfg->lp_reg = regul->low_power_reg;
858
859 return 0;
860 }
861
stpmic1_lp_load_unpg(struct stpmic1_lp_cfg * cfg)862 int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
863 {
864 uint8_t val = 0;
865 int status = 0;
866
867 assert(cfg->lp_reg);
868
869 status = stpmic1_register_read(cfg->ctrl_reg, &val);
870 if (!status)
871 status = stpmic1_register_write(cfg->lp_reg, val);
872
873 return status;
874 }
875
stpmic1_lp_reg_on_off(const char * name,uint8_t enable)876 int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
877 {
878 const struct regul_struct *regul = get_regulator_data(name);
879
880 if (!regul->low_power_reg)
881 return -1;
882
883 return stpmic1_register_update(regul->low_power_reg, enable,
884 LDO_BUCK_ENABLE_MASK);
885 }
886
stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg * cfg,int enable)887 int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
888 {
889 assert(cfg->lp_reg && (enable == 0 || enable == 1));
890
891 return stpmic1_register_update(cfg->lp_reg, enable,
892 LDO_BUCK_ENABLE_MASK);
893 }
894
stpmic1_lp_set_mode(const char * name,uint8_t hplp)895 int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
896 {
897 const struct regul_struct *regul = get_regulator_data(name);
898
899 assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
900
901 return stpmic1_register_update(regul->low_power_reg,
902 hplp << LDO_BUCK_HPLP_POS,
903 BIT(LDO_BUCK_HPLP_POS));
904 }
905
stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg * cfg,unsigned int mode)906 int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
907 {
908 assert(cfg->lp_reg && (mode == 0 || mode == 1));
909 return stpmic1_register_update(cfg->lp_reg,
910 mode << LDO_BUCK_HPLP_POS,
911 BIT(LDO_BUCK_HPLP_POS));
912 }
913
stpmic1_lp_set_voltage(const char * name,uint16_t millivolts)914 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
915 {
916 size_t voltage_index = voltage_to_index(name, millivolts);
917 const struct regul_struct *regul = get_regulator_data(name);
918 uint8_t mask = 0;
919
920 assert(voltage_index != VOLTAGE_INDEX_INVALID);
921
922 mask = find_plat_mask(name);
923 if (!mask)
924 return 0;
925
926 return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
927 mask);
928 }
929
930 /* 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)931 int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
932 struct stpmic1_lp_cfg *cfg)
933
934 {
935 size_t voltage_index = voltage_to_index(name, millivolts);
936 uint8_t mask = 0;
937
938 mask = find_plat_mask(name);
939 if (!mask)
940 return 1;
941
942 assert(voltage_index != VOLTAGE_INDEX_INVALID &&
943 cfg->lp_reg == get_regulator_data(name)->low_power_reg);
944
945 cfg->value = voltage_index << 2;
946 cfg->mask = mask;
947
948 return 0;
949 }
950
stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg * cfg)951 int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
952 {
953 assert(cfg->lp_reg);
954
955 return stpmic1_register_update(cfg->lp_reg, cfg->value, cfg->mask);
956 }
957
stpmic1_register_read(uint8_t register_id,uint8_t * value)958 int stpmic1_register_read(uint8_t register_id, uint8_t *value)
959 {
960 struct i2c_handle_s *i2c = pmic_i2c_handle;
961
962 return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
963 register_id, value,
964 false /* !write */);
965 }
966
stpmic1_register_write(uint8_t register_id,uint8_t value)967 int stpmic1_register_write(uint8_t register_id, uint8_t value)
968 {
969 struct i2c_handle_s *i2c = pmic_i2c_handle;
970 uint8_t val = value;
971
972 return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
973 register_id, &val,
974 true /* write */);
975 }
976
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)977 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
978 {
979 int status = 0;
980 uint8_t val = 0;
981
982 status = stpmic1_register_read(register_id, &val);
983 if (status)
984 return status;
985
986 val = (val & ~mask) | (value & mask);
987
988 return stpmic1_register_write(register_id, val);
989 }
990
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)991 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
992 {
993 pmic_i2c_handle = i2c_handle;
994 pmic_i2c_addr = i2c_addr;
995 }
996
stpmic1_dump_regulators(void)997 void stpmic1_dump_regulators(void)
998 {
999 size_t i = 0;
1000 char __maybe_unused const *name = NULL;
1001
1002 for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
1003 if (!regulators_table[i].control_reg)
1004 continue;
1005
1006 name = regulators_table[i].dt_node_name;
1007 DMSG("PMIC regul %s: %sable, %dmV",
1008 name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
1009 stpmic1_regulator_voltage_get(name));
1010 }
1011 }
1012
stpmic1_get_version(unsigned long * version)1013 int stpmic1_get_version(unsigned long *version)
1014 {
1015 uint8_t read_val = 0;
1016
1017 if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
1018 return -1;
1019
1020 *version = read_val;
1021 return 0;
1022 }
1023