xref: /optee_os/core/drivers/stpmic1.c (revision e0f7e777c2b89c0de1d2d7d0d4fe67086fbbeaa0)
1c7cf2933SEtienne Carriere // SPDX-License-Identifier: BSD-3-Clause
2c7cf2933SEtienne Carriere /*
368cfb83dSEtienne Carriere  * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
4c7cf2933SEtienne Carriere  */
5c7cf2933SEtienne Carriere 
6c7cf2933SEtienne Carriere #include <assert.h>
7c7cf2933SEtienne Carriere #include <drivers/stpmic1.h>
8c7cf2933SEtienne Carriere #include <kernel/panic.h>
9c7cf2933SEtienne Carriere #include <platform_config.h>
10c7cf2933SEtienne Carriere #include <stdint.h>
11c7cf2933SEtienne Carriere #include <string.h>
12c7cf2933SEtienne Carriere #include <trace.h>
1342032ea0SEtienne Carriere #include <util.h>
14c7cf2933SEtienne Carriere 
156a63363bSEtienne Carriere #define VOLTAGE_INDEX_INVALID		((unsigned int)~0)
166a63363bSEtienne Carriere 
17c7cf2933SEtienne Carriere struct regul_struct {
18c7cf2933SEtienne Carriere 	const char *dt_node_name;
19c7cf2933SEtienne Carriere 	const uint16_t *voltage_table;
20c7cf2933SEtienne Carriere 	uint8_t voltage_table_size;
21c7cf2933SEtienne Carriere 	uint8_t control_reg;
22c7cf2933SEtienne Carriere 	uint8_t low_power_reg;
2368cfb83dSEtienne Carriere 	uint8_t enable_pos;
24c7cf2933SEtienne Carriere 	uint8_t pull_down_reg;
25c7cf2933SEtienne Carriere 	uint8_t pull_down_pos;
26c7cf2933SEtienne Carriere 	uint8_t mask_reset_reg;
27c7cf2933SEtienne Carriere 	uint8_t mask_reset_pos;
28c7cf2933SEtienne Carriere };
29c7cf2933SEtienne Carriere 
30c7cf2933SEtienne Carriere static struct i2c_handle_s *pmic_i2c_handle;
31c7cf2933SEtienne Carriere static uint16_t pmic_i2c_addr;
32c7cf2933SEtienne Carriere 
33c7cf2933SEtienne Carriere /* Voltage tables in mV */
34c7cf2933SEtienne Carriere static const uint16_t buck1_voltage_table[] = {
35c7cf2933SEtienne Carriere 	725,
36c7cf2933SEtienne Carriere 	725,
37c7cf2933SEtienne Carriere 	725,
38c7cf2933SEtienne Carriere 	725,
39c7cf2933SEtienne Carriere 	725,
40c7cf2933SEtienne Carriere 	725,
41c7cf2933SEtienne Carriere 	750,
42c7cf2933SEtienne Carriere 	775,
43c7cf2933SEtienne Carriere 	800,
44c7cf2933SEtienne Carriere 	825,
45c7cf2933SEtienne Carriere 	850,
46c7cf2933SEtienne Carriere 	875,
47c7cf2933SEtienne Carriere 	900,
48c7cf2933SEtienne Carriere 	925,
49c7cf2933SEtienne Carriere 	950,
50c7cf2933SEtienne Carriere 	975,
51c7cf2933SEtienne Carriere 	1000,
52c7cf2933SEtienne Carriere 	1025,
53c7cf2933SEtienne Carriere 	1050,
54c7cf2933SEtienne Carriere 	1075,
55c7cf2933SEtienne Carriere 	1100,
56c7cf2933SEtienne Carriere 	1125,
57c7cf2933SEtienne Carriere 	1150,
58c7cf2933SEtienne Carriere 	1175,
59c7cf2933SEtienne Carriere 	1200,
60c7cf2933SEtienne Carriere 	1225,
61c7cf2933SEtienne Carriere 	1250,
62c7cf2933SEtienne Carriere 	1275,
63c7cf2933SEtienne Carriere 	1300,
64c7cf2933SEtienne Carriere 	1325,
65c7cf2933SEtienne Carriere 	1350,
66c7cf2933SEtienne Carriere 	1375,
67c7cf2933SEtienne Carriere 	1400,
68c7cf2933SEtienne Carriere 	1425,
69c7cf2933SEtienne Carriere 	1450,
70c7cf2933SEtienne Carriere 	1475,
71c7cf2933SEtienne Carriere 	1500,
72c7cf2933SEtienne Carriere 	1500,
73c7cf2933SEtienne Carriere 	1500,
74c7cf2933SEtienne Carriere 	1500,
75c7cf2933SEtienne Carriere 	1500,
76c7cf2933SEtienne Carriere 	1500,
77c7cf2933SEtienne Carriere 	1500,
78c7cf2933SEtienne Carriere 	1500,
79c7cf2933SEtienne Carriere 	1500,
80c7cf2933SEtienne Carriere 	1500,
81c7cf2933SEtienne Carriere 	1500,
82c7cf2933SEtienne Carriere 	1500,
83c7cf2933SEtienne Carriere 	1500,
84c7cf2933SEtienne Carriere 	1500,
85c7cf2933SEtienne Carriere 	1500,
86c7cf2933SEtienne Carriere 	1500,
87c7cf2933SEtienne Carriere 	1500,
88c7cf2933SEtienne Carriere 	1500,
89c7cf2933SEtienne Carriere 	1500,
90c7cf2933SEtienne Carriere 	1500,
91c7cf2933SEtienne Carriere 	1500,
92c7cf2933SEtienne Carriere 	1500,
93c7cf2933SEtienne Carriere 	1500,
94c7cf2933SEtienne Carriere 	1500,
95c7cf2933SEtienne Carriere 	1500,
96c7cf2933SEtienne Carriere 	1500,
97c7cf2933SEtienne Carriere 	1500,
98c7cf2933SEtienne Carriere 	1500,
99c7cf2933SEtienne Carriere };
100c7cf2933SEtienne Carriere 
101c7cf2933SEtienne Carriere static const uint16_t buck2_voltage_table[] = {
102c7cf2933SEtienne Carriere 	1000,
103c7cf2933SEtienne Carriere 	1000,
104c7cf2933SEtienne Carriere 	1000,
105c7cf2933SEtienne Carriere 	1000,
106c7cf2933SEtienne Carriere 	1000,
107c7cf2933SEtienne Carriere 	1000,
108c7cf2933SEtienne Carriere 	1000,
109c7cf2933SEtienne Carriere 	1000,
110c7cf2933SEtienne Carriere 	1000,
111c7cf2933SEtienne Carriere 	1000,
112c7cf2933SEtienne Carriere 	1000,
113c7cf2933SEtienne Carriere 	1000,
114c7cf2933SEtienne Carriere 	1000,
115c7cf2933SEtienne Carriere 	1000,
116c7cf2933SEtienne Carriere 	1000,
117c7cf2933SEtienne Carriere 	1000,
118c7cf2933SEtienne Carriere 	1000,
119c7cf2933SEtienne Carriere 	1000,
120c7cf2933SEtienne Carriere 	1050,
121c7cf2933SEtienne Carriere 	1050,
122c7cf2933SEtienne Carriere 	1100,
123c7cf2933SEtienne Carriere 	1100,
124c7cf2933SEtienne Carriere 	1150,
125c7cf2933SEtienne Carriere 	1150,
126c7cf2933SEtienne Carriere 	1200,
127c7cf2933SEtienne Carriere 	1200,
128c7cf2933SEtienne Carriere 	1250,
129c7cf2933SEtienne Carriere 	1250,
130c7cf2933SEtienne Carriere 	1300,
131c7cf2933SEtienne Carriere 	1300,
132c7cf2933SEtienne Carriere 	1350,
133c7cf2933SEtienne Carriere 	1350,
134c7cf2933SEtienne Carriere 	1400,
135c7cf2933SEtienne Carriere 	1400,
136c7cf2933SEtienne Carriere 	1450,
137c7cf2933SEtienne Carriere 	1450,
138c7cf2933SEtienne Carriere 	1500,
139c7cf2933SEtienne Carriere };
140c7cf2933SEtienne Carriere 
141c7cf2933SEtienne Carriere static const uint16_t buck3_voltage_table[] = {
142c7cf2933SEtienne Carriere 	1000,
143c7cf2933SEtienne Carriere 	1000,
144c7cf2933SEtienne Carriere 	1000,
145c7cf2933SEtienne Carriere 	1000,
146c7cf2933SEtienne Carriere 	1000,
147c7cf2933SEtienne Carriere 	1000,
148c7cf2933SEtienne Carriere 	1000,
149c7cf2933SEtienne Carriere 	1000,
150c7cf2933SEtienne Carriere 	1000,
151c7cf2933SEtienne Carriere 	1000,
152c7cf2933SEtienne Carriere 	1000,
153c7cf2933SEtienne Carriere 	1000,
154c7cf2933SEtienne Carriere 	1000,
155c7cf2933SEtienne Carriere 	1000,
156c7cf2933SEtienne Carriere 	1000,
157c7cf2933SEtienne Carriere 	1000,
158c7cf2933SEtienne Carriere 	1000,
159c7cf2933SEtienne Carriere 	1000,
160c7cf2933SEtienne Carriere 	1000,
161c7cf2933SEtienne Carriere 	1000,
162c7cf2933SEtienne Carriere 	1100,
163c7cf2933SEtienne Carriere 	1100,
164c7cf2933SEtienne Carriere 	1100,
165c7cf2933SEtienne Carriere 	1100,
166c7cf2933SEtienne Carriere 	1200,
167c7cf2933SEtienne Carriere 	1200,
168c7cf2933SEtienne Carriere 	1200,
169c7cf2933SEtienne Carriere 	1200,
170c7cf2933SEtienne Carriere 	1300,
171c7cf2933SEtienne Carriere 	1300,
172c7cf2933SEtienne Carriere 	1300,
173c7cf2933SEtienne Carriere 	1300,
174c7cf2933SEtienne Carriere 	1400,
175c7cf2933SEtienne Carriere 	1400,
176c7cf2933SEtienne Carriere 	1400,
177c7cf2933SEtienne Carriere 	1400,
178c7cf2933SEtienne Carriere 	1500,
179c7cf2933SEtienne Carriere 	1600,
180c7cf2933SEtienne Carriere 	1700,
181c7cf2933SEtienne Carriere 	1800,
182c7cf2933SEtienne Carriere 	1900,
183c7cf2933SEtienne Carriere 	2000,
184c7cf2933SEtienne Carriere 	2100,
185c7cf2933SEtienne Carriere 	2200,
186c7cf2933SEtienne Carriere 	2300,
187c7cf2933SEtienne Carriere 	2400,
188c7cf2933SEtienne Carriere 	2500,
189c7cf2933SEtienne Carriere 	2600,
190c7cf2933SEtienne Carriere 	2700,
191c7cf2933SEtienne Carriere 	2800,
192c7cf2933SEtienne Carriere 	2900,
193c7cf2933SEtienne Carriere 	3000,
194c7cf2933SEtienne Carriere 	3100,
195c7cf2933SEtienne Carriere 	3200,
196c7cf2933SEtienne Carriere 	3300,
197c7cf2933SEtienne Carriere 	3400,
198c7cf2933SEtienne Carriere };
199c7cf2933SEtienne Carriere 
200c7cf2933SEtienne Carriere static const uint16_t buck4_voltage_table[] = {
201c7cf2933SEtienne Carriere 	600,
202c7cf2933SEtienne Carriere 	625,
203c7cf2933SEtienne Carriere 	650,
204c7cf2933SEtienne Carriere 	675,
205c7cf2933SEtienne Carriere 	700,
206c7cf2933SEtienne Carriere 	725,
207c7cf2933SEtienne Carriere 	750,
208c7cf2933SEtienne Carriere 	775,
209c7cf2933SEtienne Carriere 	800,
210c7cf2933SEtienne Carriere 	825,
211c7cf2933SEtienne Carriere 	850,
212c7cf2933SEtienne Carriere 	875,
213c7cf2933SEtienne Carriere 	900,
214c7cf2933SEtienne Carriere 	925,
215c7cf2933SEtienne Carriere 	950,
216c7cf2933SEtienne Carriere 	975,
217c7cf2933SEtienne Carriere 	1000,
218c7cf2933SEtienne Carriere 	1025,
219c7cf2933SEtienne Carriere 	1050,
220c7cf2933SEtienne Carriere 	1075,
221c7cf2933SEtienne Carriere 	1100,
222c7cf2933SEtienne Carriere 	1125,
223c7cf2933SEtienne Carriere 	1150,
224c7cf2933SEtienne Carriere 	1175,
225c7cf2933SEtienne Carriere 	1200,
226c7cf2933SEtienne Carriere 	1225,
227c7cf2933SEtienne Carriere 	1250,
228c7cf2933SEtienne Carriere 	1275,
229c7cf2933SEtienne Carriere 	1300,
230c7cf2933SEtienne Carriere 	1300,
231c7cf2933SEtienne Carriere 	1350,
232c7cf2933SEtienne Carriere 	1350,
233c7cf2933SEtienne Carriere 	1400,
234c7cf2933SEtienne Carriere 	1400,
235c7cf2933SEtienne Carriere 	1450,
236c7cf2933SEtienne Carriere 	1450,
237c7cf2933SEtienne Carriere 	1500,
238c7cf2933SEtienne Carriere 	1600,
239c7cf2933SEtienne Carriere 	1700,
240c7cf2933SEtienne Carriere 	1800,
241c7cf2933SEtienne Carriere 	1900,
242c7cf2933SEtienne Carriere 	2000,
243c7cf2933SEtienne Carriere 	2100,
244c7cf2933SEtienne Carriere 	2200,
245c7cf2933SEtienne Carriere 	2300,
246c7cf2933SEtienne Carriere 	2400,
247c7cf2933SEtienne Carriere 	2500,
248c7cf2933SEtienne Carriere 	2600,
249c7cf2933SEtienne Carriere 	2700,
250c7cf2933SEtienne Carriere 	2800,
251c7cf2933SEtienne Carriere 	2900,
252c7cf2933SEtienne Carriere 	3000,
253c7cf2933SEtienne Carriere 	3100,
254c7cf2933SEtienne Carriere 	3200,
255c7cf2933SEtienne Carriere 	3300,
256c7cf2933SEtienne Carriere 	3400,
257c7cf2933SEtienne Carriere 	3500,
258c7cf2933SEtienne Carriere 	3600,
259c7cf2933SEtienne Carriere 	3700,
260c7cf2933SEtienne Carriere 	3800,
261c7cf2933SEtienne Carriere 	3900,
262c7cf2933SEtienne Carriere };
263c7cf2933SEtienne Carriere 
264c7cf2933SEtienne Carriere static const uint16_t ldo1_voltage_table[] = {
265c7cf2933SEtienne Carriere 	1700,
266c7cf2933SEtienne Carriere 	1700,
267c7cf2933SEtienne Carriere 	1700,
268c7cf2933SEtienne Carriere 	1700,
269c7cf2933SEtienne Carriere 	1700,
270c7cf2933SEtienne Carriere 	1700,
271c7cf2933SEtienne Carriere 	1700,
272c7cf2933SEtienne Carriere 	1700,
273c7cf2933SEtienne Carriere 	1700,
274c7cf2933SEtienne Carriere 	1800,
275c7cf2933SEtienne Carriere 	1900,
276c7cf2933SEtienne Carriere 	2000,
277c7cf2933SEtienne Carriere 	2100,
278c7cf2933SEtienne Carriere 	2200,
279c7cf2933SEtienne Carriere 	2300,
280c7cf2933SEtienne Carriere 	2400,
281c7cf2933SEtienne Carriere 	2500,
282c7cf2933SEtienne Carriere 	2600,
283c7cf2933SEtienne Carriere 	2700,
284c7cf2933SEtienne Carriere 	2800,
285c7cf2933SEtienne Carriere 	2900,
286c7cf2933SEtienne Carriere 	3000,
287c7cf2933SEtienne Carriere 	3100,
288c7cf2933SEtienne Carriere 	3200,
289c7cf2933SEtienne Carriere 	3300,
290c7cf2933SEtienne Carriere };
291c7cf2933SEtienne Carriere 
292c7cf2933SEtienne Carriere static const uint16_t ldo2_voltage_table[] = {
293c7cf2933SEtienne Carriere 	1700,
294c7cf2933SEtienne Carriere 	1700,
295c7cf2933SEtienne Carriere 	1700,
296c7cf2933SEtienne Carriere 	1700,
297c7cf2933SEtienne Carriere 	1700,
298c7cf2933SEtienne Carriere 	1700,
299c7cf2933SEtienne Carriere 	1700,
300c7cf2933SEtienne Carriere 	1700,
301c7cf2933SEtienne Carriere 	1700,
302c7cf2933SEtienne Carriere 	1800,
303c7cf2933SEtienne Carriere 	1900,
304c7cf2933SEtienne Carriere 	2000,
305c7cf2933SEtienne Carriere 	2100,
306c7cf2933SEtienne Carriere 	2200,
307c7cf2933SEtienne Carriere 	2300,
308c7cf2933SEtienne Carriere 	2400,
309c7cf2933SEtienne Carriere 	2500,
310c7cf2933SEtienne Carriere 	2600,
311c7cf2933SEtienne Carriere 	2700,
312c7cf2933SEtienne Carriere 	2800,
313c7cf2933SEtienne Carriere 	2900,
314c7cf2933SEtienne Carriere 	3000,
315c7cf2933SEtienne Carriere 	3100,
316c7cf2933SEtienne Carriere 	3200,
317c7cf2933SEtienne Carriere 	3300,
318c7cf2933SEtienne Carriere };
319c7cf2933SEtienne Carriere 
320c7cf2933SEtienne Carriere static const uint16_t ldo3_voltage_table[] = {
321c7cf2933SEtienne Carriere 	1700,
322c7cf2933SEtienne Carriere 	1700,
323c7cf2933SEtienne Carriere 	1700,
324c7cf2933SEtienne Carriere 	1700,
325c7cf2933SEtienne Carriere 	1700,
326c7cf2933SEtienne Carriere 	1700,
327c7cf2933SEtienne Carriere 	1700,
328c7cf2933SEtienne Carriere 	1700,
329c7cf2933SEtienne Carriere 	1700,
330c7cf2933SEtienne Carriere 	1800,
331c7cf2933SEtienne Carriere 	1900,
332c7cf2933SEtienne Carriere 	2000,
333c7cf2933SEtienne Carriere 	2100,
334c7cf2933SEtienne Carriere 	2200,
335c7cf2933SEtienne Carriere 	2300,
336c7cf2933SEtienne Carriere 	2400,
337c7cf2933SEtienne Carriere 	2500,
338c7cf2933SEtienne Carriere 	2600,
339c7cf2933SEtienne Carriere 	2700,
340c7cf2933SEtienne Carriere 	2800,
341c7cf2933SEtienne Carriere 	2900,
342c7cf2933SEtienne Carriere 	3000,
343c7cf2933SEtienne Carriere 	3100,
344c7cf2933SEtienne Carriere 	3200,
345c7cf2933SEtienne Carriere 	3300,
346c7cf2933SEtienne Carriere 	3300,
347c7cf2933SEtienne Carriere 	3300,
348c7cf2933SEtienne Carriere 	3300,
349c7cf2933SEtienne Carriere 	3300,
350c7cf2933SEtienne Carriere 	3300,
351c7cf2933SEtienne Carriere 	3300,
352f7e28951SEtienne Carriere 	500,	/* VOUT2/2 (Sink/source mode) */
353c7cf2933SEtienne Carriere 	0xFFFF, /* VREFDDR */
354c7cf2933SEtienne Carriere };
355c7cf2933SEtienne Carriere 
356c7cf2933SEtienne Carriere static const uint16_t ldo5_voltage_table[] = {
357c7cf2933SEtienne Carriere 	1700,
358c7cf2933SEtienne Carriere 	1700,
359c7cf2933SEtienne Carriere 	1700,
360c7cf2933SEtienne Carriere 	1700,
361c7cf2933SEtienne Carriere 	1700,
362c7cf2933SEtienne Carriere 	1700,
363c7cf2933SEtienne Carriere 	1700,
364c7cf2933SEtienne Carriere 	1700,
365c7cf2933SEtienne Carriere 	1700,
366c7cf2933SEtienne Carriere 	1800,
367c7cf2933SEtienne Carriere 	1900,
368c7cf2933SEtienne Carriere 	2000,
369c7cf2933SEtienne Carriere 	2100,
370c7cf2933SEtienne Carriere 	2200,
371c7cf2933SEtienne Carriere 	2300,
372c7cf2933SEtienne Carriere 	2400,
373c7cf2933SEtienne Carriere 	2500,
374c7cf2933SEtienne Carriere 	2600,
375c7cf2933SEtienne Carriere 	2700,
376c7cf2933SEtienne Carriere 	2800,
377c7cf2933SEtienne Carriere 	2900,
378c7cf2933SEtienne Carriere 	3000,
379c7cf2933SEtienne Carriere 	3100,
380c7cf2933SEtienne Carriere 	3200,
381c7cf2933SEtienne Carriere 	3300,
382c7cf2933SEtienne Carriere 	3400,
383c7cf2933SEtienne Carriere 	3500,
384c7cf2933SEtienne Carriere 	3600,
385c7cf2933SEtienne Carriere 	3700,
386c7cf2933SEtienne Carriere 	3800,
387c7cf2933SEtienne Carriere 	3900,
388c7cf2933SEtienne Carriere };
389c7cf2933SEtienne Carriere 
390c7cf2933SEtienne Carriere static const uint16_t ldo6_voltage_table[] = {
391c7cf2933SEtienne Carriere 	900,
392c7cf2933SEtienne Carriere 	1000,
393c7cf2933SEtienne Carriere 	1100,
394c7cf2933SEtienne Carriere 	1200,
395c7cf2933SEtienne Carriere 	1300,
396c7cf2933SEtienne Carriere 	1400,
397c7cf2933SEtienne Carriere 	1500,
398c7cf2933SEtienne Carriere 	1600,
399c7cf2933SEtienne Carriere 	1700,
400c7cf2933SEtienne Carriere 	1800,
401c7cf2933SEtienne Carriere 	1900,
402c7cf2933SEtienne Carriere 	2000,
403c7cf2933SEtienne Carriere 	2100,
404c7cf2933SEtienne Carriere 	2200,
405c7cf2933SEtienne Carriere 	2300,
406c7cf2933SEtienne Carriere 	2400,
407c7cf2933SEtienne Carriere 	2500,
408c7cf2933SEtienne Carriere 	2600,
409c7cf2933SEtienne Carriere 	2700,
410c7cf2933SEtienne Carriere 	2800,
411c7cf2933SEtienne Carriere 	2900,
412c7cf2933SEtienne Carriere 	3000,
413c7cf2933SEtienne Carriere 	3100,
414c7cf2933SEtienne Carriere 	3200,
415c7cf2933SEtienne Carriere 	3300,
416c7cf2933SEtienne Carriere };
417c7cf2933SEtienne Carriere 
418c7cf2933SEtienne Carriere static const uint16_t ldo4_voltage_table[] = {
419c7cf2933SEtienne Carriere 	3300,
420c7cf2933SEtienne Carriere };
421c7cf2933SEtienne Carriere 
422c7cf2933SEtienne Carriere static const uint16_t vref_ddr_voltage_table[] = {
423c7cf2933SEtienne Carriere 	3300,
424c7cf2933SEtienne Carriere };
425c7cf2933SEtienne Carriere 
4263f692bdfSEtienne Carriere static const uint16_t fixed_5v_voltage_table[] = {
4273f692bdfSEtienne Carriere 	5000,
4283f692bdfSEtienne Carriere };
4293f692bdfSEtienne Carriere 
430c7cf2933SEtienne Carriere /* Table of Regulators in PMIC SoC */
431c7cf2933SEtienne Carriere static const struct regul_struct regulators_table[] = {
432c7cf2933SEtienne Carriere 	{
433c7cf2933SEtienne Carriere 		.dt_node_name	= "buck1",
434c7cf2933SEtienne Carriere 		.voltage_table	= buck1_voltage_table,
435c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
436c7cf2933SEtienne Carriere 		.control_reg	= BUCK1_CONTROL_REG,
437c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK1_PWRCTRL_REG,
43868cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
439c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
440c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK1_PULL_DOWN_SHIFT,
441c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
442c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK1_MASK_RESET_SHIFT,
443c7cf2933SEtienne Carriere 	},
444c7cf2933SEtienne Carriere 	{
445c7cf2933SEtienne Carriere 		.dt_node_name	= "buck2",
446c7cf2933SEtienne Carriere 		.voltage_table	= buck2_voltage_table,
447c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
448c7cf2933SEtienne Carriere 		.control_reg	= BUCK2_CONTROL_REG,
449c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK2_PWRCTRL_REG,
45068cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
451c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
452c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK2_PULL_DOWN_SHIFT,
453c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
454c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK2_MASK_RESET_SHIFT,
455c7cf2933SEtienne Carriere 	},
456c7cf2933SEtienne Carriere 	{
457c7cf2933SEtienne Carriere 		.dt_node_name	= "buck3",
458c7cf2933SEtienne Carriere 		.voltage_table	= buck3_voltage_table,
459c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
460c7cf2933SEtienne Carriere 		.control_reg	= BUCK3_CONTROL_REG,
461c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK3_PWRCTRL_REG,
46268cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
463c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
464c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK3_PULL_DOWN_SHIFT,
465c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
466c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK3_MASK_RESET_SHIFT,
467c7cf2933SEtienne Carriere 	},
468c7cf2933SEtienne Carriere 	{
469c7cf2933SEtienne Carriere 		.dt_node_name	= "buck4",
470c7cf2933SEtienne Carriere 		.voltage_table	= buck4_voltage_table,
471c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
472c7cf2933SEtienne Carriere 		.control_reg	= BUCK4_CONTROL_REG,
473c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK4_PWRCTRL_REG,
47468cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
475c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
476c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK4_PULL_DOWN_SHIFT,
477c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
478c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK4_MASK_RESET_SHIFT,
479c7cf2933SEtienne Carriere 	},
480c7cf2933SEtienne Carriere 	{
481c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo1",
482c7cf2933SEtienne Carriere 		.voltage_table	= ldo1_voltage_table,
483c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
484c7cf2933SEtienne Carriere 		.control_reg	= LDO1_CONTROL_REG,
485c7cf2933SEtienne Carriere 		.low_power_reg	= LDO1_PWRCTRL_REG,
48668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
487c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
488c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO1_MASK_RESET_SHIFT,
489c7cf2933SEtienne Carriere 	},
490c7cf2933SEtienne Carriere 	{
491c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo2",
492c7cf2933SEtienne Carriere 		.voltage_table	= ldo2_voltage_table,
493c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
494c7cf2933SEtienne Carriere 		.control_reg	= LDO2_CONTROL_REG,
495c7cf2933SEtienne Carriere 		.low_power_reg	= LDO2_PWRCTRL_REG,
49668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
497c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
498c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO2_MASK_RESET_SHIFT,
499c7cf2933SEtienne Carriere 	},
500c7cf2933SEtienne Carriere 	{
501c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo3",
502c7cf2933SEtienne Carriere 		.voltage_table	= ldo3_voltage_table,
503c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
504c7cf2933SEtienne Carriere 		.control_reg	= LDO3_CONTROL_REG,
505c7cf2933SEtienne Carriere 		.low_power_reg	= LDO3_PWRCTRL_REG,
50668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
507c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
508c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO3_MASK_RESET_SHIFT,
509c7cf2933SEtienne Carriere 	},
510c7cf2933SEtienne Carriere 	{
511c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo4",
512c7cf2933SEtienne Carriere 		.voltage_table	= ldo4_voltage_table,
513c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
514c7cf2933SEtienne Carriere 		.control_reg	= LDO4_CONTROL_REG,
515c7cf2933SEtienne Carriere 		.low_power_reg	= LDO4_PWRCTRL_REG,
51668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
517c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
518c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO4_MASK_RESET_SHIFT,
519c7cf2933SEtienne Carriere 	},
520c7cf2933SEtienne Carriere 	{
521c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo5",
522c7cf2933SEtienne Carriere 		.voltage_table	= ldo5_voltage_table,
523c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
524c7cf2933SEtienne Carriere 		.control_reg	= LDO5_CONTROL_REG,
525c7cf2933SEtienne Carriere 		.low_power_reg	= LDO5_PWRCTRL_REG,
52668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
527c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
528c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO5_MASK_RESET_SHIFT,
529c7cf2933SEtienne Carriere 	},
530c7cf2933SEtienne Carriere 	{
531c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo6",
532c7cf2933SEtienne Carriere 		.voltage_table	= ldo6_voltage_table,
533c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
534c7cf2933SEtienne Carriere 		.control_reg	= LDO6_CONTROL_REG,
535c7cf2933SEtienne Carriere 		.low_power_reg	= LDO6_PWRCTRL_REG,
53668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
537c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
538c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO6_MASK_RESET_SHIFT,
539c7cf2933SEtienne Carriere 	},
540c7cf2933SEtienne Carriere 	{
541c7cf2933SEtienne Carriere 		.dt_node_name	= "vref_ddr",
542c7cf2933SEtienne Carriere 		.voltage_table	= vref_ddr_voltage_table,
543c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
544c7cf2933SEtienne Carriere 		.control_reg	= VREF_DDR_CONTROL_REG,
545c7cf2933SEtienne Carriere 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
54668cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
547c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
548c7cf2933SEtienne Carriere 		.mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT,
549c7cf2933SEtienne Carriere 	},
550c7cf2933SEtienne Carriere 	{
551c7cf2933SEtienne Carriere 		.dt_node_name = "boost",
5523f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5533f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5543f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5553f692bdfSEtienne Carriere 		.enable_pos	= BOOST_ENABLED_POS,
556c7cf2933SEtienne Carriere 	},
557c7cf2933SEtienne Carriere 	{
558c7cf2933SEtienne Carriere 		.dt_node_name	= "pwr_sw1",
5593f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5603f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5613f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5623f692bdfSEtienne Carriere 		.enable_pos	= USBSW_OTG_SWITCH_ENABLED_POS,
563c7cf2933SEtienne Carriere 	},
564c7cf2933SEtienne Carriere 	{
565c7cf2933SEtienne Carriere 		.dt_node_name	= "pwr_sw2",
5663f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5673f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5683f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5693f692bdfSEtienne Carriere 		.enable_pos	= SWIN_SWOUT_ENABLED_POS,
570c7cf2933SEtienne Carriere 	},
571c7cf2933SEtienne Carriere };
572c7cf2933SEtienne Carriere 
573c7cf2933SEtienne Carriere static const struct regul_struct *get_regulator_data(const char *name)
574c7cf2933SEtienne Carriere {
575c7cf2933SEtienne Carriere 	unsigned int i = 0;
576c7cf2933SEtienne Carriere 
577c7cf2933SEtienne Carriere 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++)
578c7cf2933SEtienne Carriere 		if (strcmp(name, regulators_table[i].dt_node_name) == 0)
579c7cf2933SEtienne Carriere 			return &regulators_table[i];
580c7cf2933SEtienne Carriere 
5816a63363bSEtienne Carriere 	DMSG("Regulator %s not found", name);
5826a63363bSEtienne Carriere 	return NULL;
583c7cf2933SEtienne Carriere }
584c7cf2933SEtienne Carriere 
585*e0f7e777SEtienne Carriere bool stpmic1_regulator_is_valid(const char *name)
586*e0f7e777SEtienne Carriere {
587*e0f7e777SEtienne Carriere 	return get_regulator_data(name);
588*e0f7e777SEtienne Carriere }
589*e0f7e777SEtienne Carriere 
590c52a7c2eSEtienne Carriere TEE_Result stpmic1_regulator_levels_mv(const char *name,
591c52a7c2eSEtienne Carriere 				       const uint16_t **levels,
592c52a7c2eSEtienne Carriere 				       size_t *levels_count)
593c52a7c2eSEtienne Carriere {
594c52a7c2eSEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
595c52a7c2eSEtienne Carriere 
596c52a7c2eSEtienne Carriere 	if (!regul)
597c52a7c2eSEtienne Carriere 		return TEE_ERROR_BAD_PARAMETERS;
598c52a7c2eSEtienne Carriere 
599c52a7c2eSEtienne Carriere 	if (levels_count)
600c52a7c2eSEtienne Carriere 		*levels_count = regul->voltage_table_size;
601c52a7c2eSEtienne Carriere 
602c52a7c2eSEtienne Carriere 	if (levels)
603c52a7c2eSEtienne Carriere 		*levels = regul->voltage_table;
604c52a7c2eSEtienne Carriere 
605c52a7c2eSEtienne Carriere 	return TEE_SUCCESS;
606c52a7c2eSEtienne Carriere }
607c52a7c2eSEtienne Carriere 
6086a63363bSEtienne Carriere static size_t voltage_to_index(const char *name, uint16_t millivolts)
609c7cf2933SEtienne Carriere {
610c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
611c7cf2933SEtienne Carriere 	unsigned int i = 0;
612c7cf2933SEtienne Carriere 
613c7cf2933SEtienne Carriere 	assert(regul->voltage_table);
614c7cf2933SEtienne Carriere 	for (i = 0; i < regul->voltage_table_size; i++)
615c7cf2933SEtienne Carriere 		if (regul->voltage_table[i] == millivolts)
616c7cf2933SEtienne Carriere 			return i;
617c7cf2933SEtienne Carriere 
6186a63363bSEtienne Carriere 	return VOLTAGE_INDEX_INVALID;
619c7cf2933SEtienne Carriere }
620c7cf2933SEtienne Carriere 
621c7cf2933SEtienne Carriere int stpmic1_powerctrl_on(void)
622c7cf2933SEtienne Carriere {
623c7cf2933SEtienne Carriere 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
624c7cf2933SEtienne Carriere 				       PWRCTRL_PIN_VALID);
625c7cf2933SEtienne Carriere }
626c7cf2933SEtienne Carriere 
627c7cf2933SEtienne Carriere int stpmic1_switch_off(void)
628c7cf2933SEtienne Carriere {
629c7cf2933SEtienne Carriere 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
630c7cf2933SEtienne Carriere 				       SOFTWARE_SWITCH_OFF_ENABLED);
631c7cf2933SEtienne Carriere }
632c7cf2933SEtienne Carriere 
633c7cf2933SEtienne Carriere int stpmic1_regulator_enable(const char *name)
634c7cf2933SEtienne Carriere {
635c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
636c7cf2933SEtienne Carriere 
63768cfb83dSEtienne Carriere 	return stpmic1_register_update(regul->control_reg,
63868cfb83dSEtienne Carriere 				       BIT(regul->enable_pos),
63968cfb83dSEtienne Carriere 				       BIT(regul->enable_pos));
640c7cf2933SEtienne Carriere }
641c7cf2933SEtienne Carriere 
642c7cf2933SEtienne Carriere int stpmic1_regulator_disable(const char *name)
643c7cf2933SEtienne Carriere {
644c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
645c7cf2933SEtienne Carriere 
64668cfb83dSEtienne Carriere 	return stpmic1_register_update(regul->control_reg, 0,
64768cfb83dSEtienne Carriere 				       BIT(regul->enable_pos));
648c7cf2933SEtienne Carriere }
649c7cf2933SEtienne Carriere 
6502619b28cSEtienne Carriere bool stpmic1_is_regulator_enabled(const char *name)
651c7cf2933SEtienne Carriere {
652c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
653c7cf2933SEtienne Carriere 	uint8_t val = 0;
654c7cf2933SEtienne Carriere 
655c7cf2933SEtienne Carriere 	if (stpmic1_register_read(regul->control_reg, &val))
656c7cf2933SEtienne Carriere 		panic();
657c7cf2933SEtienne Carriere 
65868cfb83dSEtienne Carriere 	return val & BIT(regul->enable_pos);
659c7cf2933SEtienne Carriere }
660c7cf2933SEtienne Carriere 
6611764a894SEtienne Carriere /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
6621764a894SEtienne Carriere static uint8_t find_plat_mask(const char *name)
6631764a894SEtienne Carriere {
6641764a894SEtienne Carriere 	if (!strncmp(name, "buck", 4))
6651764a894SEtienne Carriere 		return BUCK_VOLTAGE_MASK;
6661764a894SEtienne Carriere 
6671764a894SEtienne Carriere 	if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
6681764a894SEtienne Carriere 		return LDO_VOLTAGE_MASK;
6691764a894SEtienne Carriere 
6701764a894SEtienne Carriere 	return 0;
6711764a894SEtienne Carriere }
6721764a894SEtienne Carriere 
673c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
674c7cf2933SEtienne Carriere {
6756a63363bSEtienne Carriere 	size_t voltage_index = voltage_to_index(name, millivolts);
676c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
677c7cf2933SEtienne Carriere 	uint8_t mask = 0;
678c7cf2933SEtienne Carriere 
6796a63363bSEtienne Carriere 	if (voltage_index == VOLTAGE_INDEX_INVALID)
6806a63363bSEtienne Carriere 		return -1;
6816a63363bSEtienne Carriere 
6821764a894SEtienne Carriere 	mask = find_plat_mask(name);
6831764a894SEtienne Carriere 	if (!mask)
684c7cf2933SEtienne Carriere 		return 0;
685c7cf2933SEtienne Carriere 
686c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->control_reg,
687c7cf2933SEtienne Carriere 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
688c7cf2933SEtienne Carriere 				       mask);
689c7cf2933SEtienne Carriere }
690c7cf2933SEtienne Carriere 
691c7cf2933SEtienne Carriere int stpmic1_regulator_mask_reset_set(const char *name)
692c7cf2933SEtienne Carriere {
693c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
694c7cf2933SEtienne Carriere 
6953f692bdfSEtienne Carriere 	if (regul->control_reg == USB_CONTROL_REG) {
6963f692bdfSEtienne Carriere 		DMSG("No reset for USB control");
6973f692bdfSEtienne Carriere 		return -1;
6983f692bdfSEtienne Carriere 	}
6993f692bdfSEtienne Carriere 
700c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->mask_reset_reg,
701c7cf2933SEtienne Carriere 				       BIT(regul->mask_reset_pos),
702c7cf2933SEtienne Carriere 				       LDO_BUCK_RESET_MASK <<
703c7cf2933SEtienne Carriere 				       regul->mask_reset_pos);
704c7cf2933SEtienne Carriere }
705c7cf2933SEtienne Carriere 
7066149e2d8SEtienne Carriere int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
7076149e2d8SEtienne Carriere {
7086149e2d8SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
7096149e2d8SEtienne Carriere 
7106149e2d8SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
7116149e2d8SEtienne Carriere 	cfg->enable_pos = regul->enable_pos;
7126149e2d8SEtienne Carriere 
7136149e2d8SEtienne Carriere 	return 0;
7146149e2d8SEtienne Carriere }
7156149e2d8SEtienne Carriere 
716eb5d5313SEtienne Carriere int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
717eb5d5313SEtienne Carriere {
71868cfb83dSEtienne Carriere 	return stpmic1_register_update(cfg->ctrl_reg,
71968cfb83dSEtienne Carriere 				       BIT(cfg->enable_pos),
72068cfb83dSEtienne Carriere 				       BIT(cfg->enable_pos));
721eb5d5313SEtienne Carriere }
722eb5d5313SEtienne Carriere 
723eb5d5313SEtienne Carriere /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
72444219e70SEtienne Carriere int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
725eb5d5313SEtienne Carriere 			   struct stpmic1_bo_cfg *cfg)
726eb5d5313SEtienne Carriere {
7276a63363bSEtienne Carriere 	size_t min_index = voltage_to_index(name, min_millivolt);
728eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
729eb5d5313SEtienne Carriere 	uint8_t mask = 0;
730eb5d5313SEtienne Carriere 
7316a63363bSEtienne Carriere 	if (min_index == VOLTAGE_INDEX_INVALID)
7326a63363bSEtienne Carriere 		panic();
7336a63363bSEtienne Carriere 
7341764a894SEtienne Carriere 	mask = find_plat_mask(name);
7351764a894SEtienne Carriere 	if (!mask)
736eb5d5313SEtienne Carriere 		return 1;
737eb5d5313SEtienne Carriere 
738eb5d5313SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
73944219e70SEtienne Carriere 	cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
740eb5d5313SEtienne Carriere 	cfg->mask = mask;
741eb5d5313SEtienne Carriere 
742eb5d5313SEtienne Carriere 	return 0;
743eb5d5313SEtienne Carriere }
744eb5d5313SEtienne Carriere 
745eb5d5313SEtienne Carriere int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
746eb5d5313SEtienne Carriere {
74744219e70SEtienne Carriere 	uint8_t value = 0;
74844219e70SEtienne Carriere 
74944219e70SEtienne Carriere 	assert(cfg->ctrl_reg);
75044219e70SEtienne Carriere 
75144219e70SEtienne Carriere 	if (stpmic1_register_read(cfg->ctrl_reg, &value))
75244219e70SEtienne Carriere 		return -1;
75344219e70SEtienne Carriere 
754187ba5c2SEtienne Carriere 	if ((value & cfg->mask) >= cfg->min_value)
75544219e70SEtienne Carriere 		return 0;
75644219e70SEtienne Carriere 
75744219e70SEtienne Carriere 	return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
75844219e70SEtienne Carriere 				       cfg->mask);
759eb5d5313SEtienne Carriere }
760eb5d5313SEtienne Carriere 
761eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
762eb5d5313SEtienne Carriere {
763eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
764eb5d5313SEtienne Carriere 
765ef18a901SEtienne Carriere 	if (!regul->pull_down_reg) {
766ef18a901SEtienne Carriere 		DMSG("No pull down for regu %s", name);
767ef18a901SEtienne Carriere 		panic();
768ef18a901SEtienne Carriere 	}
769ef18a901SEtienne Carriere 
770eb5d5313SEtienne Carriere 	cfg->pd_reg = regul->pull_down_reg;
771eb5d5313SEtienne Carriere 	cfg->pd_value = BIT(regul->pull_down_pos);
772eb5d5313SEtienne Carriere 	cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
773eb5d5313SEtienne Carriere 
774eb5d5313SEtienne Carriere 	return 0;
775eb5d5313SEtienne Carriere }
776eb5d5313SEtienne Carriere 
777eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
778eb5d5313SEtienne Carriere {
779ef18a901SEtienne Carriere 	assert(cfg->pd_reg);
780ef18a901SEtienne Carriere 
781eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
782eb5d5313SEtienne Carriere 				       cfg->pd_mask);
783eb5d5313SEtienne Carriere }
784eb5d5313SEtienne Carriere 
785eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
786eb5d5313SEtienne Carriere {
787eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
788eb5d5313SEtienne Carriere 
789ef18a901SEtienne Carriere 	if (!regul->mask_reset_reg) {
790ef18a901SEtienne Carriere 		DMSG("No reset mask for regu %s", name);
791ef18a901SEtienne Carriere 		panic();
792ef18a901SEtienne Carriere 	}
793ef18a901SEtienne Carriere 
794eb5d5313SEtienne Carriere 	cfg->mrst_reg = regul->mask_reset_reg;
795eb5d5313SEtienne Carriere 	cfg->mrst_value = BIT(regul->mask_reset_pos);
796eb5d5313SEtienne Carriere 	cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
797eb5d5313SEtienne Carriere 
798eb5d5313SEtienne Carriere 	return 0;
799eb5d5313SEtienne Carriere }
800eb5d5313SEtienne Carriere 
801eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
802eb5d5313SEtienne Carriere {
803ef18a901SEtienne Carriere 	assert(cfg->mrst_reg);
804ef18a901SEtienne Carriere 
805eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
806eb5d5313SEtienne Carriere 				       cfg->mrst_mask);
807eb5d5313SEtienne Carriere }
808eb5d5313SEtienne Carriere 
809c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_get(const char *name)
810c7cf2933SEtienne Carriere {
811c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
812c7cf2933SEtienne Carriere 	uint8_t value = 0;
813c7cf2933SEtienne Carriere 	uint8_t mask = 0;
814c7cf2933SEtienne Carriere 
8151764a894SEtienne Carriere 	mask = find_plat_mask(name);
8161764a894SEtienne Carriere 	if (!mask)
817c7cf2933SEtienne Carriere 		return 0;
818c7cf2933SEtienne Carriere 
819c7cf2933SEtienne Carriere 	if (stpmic1_register_read(regul->control_reg, &value))
820c7cf2933SEtienne Carriere 		return -1;
821c7cf2933SEtienne Carriere 
822c7cf2933SEtienne Carriere 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
823c7cf2933SEtienne Carriere 
824c7cf2933SEtienne Carriere 	if (value > regul->voltage_table_size)
825c7cf2933SEtienne Carriere 		return -1;
826c7cf2933SEtienne Carriere 
827c7cf2933SEtienne Carriere 	return regul->voltage_table[value];
828c7cf2933SEtienne Carriere }
829c7cf2933SEtienne Carriere 
830c7cf2933SEtienne Carriere int stpmic1_lp_copy_reg(const char *name)
831c7cf2933SEtienne Carriere {
832c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
833c7cf2933SEtienne Carriere 	uint8_t val = 0;
834c7cf2933SEtienne Carriere 	int status = 0;
835c7cf2933SEtienne Carriere 
836972b3d9aSEtienne Carriere 	if (!regul->low_power_reg)
837972b3d9aSEtienne Carriere 		return -1;
838972b3d9aSEtienne Carriere 
839c7cf2933SEtienne Carriere 	status = stpmic1_register_read(regul->control_reg, &val);
840c7cf2933SEtienne Carriere 	if (status)
841c7cf2933SEtienne Carriere 		return status;
842c7cf2933SEtienne Carriere 
843c7cf2933SEtienne Carriere 	return stpmic1_register_write(regul->low_power_reg, val);
844c7cf2933SEtienne Carriere }
845c7cf2933SEtienne Carriere 
846972b3d9aSEtienne Carriere bool stpmic1_regu_has_lp_cfg(const char *name)
847972b3d9aSEtienne Carriere {
848972b3d9aSEtienne Carriere 	return get_regulator_data(name)->low_power_reg;
849972b3d9aSEtienne Carriere }
850972b3d9aSEtienne Carriere 
851eb5d5313SEtienne Carriere int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
852eb5d5313SEtienne Carriere {
853eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
854eb5d5313SEtienne Carriere 
855972b3d9aSEtienne Carriere 	if (!regul->low_power_reg)
856972b3d9aSEtienne Carriere 		return -1;
857972b3d9aSEtienne Carriere 
858eb5d5313SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
859eb5d5313SEtienne Carriere 	cfg->lp_reg = regul->low_power_reg;
860eb5d5313SEtienne Carriere 
861eb5d5313SEtienne Carriere 	return 0;
862eb5d5313SEtienne Carriere }
863eb5d5313SEtienne Carriere 
864eb5d5313SEtienne Carriere int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
865eb5d5313SEtienne Carriere {
866eb5d5313SEtienne Carriere 	uint8_t val = 0;
867eb5d5313SEtienne Carriere 	int status = 0;
868eb5d5313SEtienne Carriere 
869ef18a901SEtienne Carriere 	assert(cfg->lp_reg);
870ef18a901SEtienne Carriere 
871eb5d5313SEtienne Carriere 	status = stpmic1_register_read(cfg->ctrl_reg, &val);
872eb5d5313SEtienne Carriere 	if (!status)
873eb5d5313SEtienne Carriere 		status = stpmic1_register_write(cfg->lp_reg, val);
874eb5d5313SEtienne Carriere 
875eb5d5313SEtienne Carriere 	return status;
876eb5d5313SEtienne Carriere }
877eb5d5313SEtienne Carriere 
878c7cf2933SEtienne Carriere int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
879c7cf2933SEtienne Carriere {
880c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
881c7cf2933SEtienne Carriere 
882972b3d9aSEtienne Carriere 	if (!regul->low_power_reg)
883972b3d9aSEtienne Carriere 		return -1;
884972b3d9aSEtienne Carriere 
885c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg, enable,
886c7cf2933SEtienne Carriere 				       LDO_BUCK_ENABLE_MASK);
887c7cf2933SEtienne Carriere }
888c7cf2933SEtienne Carriere 
889eb5d5313SEtienne Carriere int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
890eb5d5313SEtienne Carriere {
891ef18a901SEtienne Carriere 	assert(cfg->lp_reg && (enable == 0 || enable == 1));
892ef18a901SEtienne Carriere 
893eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg, enable,
894eb5d5313SEtienne Carriere 				       LDO_BUCK_ENABLE_MASK);
895eb5d5313SEtienne Carriere }
896eb5d5313SEtienne Carriere 
897c7cf2933SEtienne Carriere int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
898c7cf2933SEtienne Carriere {
899c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
900c7cf2933SEtienne Carriere 
901ef18a901SEtienne Carriere 	assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
902ef18a901SEtienne Carriere 
903c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg,
90442032ea0SEtienne Carriere 				       hplp << LDO_BUCK_HPLP_POS,
90542032ea0SEtienne Carriere 				       BIT(LDO_BUCK_HPLP_POS));
906c7cf2933SEtienne Carriere }
907c7cf2933SEtienne Carriere 
908eb5d5313SEtienne Carriere int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
909eb5d5313SEtienne Carriere {
910ef18a901SEtienne Carriere 	assert(cfg->lp_reg && (mode == 0 || mode == 1));
911eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg,
91242032ea0SEtienne Carriere 				       mode << LDO_BUCK_HPLP_POS,
91342032ea0SEtienne Carriere 				       BIT(LDO_BUCK_HPLP_POS));
914eb5d5313SEtienne Carriere }
915eb5d5313SEtienne Carriere 
916c7cf2933SEtienne Carriere int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
917c7cf2933SEtienne Carriere {
9186a63363bSEtienne Carriere 	size_t voltage_index = voltage_to_index(name, millivolts);
919c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
920c7cf2933SEtienne Carriere 	uint8_t mask = 0;
921c7cf2933SEtienne Carriere 
9226a63363bSEtienne Carriere 	assert(voltage_index != VOLTAGE_INDEX_INVALID);
9236a63363bSEtienne Carriere 
9241764a894SEtienne Carriere 	mask = find_plat_mask(name);
9251764a894SEtienne Carriere 	if (!mask)
926c7cf2933SEtienne Carriere 		return 0;
927c7cf2933SEtienne Carriere 
928c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
929c7cf2933SEtienne Carriere 				       mask);
930c7cf2933SEtienne Carriere }
931c7cf2933SEtienne Carriere 
932eb5d5313SEtienne Carriere /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */
933eb5d5313SEtienne Carriere int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
934eb5d5313SEtienne Carriere 			   struct stpmic1_lp_cfg *cfg)
935eb5d5313SEtienne Carriere 
936eb5d5313SEtienne Carriere {
9376a63363bSEtienne Carriere 	size_t voltage_index = voltage_to_index(name, millivolts);
938eb5d5313SEtienne Carriere 	uint8_t mask = 0;
939eb5d5313SEtienne Carriere 
9401764a894SEtienne Carriere 	mask = find_plat_mask(name);
9411764a894SEtienne Carriere 	if (!mask)
942eb5d5313SEtienne Carriere 		return 1;
943eb5d5313SEtienne Carriere 
9446a63363bSEtienne Carriere 	assert(voltage_index != VOLTAGE_INDEX_INVALID &&
9456a63363bSEtienne Carriere 	       cfg->lp_reg == get_regulator_data(name)->low_power_reg);
9466a63363bSEtienne Carriere 
947eb5d5313SEtienne Carriere 	cfg->value = voltage_index << 2;
948eb5d5313SEtienne Carriere 	cfg->mask = mask;
949eb5d5313SEtienne Carriere 
950eb5d5313SEtienne Carriere 	return 0;
951eb5d5313SEtienne Carriere }
952eb5d5313SEtienne Carriere 
953eb5d5313SEtienne Carriere int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
954eb5d5313SEtienne Carriere {
955ef18a901SEtienne Carriere 	assert(cfg->lp_reg);
956ef18a901SEtienne Carriere 
957eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg, cfg->value,	cfg->mask);
958eb5d5313SEtienne Carriere }
959eb5d5313SEtienne Carriere 
960c7cf2933SEtienne Carriere int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
961c7cf2933SEtienne Carriere {
962c7cf2933SEtienne Carriere 	struct i2c_handle_s *i2c = pmic_i2c_handle;
963c7cf2933SEtienne Carriere 
964eb5d5313SEtienne Carriere 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
965eb5d5313SEtienne Carriere 					    register_id, value,
966eb5d5313SEtienne Carriere 					    false /* !write */);
967c7cf2933SEtienne Carriere }
968c7cf2933SEtienne Carriere 
969c7cf2933SEtienne Carriere int stpmic1_register_write(uint8_t register_id, uint8_t value)
970c7cf2933SEtienne Carriere {
971c7cf2933SEtienne Carriere 	struct i2c_handle_s *i2c = pmic_i2c_handle;
972c7cf2933SEtienne Carriere 	uint8_t val = value;
973c7cf2933SEtienne Carriere 
974eb5d5313SEtienne Carriere 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
975eb5d5313SEtienne Carriere 					    register_id, &val,
976eb5d5313SEtienne Carriere 					    true /* write */);
977c7cf2933SEtienne Carriere }
978c7cf2933SEtienne Carriere 
979c7cf2933SEtienne Carriere int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
980c7cf2933SEtienne Carriere {
981c7cf2933SEtienne Carriere 	int status = 0;
982c7cf2933SEtienne Carriere 	uint8_t val = 0;
983c7cf2933SEtienne Carriere 
984c7cf2933SEtienne Carriere 	status = stpmic1_register_read(register_id, &val);
985c7cf2933SEtienne Carriere 	if (status)
986c7cf2933SEtienne Carriere 		return status;
987c7cf2933SEtienne Carriere 
988c7cf2933SEtienne Carriere 	val = (val & ~mask) | (value & mask);
989c7cf2933SEtienne Carriere 
990c7cf2933SEtienne Carriere 	return stpmic1_register_write(register_id, val);
991c7cf2933SEtienne Carriere }
992c7cf2933SEtienne Carriere 
993c7cf2933SEtienne Carriere void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
994c7cf2933SEtienne Carriere {
995c7cf2933SEtienne Carriere 	pmic_i2c_handle = i2c_handle;
996c7cf2933SEtienne Carriere 	pmic_i2c_addr = i2c_addr;
997c7cf2933SEtienne Carriere }
998c7cf2933SEtienne Carriere 
999c7cf2933SEtienne Carriere void stpmic1_dump_regulators(void)
1000c7cf2933SEtienne Carriere {
1001c7cf2933SEtienne Carriere 	size_t i = 0;
1002c7cf2933SEtienne Carriere 	char __maybe_unused const *name = NULL;
1003c7cf2933SEtienne Carriere 
1004c7cf2933SEtienne Carriere 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
1005c7cf2933SEtienne Carriere 		if (!regulators_table[i].control_reg)
1006c7cf2933SEtienne Carriere 			continue;
1007c7cf2933SEtienne Carriere 
1008c7cf2933SEtienne Carriere 		name = regulators_table[i].dt_node_name;
1009c7cf2933SEtienne Carriere 		DMSG("PMIC regul %s: %sable, %dmV",
1010c7cf2933SEtienne Carriere 		     name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
1011c7cf2933SEtienne Carriere 		     stpmic1_regulator_voltage_get(name));
1012c7cf2933SEtienne Carriere 	}
1013c7cf2933SEtienne Carriere }
1014c7cf2933SEtienne Carriere 
1015c7cf2933SEtienne Carriere int stpmic1_get_version(unsigned long *version)
1016c7cf2933SEtienne Carriere {
1017c7cf2933SEtienne Carriere 	uint8_t read_val = 0;
1018c7cf2933SEtienne Carriere 
1019c7cf2933SEtienne Carriere 	if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
1020c7cf2933SEtienne Carriere 		return -1;
1021c7cf2933SEtienne Carriere 
1022c7cf2933SEtienne Carriere 	*version = read_val;
1023c7cf2933SEtienne Carriere 	return 0;
1024c7cf2933SEtienne Carriere }
1025