1 /*
2 * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <string.h>
8
9 #include <common/debug.h>
10 #include <drivers/st/stpmic1.h>
11
12 #define I2C_TIMEOUT_MS 25
13
14 struct regul_struct {
15 const char *dt_node_name;
16 const uint16_t *voltage_table;
17 uint8_t voltage_table_size;
18 uint8_t control_reg;
19 uint8_t low_power_reg;
20 uint8_t pull_down_reg;
21 uint8_t pull_down;
22 uint8_t mask_reset_reg;
23 uint8_t mask_reset;
24 };
25
26 static struct i2c_handle_s *pmic_i2c_handle;
27 static uint16_t pmic_i2c_addr;
28
29 /* Voltage tables in mV */
30 static const uint16_t buck1_voltage_table[] = {
31 725,
32 725,
33 725,
34 725,
35 725,
36 725,
37 750,
38 775,
39 800,
40 825,
41 850,
42 875,
43 900,
44 925,
45 950,
46 975,
47 1000,
48 1025,
49 1050,
50 1075,
51 1100,
52 1125,
53 1150,
54 1175,
55 1200,
56 1225,
57 1250,
58 1275,
59 1300,
60 1325,
61 1350,
62 1375,
63 1400,
64 1425,
65 1450,
66 1475,
67 1500,
68 1500,
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 };
96
97 static const uint16_t buck2_voltage_table[] = {
98 1000,
99 1000,
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 1050,
117 1050,
118 1100,
119 1100,
120 1150,
121 1150,
122 1200,
123 1200,
124 1250,
125 1250,
126 1300,
127 1300,
128 1350,
129 1350,
130 1400,
131 1400,
132 1450,
133 1450,
134 1500,
135 };
136
137 static const uint16_t buck3_voltage_table[] = {
138 1000,
139 1000,
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 1100,
159 1100,
160 1100,
161 1100,
162 1200,
163 1200,
164 1200,
165 1200,
166 1300,
167 1300,
168 1300,
169 1300,
170 1400,
171 1400,
172 1400,
173 1400,
174 1500,
175 1600,
176 1700,
177 1800,
178 1900,
179 2000,
180 2100,
181 2200,
182 2300,
183 2400,
184 2500,
185 2600,
186 2700,
187 2800,
188 2900,
189 3000,
190 3100,
191 3200,
192 3300,
193 3400,
194 };
195
196 static const uint16_t buck4_voltage_table[] = {
197 600,
198 625,
199 650,
200 675,
201 700,
202 725,
203 750,
204 775,
205 800,
206 825,
207 850,
208 875,
209 900,
210 925,
211 950,
212 975,
213 1000,
214 1025,
215 1050,
216 1075,
217 1100,
218 1125,
219 1150,
220 1175,
221 1200,
222 1225,
223 1250,
224 1275,
225 1300,
226 1300,
227 1350,
228 1350,
229 1400,
230 1400,
231 1450,
232 1450,
233 1500,
234 1600,
235 1700,
236 1800,
237 1900,
238 2000,
239 2100,
240 2200,
241 2300,
242 2400,
243 2500,
244 2600,
245 2700,
246 2800,
247 2900,
248 3000,
249 3100,
250 3200,
251 3300,
252 3400,
253 3500,
254 3600,
255 3700,
256 3800,
257 3900,
258 };
259
260 static const uint16_t ldo1_voltage_table[] = {
261 1700,
262 1700,
263 1700,
264 1700,
265 1700,
266 1700,
267 1700,
268 1700,
269 1700,
270 1800,
271 1900,
272 2000,
273 2100,
274 2200,
275 2300,
276 2400,
277 2500,
278 2600,
279 2700,
280 2800,
281 2900,
282 3000,
283 3100,
284 3200,
285 3300,
286 };
287
288 static const uint16_t ldo2_voltage_table[] = {
289 1700,
290 1700,
291 1700,
292 1700,
293 1700,
294 1700,
295 1700,
296 1700,
297 1700,
298 1800,
299 1900,
300 2000,
301 2100,
302 2200,
303 2300,
304 2400,
305 2500,
306 2600,
307 2700,
308 2800,
309 2900,
310 3000,
311 3100,
312 3200,
313 3300,
314 };
315
316 static const uint16_t ldo3_voltage_table[] = {
317 1700,
318 1700,
319 1700,
320 1700,
321 1700,
322 1700,
323 1700,
324 1700,
325 1700,
326 1800,
327 1900,
328 2000,
329 2100,
330 2200,
331 2300,
332 2400,
333 2500,
334 2600,
335 2700,
336 2800,
337 2900,
338 3000,
339 3100,
340 3200,
341 3300,
342 3300,
343 3300,
344 3300,
345 3300,
346 3300,
347 3300,
348 500,
349 0xFFFF, /* VREFDDR */
350 };
351
352 static const uint16_t ldo5_voltage_table[] = {
353 1700,
354 1700,
355 1700,
356 1700,
357 1700,
358 1700,
359 1700,
360 1700,
361 1700,
362 1800,
363 1900,
364 2000,
365 2100,
366 2200,
367 2300,
368 2400,
369 2500,
370 2600,
371 2700,
372 2800,
373 2900,
374 3000,
375 3100,
376 3200,
377 3300,
378 3400,
379 3500,
380 3600,
381 3700,
382 3800,
383 3900,
384 };
385
386 static const uint16_t ldo6_voltage_table[] = {
387 900,
388 1000,
389 1100,
390 1200,
391 1300,
392 1400,
393 1500,
394 1600,
395 1700,
396 1800,
397 1900,
398 2000,
399 2100,
400 2200,
401 2300,
402 2400,
403 2500,
404 2600,
405 2700,
406 2800,
407 2900,
408 3000,
409 3100,
410 3200,
411 3300,
412 };
413
414 static const uint16_t ldo4_voltage_table[] = {
415 3300,
416 };
417
418 static const uint16_t vref_ddr_voltage_table[] = {
419 3300,
420 };
421
422 /* Table of Regulators in PMIC SoC */
423 static const struct regul_struct regulators_table[] = {
424 {
425 .dt_node_name = "buck1",
426 .voltage_table = buck1_voltage_table,
427 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
428 .control_reg = BUCK1_CONTROL_REG,
429 .low_power_reg = BUCK1_PWRCTRL_REG,
430 .pull_down_reg = BUCK_PULL_DOWN_REG,
431 .pull_down = BUCK1_PULL_DOWN_SHIFT,
432 .mask_reset_reg = MASK_RESET_BUCK_REG,
433 .mask_reset = BUCK1_MASK_RESET,
434 },
435 {
436 .dt_node_name = "buck2",
437 .voltage_table = buck2_voltage_table,
438 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
439 .control_reg = BUCK2_CONTROL_REG,
440 .low_power_reg = BUCK2_PWRCTRL_REG,
441 .pull_down_reg = BUCK_PULL_DOWN_REG,
442 .pull_down = BUCK2_PULL_DOWN_SHIFT,
443 .mask_reset_reg = MASK_RESET_BUCK_REG,
444 .mask_reset = BUCK2_MASK_RESET,
445 },
446 {
447 .dt_node_name = "buck3",
448 .voltage_table = buck3_voltage_table,
449 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
450 .control_reg = BUCK3_CONTROL_REG,
451 .low_power_reg = BUCK3_PWRCTRL_REG,
452 .pull_down_reg = BUCK_PULL_DOWN_REG,
453 .pull_down = BUCK3_PULL_DOWN_SHIFT,
454 .mask_reset_reg = MASK_RESET_BUCK_REG,
455 .mask_reset = BUCK3_MASK_RESET,
456 },
457 {
458 .dt_node_name = "buck4",
459 .voltage_table = buck4_voltage_table,
460 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
461 .control_reg = BUCK4_CONTROL_REG,
462 .low_power_reg = BUCK4_PWRCTRL_REG,
463 .pull_down_reg = BUCK_PULL_DOWN_REG,
464 .pull_down = BUCK4_PULL_DOWN_SHIFT,
465 .mask_reset_reg = MASK_RESET_BUCK_REG,
466 .mask_reset = BUCK4_MASK_RESET,
467 },
468 {
469 .dt_node_name = "ldo1",
470 .voltage_table = ldo1_voltage_table,
471 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
472 .control_reg = LDO1_CONTROL_REG,
473 .low_power_reg = LDO1_PWRCTRL_REG,
474 .mask_reset_reg = MASK_RESET_LDO_REG,
475 .mask_reset = LDO1_MASK_RESET,
476 },
477 {
478 .dt_node_name = "ldo2",
479 .voltage_table = ldo2_voltage_table,
480 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
481 .control_reg = LDO2_CONTROL_REG,
482 .low_power_reg = LDO2_PWRCTRL_REG,
483 .mask_reset_reg = MASK_RESET_LDO_REG,
484 .mask_reset = LDO2_MASK_RESET,
485 },
486 {
487 .dt_node_name = "ldo3",
488 .voltage_table = ldo3_voltage_table,
489 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
490 .control_reg = LDO3_CONTROL_REG,
491 .low_power_reg = LDO3_PWRCTRL_REG,
492 .mask_reset_reg = MASK_RESET_LDO_REG,
493 .mask_reset = LDO3_MASK_RESET,
494 },
495 {
496 .dt_node_name = "ldo4",
497 .voltage_table = ldo4_voltage_table,
498 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
499 .control_reg = LDO4_CONTROL_REG,
500 .low_power_reg = LDO4_PWRCTRL_REG,
501 .mask_reset_reg = MASK_RESET_LDO_REG,
502 .mask_reset = LDO4_MASK_RESET,
503 },
504 {
505 .dt_node_name = "ldo5",
506 .voltage_table = ldo5_voltage_table,
507 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
508 .control_reg = LDO5_CONTROL_REG,
509 .low_power_reg = LDO5_PWRCTRL_REG,
510 .mask_reset_reg = MASK_RESET_LDO_REG,
511 .mask_reset = LDO5_MASK_RESET,
512 },
513 {
514 .dt_node_name = "ldo6",
515 .voltage_table = ldo6_voltage_table,
516 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
517 .control_reg = LDO6_CONTROL_REG,
518 .low_power_reg = LDO6_PWRCTRL_REG,
519 .mask_reset_reg = MASK_RESET_LDO_REG,
520 .mask_reset = LDO6_MASK_RESET,
521 },
522 {
523 .dt_node_name = "vref_ddr",
524 .voltage_table = vref_ddr_voltage_table,
525 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
526 .control_reg = VREF_DDR_CONTROL_REG,
527 .low_power_reg = VREF_DDR_PWRCTRL_REG,
528 .mask_reset_reg = MASK_RESET_LDO_REG,
529 .mask_reset = VREF_DDR_MASK_RESET,
530 },
531 };
532
533 #define MAX_REGUL ARRAY_SIZE(regulators_table)
534
get_regulator_data(const char * name)535 static const struct regul_struct *get_regulator_data(const char *name)
536 {
537 uint8_t i;
538
539 for (i = 0 ; i < MAX_REGUL ; i++) {
540 if (strncmp(name, regulators_table[i].dt_node_name,
541 strlen(regulators_table[i].dt_node_name)) == 0) {
542 return ®ulators_table[i];
543 }
544 }
545
546 /* Regulator not found */
547 panic();
548 return NULL;
549 }
550
voltage_to_index(const char * name,uint16_t millivolts)551 static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
552 {
553 const struct regul_struct *regul = get_regulator_data(name);
554 uint8_t i;
555
556 for (i = 0 ; i < regul->voltage_table_size ; i++) {
557 if (regul->voltage_table[i] == millivolts) {
558 return i;
559 }
560 }
561
562 /* Voltage not found */
563 panic();
564
565 return 0;
566 }
567
stpmic1_powerctrl_on(void)568 int stpmic1_powerctrl_on(void)
569 {
570 return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
571 PWRCTRL_PIN_VALID);
572 }
573
stpmic1_switch_off(void)574 int stpmic1_switch_off(void)
575 {
576 return stpmic1_register_update(MAIN_CONTROL_REG, 1,
577 SOFTWARE_SWITCH_OFF_ENABLED);
578 }
579
stpmic1_regulator_enable(const char * name)580 int stpmic1_regulator_enable(const char *name)
581 {
582 const struct regul_struct *regul = get_regulator_data(name);
583
584 return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
585 }
586
stpmic1_regulator_disable(const char * name)587 int stpmic1_regulator_disable(const char *name)
588 {
589 const struct regul_struct *regul = get_regulator_data(name);
590
591 return stpmic1_register_update(regul->control_reg, 0, BIT(0));
592 }
593
stpmic1_is_regulator_enabled(const char * name)594 uint8_t stpmic1_is_regulator_enabled(const char *name)
595 {
596 uint8_t val;
597 const struct regul_struct *regul = get_regulator_data(name);
598
599 if (stpmic1_register_read(regul->control_reg, &val) != 0) {
600 panic();
601 }
602
603 return (val & 0x1U);
604 }
605
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)606 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
607 {
608 uint8_t voltage_index = voltage_to_index(name, millivolts);
609 const struct regul_struct *regul = get_regulator_data(name);
610 uint8_t mask;
611
612 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
613 if (strncmp(name, "buck", 4) == 0) {
614 mask = BUCK_VOLTAGE_MASK;
615 } else if ((strncmp(name, "ldo", 3) == 0) &&
616 (strncmp(name, "ldo4", 4) != 0)) {
617 mask = LDO_VOLTAGE_MASK;
618 } else {
619 return 0;
620 }
621
622 return stpmic1_register_update(regul->control_reg,
623 voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
624 mask);
625 }
626
stpmic1_regulator_pull_down_set(const char * name)627 int stpmic1_regulator_pull_down_set(const char *name)
628 {
629 const struct regul_struct *regul = get_regulator_data(name);
630
631 if (regul->pull_down_reg != 0) {
632 return stpmic1_register_update(regul->pull_down_reg,
633 BIT(regul->pull_down),
634 LDO_BUCK_PULL_DOWN_MASK <<
635 regul->pull_down);
636 }
637
638 return 0;
639 }
640
stpmic1_regulator_mask_reset_set(const char * name)641 int stpmic1_regulator_mask_reset_set(const char *name)
642 {
643 const struct regul_struct *regul = get_regulator_data(name);
644
645 return stpmic1_register_update(regul->mask_reset_reg,
646 BIT(regul->mask_reset),
647 LDO_BUCK_RESET_MASK <<
648 regul->mask_reset);
649 }
650
stpmic1_regulator_voltage_get(const char * name)651 int stpmic1_regulator_voltage_get(const char *name)
652 {
653 const struct regul_struct *regul = get_regulator_data(name);
654 uint8_t value;
655 uint8_t mask;
656
657 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
658 if (strncmp(name, "buck", 4) == 0) {
659 mask = BUCK_VOLTAGE_MASK;
660 } else if ((strncmp(name, "ldo", 3) == 0) &&
661 (strncmp(name, "ldo4", 4) != 0)) {
662 mask = LDO_VOLTAGE_MASK;
663 } else {
664 return 0;
665 }
666
667 if (stpmic1_register_read(regul->control_reg, &value))
668 return -1;
669
670 value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
671
672 if (value > regul->voltage_table_size)
673 return -1;
674
675 return (int)regul->voltage_table[value];
676 }
677
stpmic1_register_read(uint8_t register_id,uint8_t * value)678 int stpmic1_register_read(uint8_t register_id, uint8_t *value)
679 {
680 return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
681 (uint16_t)register_id,
682 I2C_MEMADD_SIZE_8BIT, value,
683 1, I2C_TIMEOUT_MS);
684 }
685
stpmic1_register_write(uint8_t register_id,uint8_t value)686 int stpmic1_register_write(uint8_t register_id, uint8_t value)
687 {
688 int status;
689
690 status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
691 (uint16_t)register_id,
692 I2C_MEMADD_SIZE_8BIT, &value,
693 1, I2C_TIMEOUT_MS);
694
695 #if ENABLE_ASSERTIONS
696 if (status != 0) {
697 return status;
698 }
699
700 if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
701 uint8_t readval;
702
703 status = stpmic1_register_read(register_id, &readval);
704 if (status != 0) {
705 return status;
706 }
707
708 if (readval != value) {
709 return -1;
710 }
711 }
712 #endif
713
714 return status;
715 }
716
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)717 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
718 {
719 int status;
720 uint8_t val;
721
722 status = stpmic1_register_read(register_id, &val);
723 if (status != 0) {
724 return status;
725 }
726
727 val = (val & ~mask) | (value & mask);
728
729 return stpmic1_register_write(register_id, val);
730 }
731
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)732 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
733 {
734 pmic_i2c_handle = i2c_handle;
735 pmic_i2c_addr = i2c_addr;
736 }
737
stpmic1_dump_regulators(void)738 void stpmic1_dump_regulators(void)
739 {
740 uint32_t i;
741
742 for (i = 0U; i < MAX_REGUL; i++) {
743 const char *name __unused = regulators_table[i].dt_node_name;
744
745 VERBOSE("PMIC regul %s: %sable, %dmV",
746 name,
747 stpmic1_is_regulator_enabled(name) ? "en" : "dis",
748 stpmic1_regulator_voltage_get(name));
749 }
750 }
751
stpmic1_get_version(unsigned long * version)752 int stpmic1_get_version(unsigned long *version)
753 {
754 int rc;
755 uint8_t read_val;
756
757 rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
758 if (rc) {
759 return -1;
760 }
761
762 *version = (unsigned long)read_val;
763
764 return 0;
765 }
766