blob: 8a9eae16a2ebb8ac52c2fd7863dff5c2b50384fd [file] [log] [blame]
Yann Gautiere4f559f2018-07-16 17:55:07 +02001/*
Yann Gautier23684d02019-01-16 18:31:00 +01002 * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
Yann Gautiere4f559f2018-07-16 17:55:07 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautiere4f559f2018-07-16 17:55:07 +02007#include <string.h>
8
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +00009#include <common/debug.h>
Yann Gautier23684d02019-01-16 18:31:00 +010010#include <drivers/st/stpmic1.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000011#include <plat/common/platform.h>
12
Yann Gautiere4f559f2018-07-16 17:55:07 +020013struct regul_struct {
14 const char *dt_node_name;
15 const uint16_t *voltage_table;
16 uint8_t voltage_table_size;
17 uint8_t control_reg;
18 uint8_t low_power_reg;
19};
20
Yann Gautier23684d02019-01-16 18:31:00 +010021static struct i2c_handle_s *pmic_i2c_handle;
22static uint16_t pmic_i2c_addr;
Yann Gautiere4f559f2018-07-16 17:55:07 +020023
24/* Voltage tables in mV */
25static const uint16_t buck1_voltage_table[] = {
26 600,
27 625,
28 650,
29 675,
30 700,
31 725,
32 750,
33 775,
34 800,
35 825,
36 850,
37 875,
38 900,
39 925,
40 950,
41 975,
42 1000,
43 1025,
44 1050,
45 1075,
46 1100,
47 1125,
48 1150,
49 1175,
50 1200,
51 1225,
52 1250,
53 1275,
54 1300,
55 1325,
56 1350,
57 1350,
58};
59
60static const uint16_t buck2_voltage_table[] = {
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 1000,
79 1050,
80 1050,
81 1100,
82 1100,
83 1150,
84 1150,
85 1200,
86 1200,
87 1250,
88 1250,
89 1300,
90 1300,
91 1350,
92 1350,
93 1400,
94 1400,
95 1450,
96 1450,
97 1500,
98};
99
100static const uint16_t buck3_voltage_table[] = {
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 1000,
121 1100,
122 1100,
123 1100,
124 1100,
125 1200,
126 1200,
127 1200,
128 1200,
129 1300,
130 1300,
131 1300,
132 1300,
133 1400,
134 1400,
135 1400,
136 1400,
137 1500,
138 1600,
139 1700,
140 1800,
141 1900,
142 2000,
143 2100,
144 2200,
145 2300,
146 2400,
147 2500,
148 2600,
149 2700,
150 2800,
151 2900,
152 3000,
153 3100,
154 3200,
155 3300,
156 3400,
157};
158
159static const uint16_t buck4_voltage_table[] = {
160 600,
161 625,
162 650,
163 675,
164 700,
165 725,
166 750,
167 775,
168 800,
169 825,
170 850,
171 875,
172 900,
173 925,
174 950,
175 975,
176 1000,
177 1025,
178 1050,
179 1075,
180 1100,
181 1125,
182 1150,
183 1175,
184 1200,
185 1225,
186 1250,
187 1275,
188 1300,
189 1300,
190 1350,
191 1350,
192 1400,
193 1400,
194 1450,
195 1450,
196 1500,
197 1600,
198 1700,
199 1800,
200 1900,
201 2000,
202 2100,
203 2200,
204 2300,
205 2400,
206 2500,
207 2600,
208 2700,
209 2800,
210 2900,
211 3000,
212 3100,
213 3200,
214 3300,
215 3400,
216 3500,
217 3600,
218 3700,
219 3800,
220 3900,
221};
222
223static const uint16_t ldo1_voltage_table[] = {
224 1700,
225 1700,
226 1700,
227 1700,
228 1700,
229 1700,
230 1700,
231 1700,
232 1700,
233 1800,
234 1900,
235 2000,
236 2100,
237 2200,
238 2300,
239 2400,
240 2500,
241 2600,
242 2700,
243 2800,
244 2900,
245 3000,
246 3100,
247 3200,
248 3300,
249};
250
251static const uint16_t ldo2_voltage_table[] = {
252 1700,
253 1700,
254 1700,
255 1700,
256 1700,
257 1700,
258 1700,
259 1700,
260 1700,
261 1800,
262 1900,
263 2000,
264 2100,
265 2200,
266 2300,
267 2400,
268 2500,
269 2600,
270 2700,
271 2800,
272 2900,
273 3000,
274 3100,
275 3200,
276 3300,
277};
278
279static const uint16_t ldo3_voltage_table[] = {
280 1700,
281 1700,
282 1700,
283 1700,
284 1700,
285 1700,
286 1700,
287 1700,
288 1700,
289 1800,
290 1900,
291 2000,
292 2100,
293 2200,
294 2300,
295 2400,
296 2500,
297 2600,
298 2700,
299 2800,
300 2900,
301 3000,
302 3100,
303 3200,
304 3300,
305 3300,
306 3300,
307 3300,
308 3300,
309 3300,
310 3300,
311 0xFFFF, /* VREFDDR */
312};
313
314static const uint16_t ldo5_voltage_table[] = {
315 1700,
316 1700,
317 1700,
318 1700,
319 1700,
320 1700,
321 1700,
322 1700,
323 1700,
324 1800,
325 1900,
326 2000,
327 2100,
328 2200,
329 2300,
330 2400,
331 2500,
332 2600,
333 2700,
334 2800,
335 2900,
336 3000,
337 3100,
338 3200,
339 3300,
340 3400,
341 3500,
342 3600,
343 3700,
344 3800,
345 3900,
346};
347
348static const uint16_t ldo6_voltage_table[] = {
349 900,
350 1000,
351 1100,
352 1200,
353 1300,
354 1400,
355 1500,
356 1600,
357 1700,
358 1800,
359 1900,
360 2000,
361 2100,
362 2200,
363 2300,
364 2400,
365 2500,
366 2600,
367 2700,
368 2800,
369 2900,
370 3000,
371 3100,
372 3200,
373 3300,
374};
375
376static const uint16_t ldo4_voltage_table[] = {
377 3300,
378};
379
380static const uint16_t vref_ddr_voltage_table[] = {
381 3300,
382};
383
384/* Table of Regulators in PMIC SoC */
385static const struct regul_struct regulators_table[] = {
386 {
387 .dt_node_name = "buck1",
388 .voltage_table = buck1_voltage_table,
389 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
390 .control_reg = BUCK1_CONTROL_REG,
391 .low_power_reg = BUCK1_PWRCTRL_REG,
392 },
393 {
394 .dt_node_name = "buck2",
395 .voltage_table = buck2_voltage_table,
396 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
397 .control_reg = BUCK2_CONTROL_REG,
398 .low_power_reg = BUCK2_PWRCTRL_REG,
399 },
400 {
401 .dt_node_name = "buck3",
402 .voltage_table = buck3_voltage_table,
403 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
404 .control_reg = BUCK3_CONTROL_REG,
405 .low_power_reg = BUCK3_PWRCTRL_REG,
406 },
407 {
408 .dt_node_name = "buck4",
409 .voltage_table = buck4_voltage_table,
410 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
411 .control_reg = BUCK4_CONTROL_REG,
412 .low_power_reg = BUCK4_PWRCTRL_REG,
413 },
414 {
415 .dt_node_name = "ldo1",
416 .voltage_table = ldo1_voltage_table,
417 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
418 .control_reg = LDO1_CONTROL_REG,
419 .low_power_reg = LDO1_PWRCTRL_REG,
420 },
421 {
422 .dt_node_name = "ldo2",
423 .voltage_table = ldo2_voltage_table,
424 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
425 .control_reg = LDO2_CONTROL_REG,
426 .low_power_reg = LDO2_PWRCTRL_REG,
427 },
428 {
429 .dt_node_name = "ldo3",
430 .voltage_table = ldo3_voltage_table,
431 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
432 .control_reg = LDO3_CONTROL_REG,
433 .low_power_reg = LDO3_PWRCTRL_REG,
434 },
435 {
436 .dt_node_name = "ldo4",
437 .voltage_table = ldo4_voltage_table,
438 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
439 .control_reg = LDO4_CONTROL_REG,
440 .low_power_reg = LDO4_PWRCTRL_REG,
441 },
442 {
443 .dt_node_name = "ldo5",
444 .voltage_table = ldo5_voltage_table,
445 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
446 .control_reg = LDO5_CONTROL_REG,
447 .low_power_reg = LDO5_PWRCTRL_REG,
448 },
449 {
450 .dt_node_name = "ldo6",
451 .voltage_table = ldo6_voltage_table,
452 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
453 .control_reg = LDO6_CONTROL_REG,
454 .low_power_reg = LDO6_PWRCTRL_REG,
455 },
456 {
457 .dt_node_name = "vref_ddr",
458 .voltage_table = vref_ddr_voltage_table,
459 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
460 .control_reg = VREF_DDR_CONTROL_REG,
461 .low_power_reg = VREF_DDR_PWRCTRL_REG,
462 },
463};
464
Yann Gautier23684d02019-01-16 18:31:00 +0100465#define MAX_REGUL ARRAY_SIZE(regulators_table)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200466
Yann Gautier23684d02019-01-16 18:31:00 +0100467static const struct regul_struct *get_regulator_data(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200468{
469 uint8_t i;
470
471 for (i = 0 ; i < MAX_REGUL ; i++) {
472 if (strncmp(name, regulators_table[i].dt_node_name,
473 strlen(regulators_table[i].dt_node_name)) == 0) {
474 return &regulators_table[i];
475 }
476 }
477
478 /* Regulator not found */
479 panic();
480 return NULL;
481}
482
Yann Gautier23684d02019-01-16 18:31:00 +0100483static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200484{
Yann Gautier23684d02019-01-16 18:31:00 +0100485 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200486 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
Yann Gautier23684d02019-01-16 18:31:00 +0100500int stpmic1_switch_off(void)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200501{
Yann Gautier23684d02019-01-16 18:31:00 +0100502 return stpmic1_register_update(MAIN_CONTROL_REG, 1,
503 SOFTWARE_SWITCH_OFF_ENABLED);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200504}
505
Yann Gautier23684d02019-01-16 18:31:00 +0100506int stpmic1_regulator_enable(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200507{
Yann Gautier23684d02019-01-16 18:31:00 +0100508 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200509
Yann Gautier23684d02019-01-16 18:31:00 +0100510 return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
Yann Gautiere4f559f2018-07-16 17:55:07 +0200511}
512
Yann Gautier23684d02019-01-16 18:31:00 +0100513int stpmic1_regulator_disable(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200514{
Yann Gautier23684d02019-01-16 18:31:00 +0100515 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200516
Yann Gautier23684d02019-01-16 18:31:00 +0100517 return stpmic1_register_update(regul->control_reg, 0, BIT(0));
Yann Gautiere4f559f2018-07-16 17:55:07 +0200518}
519
Yann Gautier23684d02019-01-16 18:31:00 +0100520uint8_t stpmic1_is_regulator_enabled(const char *name)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200521{
522 uint8_t val;
Yann Gautier23684d02019-01-16 18:31:00 +0100523 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200524
Yann Gautier23684d02019-01-16 18:31:00 +0100525 if (stpmic1_register_read(regul->control_reg, &val) != 0) {
Yann Gautiere4f559f2018-07-16 17:55:07 +0200526 panic();
527 }
528
529 return (val & 0x1U);
530}
531
Yann Gautier23684d02019-01-16 18:31:00 +0100532int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200533{
Yann Gautier23684d02019-01-16 18:31:00 +0100534 uint8_t voltage_index = voltage_to_index(name, millivolts);
535 const struct regul_struct *regul = get_regulator_data(name);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200536
Yann Gautier23684d02019-01-16 18:31:00 +0100537 return stpmic1_register_update(regul->control_reg, voltage_index << 2,
538 0xFC);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200539}
540
Yann Gautier23684d02019-01-16 18:31:00 +0100541int stpmic1_register_read(uint8_t register_id, uint8_t *value)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200542{
Yann Gautier23684d02019-01-16 18:31:00 +0100543 return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
544 (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
545 value, 1, 100000);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200546}
547
Yann Gautier23684d02019-01-16 18:31:00 +0100548int stpmic1_register_write(uint8_t register_id, uint8_t value)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200549{
550 int status;
551
Yann Gautier23684d02019-01-16 18:31:00 +0100552 status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
Yann Gautiere4f559f2018-07-16 17:55:07 +0200553 (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
Yann Gautier23684d02019-01-16 18:31:00 +0100563 status = stpmic1_register_read(register_id, &readval);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200564 if (status != 0) {
565 return status;
566 }
567
568 if (readval != value) {
569 return -1;
570 }
571 }
572
573 return 0;
574}
575
Yann Gautier23684d02019-01-16 18:31:00 +0100576int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200577{
578 int status;
579 uint8_t val;
580
Yann Gautier23684d02019-01-16 18:31:00 +0100581 status = stpmic1_register_read(register_id, &val);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200582 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 */
Yann Gautier23684d02019-01-16 18:31:00 +0100593 return stpmic1_register_write(register_id, val);
Yann Gautiere4f559f2018-07-16 17:55:07 +0200594}
595
Yann Gautier23684d02019-01-16 18:31:00 +0100596void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
Yann Gautiere4f559f2018-07-16 17:55:07 +0200597{
Yann Gautier23684d02019-01-16 18:31:00 +0100598 pmic_i2c_handle = i2c_handle;
599 pmic_i2c_addr = i2c_addr;
Yann Gautiere4f559f2018-07-16 17:55:07 +0200600}