blob: 5951899a1a6b92e627ee2d2036a17eec6f3f6951 [file] [log] [blame]
Yann Gautierbb836ee2018-07-16 17:55:07 +02001/*
2 * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <debug.h>
8#include <platform.h>
9#include <stpmu1.h>
10#include <string.h>
11
12struct regul_struct {
13 const char *dt_node_name;
14 const uint16_t *voltage_table;
15 uint8_t voltage_table_size;
16 uint8_t control_reg;
17 uint8_t low_power_reg;
18};
19
20static struct i2c_handle_s *stpmu_i2c_handle;
21static uint16_t stpmu_i2c_addr;
22
23/* Voltage tables in mV */
24static const uint16_t buck1_voltage_table[] = {
25 600,
26 625,
27 650,
28 675,
29 700,
30 725,
31 750,
32 775,
33 800,
34 825,
35 850,
36 875,
37 900,
38 925,
39 950,
40 975,
41 1000,
42 1025,
43 1050,
44 1075,
45 1100,
46 1125,
47 1150,
48 1175,
49 1200,
50 1225,
51 1250,
52 1275,
53 1300,
54 1325,
55 1350,
56 1350,
57};
58
59static const uint16_t buck2_voltage_table[] = {
60 1000,
61 1000,
62 1000,
63 1000,
64 1000,
65 1000,
66 1000,
67 1000,
68 1000,
69 1000,
70 1000,
71 1000,
72 1000,
73 1000,
74 1000,
75 1000,
76 1000,
77 1000,
78 1050,
79 1050,
80 1100,
81 1100,
82 1150,
83 1150,
84 1200,
85 1200,
86 1250,
87 1250,
88 1300,
89 1300,
90 1350,
91 1350,
92 1400,
93 1400,
94 1450,
95 1450,
96 1500,
97};
98
99static const uint16_t buck3_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 1000,
119 1000,
120 1100,
121 1100,
122 1100,
123 1100,
124 1200,
125 1200,
126 1200,
127 1200,
128 1300,
129 1300,
130 1300,
131 1300,
132 1400,
133 1400,
134 1400,
135 1400,
136 1500,
137 1600,
138 1700,
139 1800,
140 1900,
141 2000,
142 2100,
143 2200,
144 2300,
145 2400,
146 2500,
147 2600,
148 2700,
149 2800,
150 2900,
151 3000,
152 3100,
153 3200,
154 3300,
155 3400,
156};
157
158static const uint16_t buck4_voltage_table[] = {
159 600,
160 625,
161 650,
162 675,
163 700,
164 725,
165 750,
166 775,
167 800,
168 825,
169 850,
170 875,
171 900,
172 925,
173 950,
174 975,
175 1000,
176 1025,
177 1050,
178 1075,
179 1100,
180 1125,
181 1150,
182 1175,
183 1200,
184 1225,
185 1250,
186 1275,
187 1300,
188 1300,
189 1350,
190 1350,
191 1400,
192 1400,
193 1450,
194 1450,
195 1500,
196 1600,
197 1700,
198 1800,
199 1900,
200 2000,
201 2100,
202 2200,
203 2300,
204 2400,
205 2500,
206 2600,
207 2700,
208 2800,
209 2900,
210 3000,
211 3100,
212 3200,
213 3300,
214 3400,
215 3500,
216 3600,
217 3700,
218 3800,
219 3900,
220};
221
222static const uint16_t ldo1_voltage_table[] = {
223 1700,
224 1700,
225 1700,
226 1700,
227 1700,
228 1700,
229 1700,
230 1700,
231 1700,
232 1800,
233 1900,
234 2000,
235 2100,
236 2200,
237 2300,
238 2400,
239 2500,
240 2600,
241 2700,
242 2800,
243 2900,
244 3000,
245 3100,
246 3200,
247 3300,
248};
249
250static const uint16_t ldo2_voltage_table[] = {
251 1700,
252 1700,
253 1700,
254 1700,
255 1700,
256 1700,
257 1700,
258 1700,
259 1700,
260 1800,
261 1900,
262 2000,
263 2100,
264 2200,
265 2300,
266 2400,
267 2500,
268 2600,
269 2700,
270 2800,
271 2900,
272 3000,
273 3100,
274 3200,
275 3300,
276};
277
278static const uint16_t ldo3_voltage_table[] = {
279 1700,
280 1700,
281 1700,
282 1700,
283 1700,
284 1700,
285 1700,
286 1700,
287 1700,
288 1800,
289 1900,
290 2000,
291 2100,
292 2200,
293 2300,
294 2400,
295 2500,
296 2600,
297 2700,
298 2800,
299 2900,
300 3000,
301 3100,
302 3200,
303 3300,
304 3300,
305 3300,
306 3300,
307 3300,
308 3300,
309 3300,
310 0xFFFF, /* VREFDDR */
311};
312
313static const uint16_t ldo5_voltage_table[] = {
314 1700,
315 1700,
316 1700,
317 1700,
318 1700,
319 1700,
320 1700,
321 1700,
322 1700,
323 1800,
324 1900,
325 2000,
326 2100,
327 2200,
328 2300,
329 2400,
330 2500,
331 2600,
332 2700,
333 2800,
334 2900,
335 3000,
336 3100,
337 3200,
338 3300,
339 3400,
340 3500,
341 3600,
342 3700,
343 3800,
344 3900,
345};
346
347static const uint16_t ldo6_voltage_table[] = {
348 900,
349 1000,
350 1100,
351 1200,
352 1300,
353 1400,
354 1500,
355 1600,
356 1700,
357 1800,
358 1900,
359 2000,
360 2100,
361 2200,
362 2300,
363 2400,
364 2500,
365 2600,
366 2700,
367 2800,
368 2900,
369 3000,
370 3100,
371 3200,
372 3300,
373};
374
375static const uint16_t ldo4_voltage_table[] = {
376 3300,
377};
378
379static const uint16_t vref_ddr_voltage_table[] = {
380 3300,
381};
382
383/* Table of Regulators in PMIC SoC */
384static const struct regul_struct regulators_table[] = {
385 {
386 .dt_node_name = "buck1",
387 .voltage_table = buck1_voltage_table,
388 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
389 .control_reg = BUCK1_CONTROL_REG,
390 .low_power_reg = BUCK1_PWRCTRL_REG,
391 },
392 {
393 .dt_node_name = "buck2",
394 .voltage_table = buck2_voltage_table,
395 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
396 .control_reg = BUCK2_CONTROL_REG,
397 .low_power_reg = BUCK2_PWRCTRL_REG,
398 },
399 {
400 .dt_node_name = "buck3",
401 .voltage_table = buck3_voltage_table,
402 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
403 .control_reg = BUCK3_CONTROL_REG,
404 .low_power_reg = BUCK3_PWRCTRL_REG,
405 },
406 {
407 .dt_node_name = "buck4",
408 .voltage_table = buck4_voltage_table,
409 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
410 .control_reg = BUCK4_CONTROL_REG,
411 .low_power_reg = BUCK4_PWRCTRL_REG,
412 },
413 {
414 .dt_node_name = "ldo1",
415 .voltage_table = ldo1_voltage_table,
416 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
417 .control_reg = LDO1_CONTROL_REG,
418 .low_power_reg = LDO1_PWRCTRL_REG,
419 },
420 {
421 .dt_node_name = "ldo2",
422 .voltage_table = ldo2_voltage_table,
423 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
424 .control_reg = LDO2_CONTROL_REG,
425 .low_power_reg = LDO2_PWRCTRL_REG,
426 },
427 {
428 .dt_node_name = "ldo3",
429 .voltage_table = ldo3_voltage_table,
430 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
431 .control_reg = LDO3_CONTROL_REG,
432 .low_power_reg = LDO3_PWRCTRL_REG,
433 },
434 {
435 .dt_node_name = "ldo4",
436 .voltage_table = ldo4_voltage_table,
437 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
438 .control_reg = LDO4_CONTROL_REG,
439 .low_power_reg = LDO4_PWRCTRL_REG,
440 },
441 {
442 .dt_node_name = "ldo5",
443 .voltage_table = ldo5_voltage_table,
444 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
445 .control_reg = LDO5_CONTROL_REG,
446 .low_power_reg = LDO5_PWRCTRL_REG,
447 },
448 {
449 .dt_node_name = "ldo6",
450 .voltage_table = ldo6_voltage_table,
451 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
452 .control_reg = LDO6_CONTROL_REG,
453 .low_power_reg = LDO6_PWRCTRL_REG,
454 },
455 {
456 .dt_node_name = "vref_ddr",
457 .voltage_table = vref_ddr_voltage_table,
458 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
459 .control_reg = VREF_DDR_CONTROL_REG,
460 .low_power_reg = VREF_DDR_PWRCTRL_REG,
461 },
462};
463
464#define MAX_REGUL ARRAY_SIZE(regulators_table)
465
466static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
467{
468 uint8_t i;
469
470 for (i = 0 ; i < MAX_REGUL ; i++) {
471 if (strncmp(name, regulators_table[i].dt_node_name,
472 strlen(regulators_table[i].dt_node_name)) == 0) {
473 return &regulators_table[i];
474 }
475 }
476
477 /* Regulator not found */
478 panic();
479 return NULL;
480}
481
482static uint8_t stpmu1_voltage_find_index(const char *name,
483 uint16_t millivolts)
484{
485 const struct regul_struct *regul = stpmu1_get_regulator_data(name);
486 uint8_t i;
487
488 for (i = 0 ; i < regul->voltage_table_size ; i++) {
489 if (regul->voltage_table[i] == millivolts) {
490 return i;
491 }
492 }
493
494 /* Voltage not found */
495 panic();
496
497 return 0;
498}
499
500int stpmu1_switch_off(void)
501{
502 return stpmu1_register_update(MAIN_CONTROL_REG, 1,
503 SOFTWARE_SWITCH_OFF_ENABLED);
504}
505
506int stpmu1_regulator_enable(const char *name)
507{
508 const struct regul_struct *regul = stpmu1_get_regulator_data(name);
509
510 return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0));
511}
512
513int stpmu1_regulator_disable(const char *name)
514{
515 const struct regul_struct *regul = stpmu1_get_regulator_data(name);
516
517 return stpmu1_register_update(regul->control_reg, 0, BIT(0));
518}
519
520uint8_t stpmu1_is_regulator_enabled(const char *name)
521{
522 uint8_t val;
523 const struct regul_struct *regul = stpmu1_get_regulator_data(name);
524
525 if (stpmu1_register_read(regul->control_reg, &val) != 0) {
526 panic();
527 }
528
529 return (val & 0x1U);
530}
531
532int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts)
533{
534 uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts);
535 const struct regul_struct *regul = stpmu1_get_regulator_data(name);
536
537 return stpmu1_register_update(regul->control_reg, voltage_index << 2,
538 0xFC);
539}
540
541int stpmu1_register_read(uint8_t register_id, uint8_t *value)
542{
543 return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr,
544 (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
545 value, 1, 100000);
546}
547
548int stpmu1_register_write(uint8_t register_id, uint8_t value)
549{
550 int status;
551
552 status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr,
553 (uint16_t)register_id,
554 I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
555
556 if (status != 0) {
557 return status;
558 }
559
560 if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
561 uint8_t readval;
562
563 status = stpmu1_register_read(register_id, &readval);
564 if (status != 0) {
565 return status;
566 }
567
568 if (readval != value) {
569 return -1;
570 }
571 }
572
573 return 0;
574}
575
576int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
577{
578 int status;
579 uint8_t val;
580
581 status = stpmu1_register_read(register_id, &val);
582 if (status != 0) {
583 return status;
584 }
585
586 /* Clear bits to update */
587 val &= ~mask;
588
589 /* Update appropriate bits*/
590 val |= (value & mask);
591
592 /* Send new value on I2C Bus */
593 return stpmu1_register_write(register_id, val);
594}
595
596void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
597{
598 stpmu_i2c_handle = i2c_handle;
599 stpmu_i2c_addr = i2c_addr;
600}