xref: /optee_os/core/drivers/stpmic1.c (revision 8c49825d6ae074d38cec500c80a60194835e1dca)
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>
89cb0d516SEtienne Carriere #include <drivers/stpmic1_regulator.h>
9c7cf2933SEtienne Carriere #include <kernel/panic.h>
10c7cf2933SEtienne Carriere #include <platform_config.h>
11c7cf2933SEtienne Carriere #include <stdint.h>
12c7cf2933SEtienne Carriere #include <string.h>
13c7cf2933SEtienne Carriere #include <trace.h>
1442032ea0SEtienne Carriere #include <util.h>
15c7cf2933SEtienne Carriere 
166a63363bSEtienne Carriere #define VOLTAGE_INDEX_INVALID		((unsigned int)~0)
176a63363bSEtienne Carriere 
18c7cf2933SEtienne Carriere struct regul_struct {
19c7cf2933SEtienne Carriere 	const char *dt_node_name;
20c7cf2933SEtienne Carriere 	const uint16_t *voltage_table;
21c7cf2933SEtienne Carriere 	uint8_t voltage_table_size;
22c7cf2933SEtienne Carriere 	uint8_t control_reg;
23c7cf2933SEtienne Carriere 	uint8_t low_power_reg;
2468cfb83dSEtienne Carriere 	uint8_t enable_pos;
25c7cf2933SEtienne Carriere 	uint8_t pull_down_reg;
26c7cf2933SEtienne Carriere 	uint8_t pull_down_pos;
27c7cf2933SEtienne Carriere 	uint8_t mask_reset_reg;
28c7cf2933SEtienne Carriere 	uint8_t mask_reset_pos;
29c7cf2933SEtienne Carriere };
30c7cf2933SEtienne Carriere 
31c7cf2933SEtienne Carriere static struct i2c_handle_s *pmic_i2c_handle;
32c7cf2933SEtienne Carriere static uint16_t pmic_i2c_addr;
33c7cf2933SEtienne Carriere 
34c7cf2933SEtienne Carriere /* Voltage tables in mV */
35c7cf2933SEtienne Carriere static const uint16_t buck1_voltage_table[] = {
36c7cf2933SEtienne Carriere 	725,
37c7cf2933SEtienne Carriere 	725,
38c7cf2933SEtienne Carriere 	725,
39c7cf2933SEtienne Carriere 	725,
40c7cf2933SEtienne Carriere 	725,
41c7cf2933SEtienne Carriere 	725,
42c7cf2933SEtienne Carriere 	750,
43c7cf2933SEtienne Carriere 	775,
44c7cf2933SEtienne Carriere 	800,
45c7cf2933SEtienne Carriere 	825,
46c7cf2933SEtienne Carriere 	850,
47c7cf2933SEtienne Carriere 	875,
48c7cf2933SEtienne Carriere 	900,
49c7cf2933SEtienne Carriere 	925,
50c7cf2933SEtienne Carriere 	950,
51c7cf2933SEtienne Carriere 	975,
52c7cf2933SEtienne Carriere 	1000,
53c7cf2933SEtienne Carriere 	1025,
54c7cf2933SEtienne Carriere 	1050,
55c7cf2933SEtienne Carriere 	1075,
56c7cf2933SEtienne Carriere 	1100,
57c7cf2933SEtienne Carriere 	1125,
58c7cf2933SEtienne Carriere 	1150,
59c7cf2933SEtienne Carriere 	1175,
60c7cf2933SEtienne Carriere 	1200,
61c7cf2933SEtienne Carriere 	1225,
62c7cf2933SEtienne Carriere 	1250,
63c7cf2933SEtienne Carriere 	1275,
64c7cf2933SEtienne Carriere 	1300,
65c7cf2933SEtienne Carriere 	1325,
66c7cf2933SEtienne Carriere 	1350,
67c7cf2933SEtienne Carriere 	1375,
68c7cf2933SEtienne Carriere 	1400,
69c7cf2933SEtienne Carriere 	1425,
70c7cf2933SEtienne Carriere 	1450,
71c7cf2933SEtienne Carriere 	1475,
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 	1500,
100c7cf2933SEtienne Carriere };
101c7cf2933SEtienne Carriere 
102c7cf2933SEtienne Carriere static const uint16_t buck2_voltage_table[] = {
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 	1000,
121c7cf2933SEtienne Carriere 	1050,
122c7cf2933SEtienne Carriere 	1050,
123c7cf2933SEtienne Carriere 	1100,
124c7cf2933SEtienne Carriere 	1100,
125c7cf2933SEtienne Carriere 	1150,
126c7cf2933SEtienne Carriere 	1150,
127c7cf2933SEtienne Carriere 	1200,
128c7cf2933SEtienne Carriere 	1200,
129c7cf2933SEtienne Carriere 	1250,
130c7cf2933SEtienne Carriere 	1250,
131c7cf2933SEtienne Carriere 	1300,
132c7cf2933SEtienne Carriere 	1300,
133c7cf2933SEtienne Carriere 	1350,
134c7cf2933SEtienne Carriere 	1350,
135c7cf2933SEtienne Carriere 	1400,
136c7cf2933SEtienne Carriere 	1400,
137c7cf2933SEtienne Carriere 	1450,
138c7cf2933SEtienne Carriere 	1450,
139c7cf2933SEtienne Carriere 	1500,
140c7cf2933SEtienne Carriere };
141c7cf2933SEtienne Carriere 
142c7cf2933SEtienne Carriere static const uint16_t buck3_voltage_table[] = {
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 	1000,
163c7cf2933SEtienne Carriere 	1100,
164c7cf2933SEtienne Carriere 	1100,
165c7cf2933SEtienne Carriere 	1100,
166c7cf2933SEtienne Carriere 	1100,
167c7cf2933SEtienne Carriere 	1200,
168c7cf2933SEtienne Carriere 	1200,
169c7cf2933SEtienne Carriere 	1200,
170c7cf2933SEtienne Carriere 	1200,
171c7cf2933SEtienne Carriere 	1300,
172c7cf2933SEtienne Carriere 	1300,
173c7cf2933SEtienne Carriere 	1300,
174c7cf2933SEtienne Carriere 	1300,
175c7cf2933SEtienne Carriere 	1400,
176c7cf2933SEtienne Carriere 	1400,
177c7cf2933SEtienne Carriere 	1400,
178c7cf2933SEtienne Carriere 	1400,
179c7cf2933SEtienne Carriere 	1500,
180c7cf2933SEtienne Carriere 	1600,
181c7cf2933SEtienne Carriere 	1700,
182c7cf2933SEtienne Carriere 	1800,
183c7cf2933SEtienne Carriere 	1900,
184c7cf2933SEtienne Carriere 	2000,
185c7cf2933SEtienne Carriere 	2100,
186c7cf2933SEtienne Carriere 	2200,
187c7cf2933SEtienne Carriere 	2300,
188c7cf2933SEtienne Carriere 	2400,
189c7cf2933SEtienne Carriere 	2500,
190c7cf2933SEtienne Carriere 	2600,
191c7cf2933SEtienne Carriere 	2700,
192c7cf2933SEtienne Carriere 	2800,
193c7cf2933SEtienne Carriere 	2900,
194c7cf2933SEtienne Carriere 	3000,
195c7cf2933SEtienne Carriere 	3100,
196c7cf2933SEtienne Carriere 	3200,
197c7cf2933SEtienne Carriere 	3300,
198c7cf2933SEtienne Carriere 	3400,
199c7cf2933SEtienne Carriere };
200c7cf2933SEtienne Carriere 
201c7cf2933SEtienne Carriere static const uint16_t buck4_voltage_table[] = {
202c7cf2933SEtienne Carriere 	600,
203c7cf2933SEtienne Carriere 	625,
204c7cf2933SEtienne Carriere 	650,
205c7cf2933SEtienne Carriere 	675,
206c7cf2933SEtienne Carriere 	700,
207c7cf2933SEtienne Carriere 	725,
208c7cf2933SEtienne Carriere 	750,
209c7cf2933SEtienne Carriere 	775,
210c7cf2933SEtienne Carriere 	800,
211c7cf2933SEtienne Carriere 	825,
212c7cf2933SEtienne Carriere 	850,
213c7cf2933SEtienne Carriere 	875,
214c7cf2933SEtienne Carriere 	900,
215c7cf2933SEtienne Carriere 	925,
216c7cf2933SEtienne Carriere 	950,
217c7cf2933SEtienne Carriere 	975,
218c7cf2933SEtienne Carriere 	1000,
219c7cf2933SEtienne Carriere 	1025,
220c7cf2933SEtienne Carriere 	1050,
221c7cf2933SEtienne Carriere 	1075,
222c7cf2933SEtienne Carriere 	1100,
223c7cf2933SEtienne Carriere 	1125,
224c7cf2933SEtienne Carriere 	1150,
225c7cf2933SEtienne Carriere 	1175,
226c7cf2933SEtienne Carriere 	1200,
227c7cf2933SEtienne Carriere 	1225,
228c7cf2933SEtienne Carriere 	1250,
229c7cf2933SEtienne Carriere 	1275,
230c7cf2933SEtienne Carriere 	1300,
231c7cf2933SEtienne Carriere 	1300,
232c7cf2933SEtienne Carriere 	1350,
233c7cf2933SEtienne Carriere 	1350,
234c7cf2933SEtienne Carriere 	1400,
235c7cf2933SEtienne Carriere 	1400,
236c7cf2933SEtienne Carriere 	1450,
237c7cf2933SEtienne Carriere 	1450,
238c7cf2933SEtienne Carriere 	1500,
239c7cf2933SEtienne Carriere 	1600,
240c7cf2933SEtienne Carriere 	1700,
241c7cf2933SEtienne Carriere 	1800,
242c7cf2933SEtienne Carriere 	1900,
243c7cf2933SEtienne Carriere 	2000,
244c7cf2933SEtienne Carriere 	2100,
245c7cf2933SEtienne Carriere 	2200,
246c7cf2933SEtienne Carriere 	2300,
247c7cf2933SEtienne Carriere 	2400,
248c7cf2933SEtienne Carriere 	2500,
249c7cf2933SEtienne Carriere 	2600,
250c7cf2933SEtienne Carriere 	2700,
251c7cf2933SEtienne Carriere 	2800,
252c7cf2933SEtienne Carriere 	2900,
253c7cf2933SEtienne Carriere 	3000,
254c7cf2933SEtienne Carriere 	3100,
255c7cf2933SEtienne Carriere 	3200,
256c7cf2933SEtienne Carriere 	3300,
257c7cf2933SEtienne Carriere 	3400,
258c7cf2933SEtienne Carriere 	3500,
259c7cf2933SEtienne Carriere 	3600,
260c7cf2933SEtienne Carriere 	3700,
261c7cf2933SEtienne Carriere 	3800,
262c7cf2933SEtienne Carriere 	3900,
263c7cf2933SEtienne Carriere };
264c7cf2933SEtienne Carriere 
265c7cf2933SEtienne Carriere static const uint16_t ldo1_voltage_table[] = {
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 	1700,
275c7cf2933SEtienne Carriere 	1800,
276c7cf2933SEtienne Carriere 	1900,
277c7cf2933SEtienne Carriere 	2000,
278c7cf2933SEtienne Carriere 	2100,
279c7cf2933SEtienne Carriere 	2200,
280c7cf2933SEtienne Carriere 	2300,
281c7cf2933SEtienne Carriere 	2400,
282c7cf2933SEtienne Carriere 	2500,
283c7cf2933SEtienne Carriere 	2600,
284c7cf2933SEtienne Carriere 	2700,
285c7cf2933SEtienne Carriere 	2800,
286c7cf2933SEtienne Carriere 	2900,
287c7cf2933SEtienne Carriere 	3000,
288c7cf2933SEtienne Carriere 	3100,
289c7cf2933SEtienne Carriere 	3200,
290c7cf2933SEtienne Carriere 	3300,
291c7cf2933SEtienne Carriere };
292c7cf2933SEtienne Carriere 
293c7cf2933SEtienne Carriere static const uint16_t ldo2_voltage_table[] = {
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 	1700,
303c7cf2933SEtienne Carriere 	1800,
304c7cf2933SEtienne Carriere 	1900,
305c7cf2933SEtienne Carriere 	2000,
306c7cf2933SEtienne Carriere 	2100,
307c7cf2933SEtienne Carriere 	2200,
308c7cf2933SEtienne Carriere 	2300,
309c7cf2933SEtienne Carriere 	2400,
310c7cf2933SEtienne Carriere 	2500,
311c7cf2933SEtienne Carriere 	2600,
312c7cf2933SEtienne Carriere 	2700,
313c7cf2933SEtienne Carriere 	2800,
314c7cf2933SEtienne Carriere 	2900,
315c7cf2933SEtienne Carriere 	3000,
316c7cf2933SEtienne Carriere 	3100,
317c7cf2933SEtienne Carriere 	3200,
318c7cf2933SEtienne Carriere 	3300,
319c7cf2933SEtienne Carriere };
320c7cf2933SEtienne Carriere 
321c7cf2933SEtienne Carriere static const uint16_t ldo3_voltage_table[] = {
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 	1700,
331c7cf2933SEtienne Carriere 	1800,
332c7cf2933SEtienne Carriere 	1900,
333c7cf2933SEtienne Carriere 	2000,
334c7cf2933SEtienne Carriere 	2100,
335c7cf2933SEtienne Carriere 	2200,
336c7cf2933SEtienne Carriere 	2300,
337c7cf2933SEtienne Carriere 	2400,
338c7cf2933SEtienne Carriere 	2500,
339c7cf2933SEtienne Carriere 	2600,
340c7cf2933SEtienne Carriere 	2700,
341c7cf2933SEtienne Carriere 	2800,
342c7cf2933SEtienne Carriere 	2900,
343c7cf2933SEtienne Carriere 	3000,
344c7cf2933SEtienne Carriere 	3100,
345c7cf2933SEtienne Carriere 	3200,
346c7cf2933SEtienne Carriere 	3300,
347c7cf2933SEtienne Carriere 	3300,
348c7cf2933SEtienne Carriere 	3300,
349c7cf2933SEtienne Carriere 	3300,
350c7cf2933SEtienne Carriere 	3300,
351c7cf2933SEtienne Carriere 	3300,
352c7cf2933SEtienne Carriere 	3300,
353f7e28951SEtienne Carriere 	500,	/* VOUT2/2 (Sink/source mode) */
354c7cf2933SEtienne Carriere 	0xFFFF, /* VREFDDR */
355c7cf2933SEtienne Carriere };
356c7cf2933SEtienne Carriere 
357c7cf2933SEtienne Carriere static const uint16_t ldo5_voltage_table[] = {
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 	1700,
367c7cf2933SEtienne Carriere 	1800,
368c7cf2933SEtienne Carriere 	1900,
369c7cf2933SEtienne Carriere 	2000,
370c7cf2933SEtienne Carriere 	2100,
371c7cf2933SEtienne Carriere 	2200,
372c7cf2933SEtienne Carriere 	2300,
373c7cf2933SEtienne Carriere 	2400,
374c7cf2933SEtienne Carriere 	2500,
375c7cf2933SEtienne Carriere 	2600,
376c7cf2933SEtienne Carriere 	2700,
377c7cf2933SEtienne Carriere 	2800,
378c7cf2933SEtienne Carriere 	2900,
379c7cf2933SEtienne Carriere 	3000,
380c7cf2933SEtienne Carriere 	3100,
381c7cf2933SEtienne Carriere 	3200,
382c7cf2933SEtienne Carriere 	3300,
383c7cf2933SEtienne Carriere 	3400,
384c7cf2933SEtienne Carriere 	3500,
385c7cf2933SEtienne Carriere 	3600,
386c7cf2933SEtienne Carriere 	3700,
387c7cf2933SEtienne Carriere 	3800,
388c7cf2933SEtienne Carriere 	3900,
389c7cf2933SEtienne Carriere };
390c7cf2933SEtienne Carriere 
391c7cf2933SEtienne Carriere static const uint16_t ldo6_voltage_table[] = {
392c7cf2933SEtienne Carriere 	900,
393c7cf2933SEtienne Carriere 	1000,
394c7cf2933SEtienne Carriere 	1100,
395c7cf2933SEtienne Carriere 	1200,
396c7cf2933SEtienne Carriere 	1300,
397c7cf2933SEtienne Carriere 	1400,
398c7cf2933SEtienne Carriere 	1500,
399c7cf2933SEtienne Carriere 	1600,
400c7cf2933SEtienne Carriere 	1700,
401c7cf2933SEtienne Carriere 	1800,
402c7cf2933SEtienne Carriere 	1900,
403c7cf2933SEtienne Carriere 	2000,
404c7cf2933SEtienne Carriere 	2100,
405c7cf2933SEtienne Carriere 	2200,
406c7cf2933SEtienne Carriere 	2300,
407c7cf2933SEtienne Carriere 	2400,
408c7cf2933SEtienne Carriere 	2500,
409c7cf2933SEtienne Carriere 	2600,
410c7cf2933SEtienne Carriere 	2700,
411c7cf2933SEtienne Carriere 	2800,
412c7cf2933SEtienne Carriere 	2900,
413c7cf2933SEtienne Carriere 	3000,
414c7cf2933SEtienne Carriere 	3100,
415c7cf2933SEtienne Carriere 	3200,
416c7cf2933SEtienne Carriere 	3300,
417c7cf2933SEtienne Carriere };
418c7cf2933SEtienne Carriere 
419c7cf2933SEtienne Carriere static const uint16_t ldo4_voltage_table[] = {
420c7cf2933SEtienne Carriere 	3300,
421c7cf2933SEtienne Carriere };
422c7cf2933SEtienne Carriere 
423c7cf2933SEtienne Carriere static const uint16_t vref_ddr_voltage_table[] = {
424c7cf2933SEtienne Carriere 	3300,
425c7cf2933SEtienne Carriere };
426c7cf2933SEtienne Carriere 
4273f692bdfSEtienne Carriere static const uint16_t fixed_5v_voltage_table[] = {
4283f692bdfSEtienne Carriere 	5000,
4293f692bdfSEtienne Carriere };
4303f692bdfSEtienne Carriere 
431c7cf2933SEtienne Carriere /* Table of Regulators in PMIC SoC */
432c7cf2933SEtienne Carriere static const struct regul_struct regulators_table[] = {
433c7cf2933SEtienne Carriere 	{
434c7cf2933SEtienne Carriere 		.dt_node_name	= "buck1",
435c7cf2933SEtienne Carriere 		.voltage_table	= buck1_voltage_table,
436c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
437c7cf2933SEtienne Carriere 		.control_reg	= BUCK1_CONTROL_REG,
438c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK1_PWRCTRL_REG,
43968cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
440c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
441c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK1_PULL_DOWN_SHIFT,
442c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
443c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK1_MASK_RESET_SHIFT,
444c7cf2933SEtienne Carriere 	},
445c7cf2933SEtienne Carriere 	{
446c7cf2933SEtienne Carriere 		.dt_node_name	= "buck2",
447c7cf2933SEtienne Carriere 		.voltage_table	= buck2_voltage_table,
448c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
449c7cf2933SEtienne Carriere 		.control_reg	= BUCK2_CONTROL_REG,
450c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK2_PWRCTRL_REG,
45168cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
452c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
453c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK2_PULL_DOWN_SHIFT,
454c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
455c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK2_MASK_RESET_SHIFT,
456c7cf2933SEtienne Carriere 	},
457c7cf2933SEtienne Carriere 	{
458c7cf2933SEtienne Carriere 		.dt_node_name	= "buck3",
459c7cf2933SEtienne Carriere 		.voltage_table	= buck3_voltage_table,
460c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
461c7cf2933SEtienne Carriere 		.control_reg	= BUCK3_CONTROL_REG,
462c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK3_PWRCTRL_REG,
46368cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
464c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
465c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK3_PULL_DOWN_SHIFT,
466c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
467c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK3_MASK_RESET_SHIFT,
468c7cf2933SEtienne Carriere 	},
469c7cf2933SEtienne Carriere 	{
470c7cf2933SEtienne Carriere 		.dt_node_name	= "buck4",
471c7cf2933SEtienne Carriere 		.voltage_table	= buck4_voltage_table,
472c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
473c7cf2933SEtienne Carriere 		.control_reg	= BUCK4_CONTROL_REG,
474c7cf2933SEtienne Carriere 		.low_power_reg	= BUCK4_PWRCTRL_REG,
47568cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
476c7cf2933SEtienne Carriere 		.pull_down_reg	= BUCK_PULL_DOWN_REG,
477c7cf2933SEtienne Carriere 		.pull_down_pos	= BUCK4_PULL_DOWN_SHIFT,
478c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_BUCK_REG,
479c7cf2933SEtienne Carriere 		.mask_reset_pos = BUCK4_MASK_RESET_SHIFT,
480c7cf2933SEtienne Carriere 	},
481c7cf2933SEtienne Carriere 	{
482c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo1",
483c7cf2933SEtienne Carriere 		.voltage_table	= ldo1_voltage_table,
484c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
485c7cf2933SEtienne Carriere 		.control_reg	= LDO1_CONTROL_REG,
486c7cf2933SEtienne Carriere 		.low_power_reg	= LDO1_PWRCTRL_REG,
48768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
488c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
489c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO1_MASK_RESET_SHIFT,
490c7cf2933SEtienne Carriere 	},
491c7cf2933SEtienne Carriere 	{
492c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo2",
493c7cf2933SEtienne Carriere 		.voltage_table	= ldo2_voltage_table,
494c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
495c7cf2933SEtienne Carriere 		.control_reg	= LDO2_CONTROL_REG,
496c7cf2933SEtienne Carriere 		.low_power_reg	= LDO2_PWRCTRL_REG,
49768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
498c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
499c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO2_MASK_RESET_SHIFT,
500c7cf2933SEtienne Carriere 	},
501c7cf2933SEtienne Carriere 	{
502c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo3",
503c7cf2933SEtienne Carriere 		.voltage_table	= ldo3_voltage_table,
504c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
505c7cf2933SEtienne Carriere 		.control_reg	= LDO3_CONTROL_REG,
506c7cf2933SEtienne Carriere 		.low_power_reg	= LDO3_PWRCTRL_REG,
50768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
508c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
509c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO3_MASK_RESET_SHIFT,
510c7cf2933SEtienne Carriere 	},
511c7cf2933SEtienne Carriere 	{
512c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo4",
513c7cf2933SEtienne Carriere 		.voltage_table	= ldo4_voltage_table,
514c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
515c7cf2933SEtienne Carriere 		.control_reg	= LDO4_CONTROL_REG,
516c7cf2933SEtienne Carriere 		.low_power_reg	= LDO4_PWRCTRL_REG,
51768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
518c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
519c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO4_MASK_RESET_SHIFT,
520c7cf2933SEtienne Carriere 	},
521c7cf2933SEtienne Carriere 	{
522c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo5",
523c7cf2933SEtienne Carriere 		.voltage_table	= ldo5_voltage_table,
524c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
525c7cf2933SEtienne Carriere 		.control_reg	= LDO5_CONTROL_REG,
526c7cf2933SEtienne Carriere 		.low_power_reg	= LDO5_PWRCTRL_REG,
52768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
528c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
529c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO5_MASK_RESET_SHIFT,
530c7cf2933SEtienne Carriere 	},
531c7cf2933SEtienne Carriere 	{
532c7cf2933SEtienne Carriere 		.dt_node_name	= "ldo6",
533c7cf2933SEtienne Carriere 		.voltage_table	= ldo6_voltage_table,
534c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
535c7cf2933SEtienne Carriere 		.control_reg	= LDO6_CONTROL_REG,
536c7cf2933SEtienne Carriere 		.low_power_reg	= LDO6_PWRCTRL_REG,
53768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
538c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
539c7cf2933SEtienne Carriere 		.mask_reset_pos = LDO6_MASK_RESET_SHIFT,
540c7cf2933SEtienne Carriere 	},
541c7cf2933SEtienne Carriere 	{
542c7cf2933SEtienne Carriere 		.dt_node_name	= "vref_ddr",
543c7cf2933SEtienne Carriere 		.voltage_table	= vref_ddr_voltage_table,
544c7cf2933SEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
545c7cf2933SEtienne Carriere 		.control_reg	= VREF_DDR_CONTROL_REG,
546c7cf2933SEtienne Carriere 		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
54768cfb83dSEtienne Carriere 		.enable_pos	= LDO_BUCK_ENABLE_POS,
548c7cf2933SEtienne Carriere 		.mask_reset_reg = MASK_RESET_LDO_REG,
549c7cf2933SEtienne Carriere 		.mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT,
550c7cf2933SEtienne Carriere 	},
551c7cf2933SEtienne Carriere 	{
552c7cf2933SEtienne Carriere 		.dt_node_name = "boost",
5533f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5543f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5553f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5563f692bdfSEtienne Carriere 		.enable_pos	= BOOST_ENABLED_POS,
557c7cf2933SEtienne Carriere 	},
558c7cf2933SEtienne Carriere 	{
559c7cf2933SEtienne Carriere 		.dt_node_name	= "pwr_sw1",
5603f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5613f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5623f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5633f692bdfSEtienne Carriere 		.enable_pos	= USBSW_OTG_SWITCH_ENABLED_POS,
564c7cf2933SEtienne Carriere 	},
565c7cf2933SEtienne Carriere 	{
566c7cf2933SEtienne Carriere 		.dt_node_name	= "pwr_sw2",
5673f692bdfSEtienne Carriere 		.voltage_table	= fixed_5v_voltage_table,
5683f692bdfSEtienne Carriere 		.voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table),
5693f692bdfSEtienne Carriere 		.control_reg	= USB_CONTROL_REG,
5703f692bdfSEtienne Carriere 		.enable_pos	= SWIN_SWOUT_ENABLED_POS,
571c7cf2933SEtienne Carriere 	},
572c7cf2933SEtienne Carriere };
573c7cf2933SEtienne Carriere 
get_regulator_data(const char * name)574c7cf2933SEtienne Carriere static const struct regul_struct *get_regulator_data(const char *name)
575c7cf2933SEtienne Carriere {
576c7cf2933SEtienne Carriere 	unsigned int i = 0;
577c7cf2933SEtienne Carriere 
578c7cf2933SEtienne Carriere 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++)
579c7cf2933SEtienne Carriere 		if (strcmp(name, regulators_table[i].dt_node_name) == 0)
580c7cf2933SEtienne Carriere 			return &regulators_table[i];
581c7cf2933SEtienne Carriere 
5826a63363bSEtienne Carriere 	DMSG("Regulator %s not found", name);
5836a63363bSEtienne Carriere 	return NULL;
584c7cf2933SEtienne Carriere }
585c7cf2933SEtienne Carriere 
stpmic1_regulator_is_valid(const char * name)586e0f7e777SEtienne Carriere bool stpmic1_regulator_is_valid(const char *name)
587e0f7e777SEtienne Carriere {
588e0f7e777SEtienne Carriere 	return get_regulator_data(name);
589e0f7e777SEtienne Carriere }
590e0f7e777SEtienne Carriere 
stpmic1_regulator_levels_mv(const char * name,const uint16_t ** levels,size_t * levels_count)5918537f7ebSMarouene Boubakri void stpmic1_regulator_levels_mv(const char *name,
592c52a7c2eSEtienne Carriere 				 const uint16_t **levels,
593c52a7c2eSEtienne Carriere 				 size_t *levels_count)
594c52a7c2eSEtienne Carriere {
595c52a7c2eSEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
596c52a7c2eSEtienne Carriere 
5978537f7ebSMarouene Boubakri 	assert(regul);
598c52a7c2eSEtienne Carriere 
599*8c49825dSEtienne Carriere 	if (levels_count) {
600c52a7c2eSEtienne Carriere 		*levels_count = regul->voltage_table_size;
601c52a7c2eSEtienne Carriere 
602*8c49825dSEtienne Carriere 		/* Remove last cell 0xFFFF that is not a voltage level */
603*8c49825dSEtienne Carriere 		if (regul->voltage_table == ldo3_voltage_table)
604*8c49825dSEtienne Carriere 			(*levels_count)--;
605*8c49825dSEtienne Carriere 	}
606*8c49825dSEtienne Carriere 
607c52a7c2eSEtienne Carriere 	if (levels)
608c52a7c2eSEtienne Carriere 		*levels = regul->voltage_table;
609c52a7c2eSEtienne Carriere }
610c52a7c2eSEtienne Carriere 
voltage_to_index(const char * name,uint16_t millivolts)6116a63363bSEtienne Carriere static size_t voltage_to_index(const char *name, uint16_t millivolts)
612c7cf2933SEtienne Carriere {
613c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
614c7cf2933SEtienne Carriere 	unsigned int i = 0;
615c7cf2933SEtienne Carriere 
616c7cf2933SEtienne Carriere 	assert(regul->voltage_table);
617c7cf2933SEtienne Carriere 	for (i = 0; i < regul->voltage_table_size; i++)
618c7cf2933SEtienne Carriere 		if (regul->voltage_table[i] == millivolts)
619c7cf2933SEtienne Carriere 			return i;
620c7cf2933SEtienne Carriere 
6216a63363bSEtienne Carriere 	return VOLTAGE_INDEX_INVALID;
622c7cf2933SEtienne Carriere }
623c7cf2933SEtienne Carriere 
stpmic1_powerctrl_on(void)624c7cf2933SEtienne Carriere int stpmic1_powerctrl_on(void)
625c7cf2933SEtienne Carriere {
626c7cf2933SEtienne Carriere 	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
627c7cf2933SEtienne Carriere 				       PWRCTRL_PIN_VALID);
628c7cf2933SEtienne Carriere }
629c7cf2933SEtienne Carriere 
stpmic1_switch_off(void)630c7cf2933SEtienne Carriere int stpmic1_switch_off(void)
631c7cf2933SEtienne Carriere {
632c7cf2933SEtienne Carriere 	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
633c7cf2933SEtienne Carriere 				       SOFTWARE_SWITCH_OFF_ENABLED);
634c7cf2933SEtienne Carriere }
635c7cf2933SEtienne Carriere 
stpmic1_regulator_enable(const char * name)636c7cf2933SEtienne Carriere int stpmic1_regulator_enable(const char *name)
637c7cf2933SEtienne Carriere {
638c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
639c7cf2933SEtienne Carriere 
64068cfb83dSEtienne Carriere 	return stpmic1_register_update(regul->control_reg,
64168cfb83dSEtienne Carriere 				       BIT(regul->enable_pos),
64268cfb83dSEtienne Carriere 				       BIT(regul->enable_pos));
643c7cf2933SEtienne Carriere }
644c7cf2933SEtienne Carriere 
stpmic1_regulator_disable(const char * name)645c7cf2933SEtienne Carriere int stpmic1_regulator_disable(const char *name)
646c7cf2933SEtienne Carriere {
647c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
648c7cf2933SEtienne Carriere 
64968cfb83dSEtienne Carriere 	return stpmic1_register_update(regul->control_reg, 0,
65068cfb83dSEtienne Carriere 				       BIT(regul->enable_pos));
651c7cf2933SEtienne Carriere }
652c7cf2933SEtienne Carriere 
stpmic1_is_regulator_enabled(const char * name)6532619b28cSEtienne Carriere bool stpmic1_is_regulator_enabled(const char *name)
654c7cf2933SEtienne Carriere {
655c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
656c7cf2933SEtienne Carriere 	uint8_t val = 0;
657c7cf2933SEtienne Carriere 
658c7cf2933SEtienne Carriere 	if (stpmic1_register_read(regul->control_reg, &val))
659c7cf2933SEtienne Carriere 		panic();
660c7cf2933SEtienne Carriere 
66168cfb83dSEtienne Carriere 	return val & BIT(regul->enable_pos);
662c7cf2933SEtienne Carriere }
663c7cf2933SEtienne Carriere 
6641764a894SEtienne Carriere /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
find_plat_mask(const char * name)6651764a894SEtienne Carriere static uint8_t find_plat_mask(const char *name)
6661764a894SEtienne Carriere {
6671764a894SEtienne Carriere 	if (!strncmp(name, "buck", 4))
6681764a894SEtienne Carriere 		return BUCK_VOLTAGE_MASK;
6691764a894SEtienne Carriere 
6701764a894SEtienne Carriere 	if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4"))
6711764a894SEtienne Carriere 		return LDO_VOLTAGE_MASK;
6721764a894SEtienne Carriere 
6731764a894SEtienne Carriere 	return 0;
6741764a894SEtienne Carriere }
6751764a894SEtienne Carriere 
stpmic1_regulator_voltage_set(const char * name,uint16_t millivolts)676c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
677c7cf2933SEtienne Carriere {
6786a63363bSEtienne Carriere 	size_t voltage_index = voltage_to_index(name, millivolts);
679c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
680c7cf2933SEtienne Carriere 	uint8_t mask = 0;
681c7cf2933SEtienne Carriere 
6826a63363bSEtienne Carriere 	if (voltage_index == VOLTAGE_INDEX_INVALID)
6836a63363bSEtienne Carriere 		return -1;
6846a63363bSEtienne Carriere 
6851764a894SEtienne Carriere 	mask = find_plat_mask(name);
6861764a894SEtienne Carriere 	if (!mask)
687c7cf2933SEtienne Carriere 		return 0;
688c7cf2933SEtienne Carriere 
689c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->control_reg,
690c7cf2933SEtienne Carriere 				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
691c7cf2933SEtienne Carriere 				       mask);
692c7cf2933SEtienne Carriere }
693c7cf2933SEtienne Carriere 
stpmic1_regulator_mask_reset_set(const char * name)694c7cf2933SEtienne Carriere int stpmic1_regulator_mask_reset_set(const char *name)
695c7cf2933SEtienne Carriere {
696c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
697c7cf2933SEtienne Carriere 
6983f692bdfSEtienne Carriere 	if (regul->control_reg == USB_CONTROL_REG) {
6993f692bdfSEtienne Carriere 		DMSG("No reset for USB control");
7003f692bdfSEtienne Carriere 		return -1;
7013f692bdfSEtienne Carriere 	}
7023f692bdfSEtienne Carriere 
703c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->mask_reset_reg,
704c7cf2933SEtienne Carriere 				       BIT(regul->mask_reset_pos),
705c7cf2933SEtienne Carriere 				       LDO_BUCK_RESET_MASK <<
706c7cf2933SEtienne Carriere 				       regul->mask_reset_pos);
707c7cf2933SEtienne Carriere }
708c7cf2933SEtienne Carriere 
stpmic1_bo_enable_cfg(const char * name,struct stpmic1_bo_cfg * cfg)7096149e2d8SEtienne Carriere int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
7106149e2d8SEtienne Carriere {
7116149e2d8SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
7126149e2d8SEtienne Carriere 
7136149e2d8SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
7146149e2d8SEtienne Carriere 	cfg->enable_pos = regul->enable_pos;
7156149e2d8SEtienne Carriere 
7166149e2d8SEtienne Carriere 	return 0;
7176149e2d8SEtienne Carriere }
7186149e2d8SEtienne Carriere 
stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg * cfg)719eb5d5313SEtienne Carriere int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg)
720eb5d5313SEtienne Carriere {
72168cfb83dSEtienne Carriere 	return stpmic1_register_update(cfg->ctrl_reg,
72268cfb83dSEtienne Carriere 				       BIT(cfg->enable_pos),
72368cfb83dSEtienne Carriere 				       BIT(cfg->enable_pos));
724eb5d5313SEtienne Carriere }
725eb5d5313SEtienne Carriere 
726eb5d5313SEtienne Carriere /* 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)72744219e70SEtienne Carriere int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt,
728eb5d5313SEtienne Carriere 			   struct stpmic1_bo_cfg *cfg)
729eb5d5313SEtienne Carriere {
7306a63363bSEtienne Carriere 	size_t min_index = voltage_to_index(name, min_millivolt);
731eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
732eb5d5313SEtienne Carriere 	uint8_t mask = 0;
733eb5d5313SEtienne Carriere 
7346a63363bSEtienne Carriere 	if (min_index == VOLTAGE_INDEX_INVALID)
7356a63363bSEtienne Carriere 		panic();
7366a63363bSEtienne Carriere 
7371764a894SEtienne Carriere 	mask = find_plat_mask(name);
7381764a894SEtienne Carriere 	if (!mask)
739eb5d5313SEtienne Carriere 		return 1;
740eb5d5313SEtienne Carriere 
741eb5d5313SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
74244219e70SEtienne Carriere 	cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT;
743eb5d5313SEtienne Carriere 	cfg->mask = mask;
744eb5d5313SEtienne Carriere 
745eb5d5313SEtienne Carriere 	return 0;
746eb5d5313SEtienne Carriere }
747eb5d5313SEtienne Carriere 
stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg * cfg)748eb5d5313SEtienne Carriere int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg)
749eb5d5313SEtienne Carriere {
75044219e70SEtienne Carriere 	uint8_t value = 0;
75144219e70SEtienne Carriere 
75244219e70SEtienne Carriere 	assert(cfg->ctrl_reg);
75344219e70SEtienne Carriere 
75444219e70SEtienne Carriere 	if (stpmic1_register_read(cfg->ctrl_reg, &value))
75544219e70SEtienne Carriere 		return -1;
75644219e70SEtienne Carriere 
757187ba5c2SEtienne Carriere 	if ((value & cfg->mask) >= cfg->min_value)
75844219e70SEtienne Carriere 		return 0;
75944219e70SEtienne Carriere 
76044219e70SEtienne Carriere 	return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value,
76144219e70SEtienne Carriere 				       cfg->mask);
762eb5d5313SEtienne Carriere }
763eb5d5313SEtienne Carriere 
stpmic1_bo_pull_down_cfg(const char * name,struct stpmic1_bo_cfg * cfg)764eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
765eb5d5313SEtienne Carriere {
766eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
767eb5d5313SEtienne Carriere 
768ef18a901SEtienne Carriere 	if (!regul->pull_down_reg) {
769ef18a901SEtienne Carriere 		DMSG("No pull down for regu %s", name);
770ef18a901SEtienne Carriere 		panic();
771ef18a901SEtienne Carriere 	}
772ef18a901SEtienne Carriere 
773eb5d5313SEtienne Carriere 	cfg->pd_reg = regul->pull_down_reg;
774eb5d5313SEtienne Carriere 	cfg->pd_value = BIT(regul->pull_down_pos);
775eb5d5313SEtienne Carriere 	cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos;
776eb5d5313SEtienne Carriere 
777eb5d5313SEtienne Carriere 	return 0;
778eb5d5313SEtienne Carriere }
779eb5d5313SEtienne Carriere 
stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg * cfg)780eb5d5313SEtienne Carriere int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg)
781eb5d5313SEtienne Carriere {
782ef18a901SEtienne Carriere 	assert(cfg->pd_reg);
783ef18a901SEtienne Carriere 
784eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->pd_reg, cfg->pd_value,
785eb5d5313SEtienne Carriere 				       cfg->pd_mask);
786eb5d5313SEtienne Carriere }
787eb5d5313SEtienne Carriere 
stpmic1_bo_mask_reset_cfg(const char * name,struct stpmic1_bo_cfg * cfg)788eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg)
789eb5d5313SEtienne Carriere {
790eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
791eb5d5313SEtienne Carriere 
792ef18a901SEtienne Carriere 	if (!regul->mask_reset_reg) {
793ef18a901SEtienne Carriere 		DMSG("No reset mask for regu %s", name);
794ef18a901SEtienne Carriere 		panic();
795ef18a901SEtienne Carriere 	}
796ef18a901SEtienne Carriere 
797eb5d5313SEtienne Carriere 	cfg->mrst_reg = regul->mask_reset_reg;
798eb5d5313SEtienne Carriere 	cfg->mrst_value = BIT(regul->mask_reset_pos);
799eb5d5313SEtienne Carriere 	cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos;
800eb5d5313SEtienne Carriere 
801eb5d5313SEtienne Carriere 	return 0;
802eb5d5313SEtienne Carriere }
803eb5d5313SEtienne Carriere 
stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg * cfg)804eb5d5313SEtienne Carriere int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg)
805eb5d5313SEtienne Carriere {
806ef18a901SEtienne Carriere 	assert(cfg->mrst_reg);
807ef18a901SEtienne Carriere 
808eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value,
809eb5d5313SEtienne Carriere 				       cfg->mrst_mask);
810eb5d5313SEtienne Carriere }
811eb5d5313SEtienne Carriere 
stpmic1_regulator_voltage_get(const char * name)812c7cf2933SEtienne Carriere int stpmic1_regulator_voltage_get(const char *name)
813c7cf2933SEtienne Carriere {
814c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
815c7cf2933SEtienne Carriere 	uint8_t value = 0;
816c7cf2933SEtienne Carriere 	uint8_t mask = 0;
817c7cf2933SEtienne Carriere 
8181764a894SEtienne Carriere 	mask = find_plat_mask(name);
8191764a894SEtienne Carriere 	if (!mask)
820c7cf2933SEtienne Carriere 		return 0;
821c7cf2933SEtienne Carriere 
822c7cf2933SEtienne Carriere 	if (stpmic1_register_read(regul->control_reg, &value))
823c7cf2933SEtienne Carriere 		return -1;
824c7cf2933SEtienne Carriere 
825c7cf2933SEtienne Carriere 	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
826c7cf2933SEtienne Carriere 
827c7cf2933SEtienne Carriere 	if (value > regul->voltage_table_size)
828c7cf2933SEtienne Carriere 		return -1;
829c7cf2933SEtienne Carriere 
830c7cf2933SEtienne Carriere 	return regul->voltage_table[value];
831c7cf2933SEtienne Carriere }
832c7cf2933SEtienne Carriere 
stpmic1_lp_copy_reg(const char * name)833c7cf2933SEtienne Carriere int stpmic1_lp_copy_reg(const char *name)
834c7cf2933SEtienne Carriere {
835c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
836c7cf2933SEtienne Carriere 	uint8_t val = 0;
837c7cf2933SEtienne Carriere 	int status = 0;
838c7cf2933SEtienne Carriere 
839972b3d9aSEtienne Carriere 	if (!regul->low_power_reg)
840972b3d9aSEtienne Carriere 		return -1;
841972b3d9aSEtienne Carriere 
842c7cf2933SEtienne Carriere 	status = stpmic1_register_read(regul->control_reg, &val);
843c7cf2933SEtienne Carriere 	if (status)
844c7cf2933SEtienne Carriere 		return status;
845c7cf2933SEtienne Carriere 
846c7cf2933SEtienne Carriere 	return stpmic1_register_write(regul->low_power_reg, val);
847c7cf2933SEtienne Carriere }
848c7cf2933SEtienne Carriere 
stpmic1_regu_has_lp_cfg(const char * name)849972b3d9aSEtienne Carriere bool stpmic1_regu_has_lp_cfg(const char *name)
850972b3d9aSEtienne Carriere {
851972b3d9aSEtienne Carriere 	return get_regulator_data(name)->low_power_reg;
852972b3d9aSEtienne Carriere }
853972b3d9aSEtienne Carriere 
stpmic1_lp_cfg(const char * name,struct stpmic1_lp_cfg * cfg)854eb5d5313SEtienne Carriere int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg)
855eb5d5313SEtienne Carriere {
856eb5d5313SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
857eb5d5313SEtienne Carriere 
858972b3d9aSEtienne Carriere 	if (!regul->low_power_reg)
859972b3d9aSEtienne Carriere 		return -1;
860972b3d9aSEtienne Carriere 
861eb5d5313SEtienne Carriere 	cfg->ctrl_reg = regul->control_reg;
862eb5d5313SEtienne Carriere 	cfg->lp_reg = regul->low_power_reg;
863eb5d5313SEtienne Carriere 
864eb5d5313SEtienne Carriere 	return 0;
865eb5d5313SEtienne Carriere }
866eb5d5313SEtienne Carriere 
stpmic1_lp_load_unpg(struct stpmic1_lp_cfg * cfg)867eb5d5313SEtienne Carriere int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg)
868eb5d5313SEtienne Carriere {
869eb5d5313SEtienne Carriere 	uint8_t val = 0;
870eb5d5313SEtienne Carriere 	int status = 0;
871eb5d5313SEtienne Carriere 
872ef18a901SEtienne Carriere 	assert(cfg->lp_reg);
873ef18a901SEtienne Carriere 
874eb5d5313SEtienne Carriere 	status = stpmic1_register_read(cfg->ctrl_reg, &val);
875eb5d5313SEtienne Carriere 	if (!status)
876eb5d5313SEtienne Carriere 		status = stpmic1_register_write(cfg->lp_reg, val);
877eb5d5313SEtienne Carriere 
878eb5d5313SEtienne Carriere 	return status;
879eb5d5313SEtienne Carriere }
880eb5d5313SEtienne Carriere 
stpmic1_lp_reg_on_off(const char * name,uint8_t enable)881c7cf2933SEtienne Carriere int stpmic1_lp_reg_on_off(const char *name, uint8_t enable)
882c7cf2933SEtienne Carriere {
883c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
884c7cf2933SEtienne Carriere 
885972b3d9aSEtienne Carriere 	if (!regul->low_power_reg)
886972b3d9aSEtienne Carriere 		return -1;
887972b3d9aSEtienne Carriere 
888c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg, enable,
889c7cf2933SEtienne Carriere 				       LDO_BUCK_ENABLE_MASK);
890c7cf2933SEtienne Carriere }
891c7cf2933SEtienne Carriere 
stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg * cfg,int enable)892eb5d5313SEtienne Carriere int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable)
893eb5d5313SEtienne Carriere {
894ef18a901SEtienne Carriere 	assert(cfg->lp_reg && (enable == 0 || enable == 1));
895ef18a901SEtienne Carriere 
896eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg, enable,
897eb5d5313SEtienne Carriere 				       LDO_BUCK_ENABLE_MASK);
898eb5d5313SEtienne Carriere }
899eb5d5313SEtienne Carriere 
stpmic1_lp_set_mode(const char * name,uint8_t hplp)900c7cf2933SEtienne Carriere int stpmic1_lp_set_mode(const char *name, uint8_t hplp)
901c7cf2933SEtienne Carriere {
902c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
903c7cf2933SEtienne Carriere 
904ef18a901SEtienne Carriere 	assert(regul->low_power_reg && (hplp == 0 || hplp == 1));
905ef18a901SEtienne Carriere 
906c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg,
90742032ea0SEtienne Carriere 				       hplp << LDO_BUCK_HPLP_POS,
90842032ea0SEtienne Carriere 				       BIT(LDO_BUCK_HPLP_POS));
909c7cf2933SEtienne Carriere }
910c7cf2933SEtienne Carriere 
stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg * cfg,unsigned int mode)911eb5d5313SEtienne Carriere int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode)
912eb5d5313SEtienne Carriere {
913ef18a901SEtienne Carriere 	assert(cfg->lp_reg && (mode == 0 || mode == 1));
914eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg,
91542032ea0SEtienne Carriere 				       mode << LDO_BUCK_HPLP_POS,
91642032ea0SEtienne Carriere 				       BIT(LDO_BUCK_HPLP_POS));
917eb5d5313SEtienne Carriere }
918eb5d5313SEtienne Carriere 
stpmic1_lp_set_voltage(const char * name,uint16_t millivolts)919c7cf2933SEtienne Carriere int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts)
920c7cf2933SEtienne Carriere {
9216a63363bSEtienne Carriere 	size_t voltage_index = voltage_to_index(name, millivolts);
922c7cf2933SEtienne Carriere 	const struct regul_struct *regul = get_regulator_data(name);
923c7cf2933SEtienne Carriere 	uint8_t mask = 0;
924c7cf2933SEtienne Carriere 
9256a63363bSEtienne Carriere 	assert(voltage_index != VOLTAGE_INDEX_INVALID);
9266a63363bSEtienne Carriere 
9271764a894SEtienne Carriere 	mask = find_plat_mask(name);
9281764a894SEtienne Carriere 	if (!mask)
929c7cf2933SEtienne Carriere 		return 0;
930c7cf2933SEtienne Carriere 
931c7cf2933SEtienne Carriere 	return stpmic1_register_update(regul->low_power_reg, voltage_index << 2,
932c7cf2933SEtienne Carriere 				       mask);
933c7cf2933SEtienne Carriere }
934c7cf2933SEtienne Carriere 
935eb5d5313SEtienne Carriere /* 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)936eb5d5313SEtienne Carriere int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts,
937eb5d5313SEtienne Carriere 			   struct stpmic1_lp_cfg *cfg)
938eb5d5313SEtienne Carriere 
939eb5d5313SEtienne Carriere {
9406a63363bSEtienne Carriere 	size_t voltage_index = voltage_to_index(name, millivolts);
941eb5d5313SEtienne Carriere 	uint8_t mask = 0;
942eb5d5313SEtienne Carriere 
9431764a894SEtienne Carriere 	mask = find_plat_mask(name);
9441764a894SEtienne Carriere 	if (!mask)
945eb5d5313SEtienne Carriere 		return 1;
946eb5d5313SEtienne Carriere 
9476a63363bSEtienne Carriere 	assert(voltage_index != VOLTAGE_INDEX_INVALID &&
9486a63363bSEtienne Carriere 	       cfg->lp_reg == get_regulator_data(name)->low_power_reg);
9496a63363bSEtienne Carriere 
950eb5d5313SEtienne Carriere 	cfg->value = voltage_index << 2;
951eb5d5313SEtienne Carriere 	cfg->mask = mask;
952eb5d5313SEtienne Carriere 
953eb5d5313SEtienne Carriere 	return 0;
954eb5d5313SEtienne Carriere }
955eb5d5313SEtienne Carriere 
stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg * cfg)956eb5d5313SEtienne Carriere int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg)
957eb5d5313SEtienne Carriere {
958ef18a901SEtienne Carriere 	assert(cfg->lp_reg);
959ef18a901SEtienne Carriere 
960eb5d5313SEtienne Carriere 	return stpmic1_register_update(cfg->lp_reg, cfg->value,	cfg->mask);
961eb5d5313SEtienne Carriere }
962eb5d5313SEtienne Carriere 
stpmic1_register_read(uint8_t register_id,uint8_t * value)963c7cf2933SEtienne Carriere int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
964c7cf2933SEtienne Carriere {
965c7cf2933SEtienne Carriere 	struct i2c_handle_s *i2c = pmic_i2c_handle;
966c7cf2933SEtienne Carriere 
967eb5d5313SEtienne Carriere 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
968eb5d5313SEtienne Carriere 					    register_id, value,
969eb5d5313SEtienne Carriere 					    false /* !write */);
970c7cf2933SEtienne Carriere }
971c7cf2933SEtienne Carriere 
stpmic1_register_write(uint8_t register_id,uint8_t value)972c7cf2933SEtienne Carriere int stpmic1_register_write(uint8_t register_id, uint8_t value)
973c7cf2933SEtienne Carriere {
974c7cf2933SEtienne Carriere 	struct i2c_handle_s *i2c = pmic_i2c_handle;
975c7cf2933SEtienne Carriere 	uint8_t val = value;
976c7cf2933SEtienne Carriere 
977eb5d5313SEtienne Carriere 	return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr,
978eb5d5313SEtienne Carriere 					    register_id, &val,
979eb5d5313SEtienne Carriere 					    true /* write */);
980c7cf2933SEtienne Carriere }
981c7cf2933SEtienne Carriere 
stpmic1_register_update(uint8_t register_id,uint8_t value,uint8_t mask)982c7cf2933SEtienne Carriere int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
983c7cf2933SEtienne Carriere {
984c7cf2933SEtienne Carriere 	int status = 0;
985c7cf2933SEtienne Carriere 	uint8_t val = 0;
986c7cf2933SEtienne Carriere 
987c7cf2933SEtienne Carriere 	status = stpmic1_register_read(register_id, &val);
988c7cf2933SEtienne Carriere 	if (status)
989c7cf2933SEtienne Carriere 		return status;
990c7cf2933SEtienne Carriere 
991c7cf2933SEtienne Carriere 	val = (val & ~mask) | (value & mask);
992c7cf2933SEtienne Carriere 
993c7cf2933SEtienne Carriere 	return stpmic1_register_write(register_id, val);
994c7cf2933SEtienne Carriere }
995c7cf2933SEtienne Carriere 
stpmic1_bind_i2c(struct i2c_handle_s * i2c_handle,uint16_t i2c_addr)996c7cf2933SEtienne Carriere void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
997c7cf2933SEtienne Carriere {
998c7cf2933SEtienne Carriere 	pmic_i2c_handle = i2c_handle;
999c7cf2933SEtienne Carriere 	pmic_i2c_addr = i2c_addr;
1000c7cf2933SEtienne Carriere }
1001c7cf2933SEtienne Carriere 
stpmic1_dump_regulators(void)1002c7cf2933SEtienne Carriere void stpmic1_dump_regulators(void)
1003c7cf2933SEtienne Carriere {
1004c7cf2933SEtienne Carriere 	size_t i = 0;
1005c7cf2933SEtienne Carriere 	char __maybe_unused const *name = NULL;
1006c7cf2933SEtienne Carriere 
1007c7cf2933SEtienne Carriere 	for (i = 0; i < ARRAY_SIZE(regulators_table); i++) {
1008c7cf2933SEtienne Carriere 		if (!regulators_table[i].control_reg)
1009c7cf2933SEtienne Carriere 			continue;
1010c7cf2933SEtienne Carriere 
1011c7cf2933SEtienne Carriere 		name = regulators_table[i].dt_node_name;
1012c7cf2933SEtienne Carriere 		DMSG("PMIC regul %s: %sable, %dmV",
1013c7cf2933SEtienne Carriere 		     name, stpmic1_is_regulator_enabled(name) ? "en" : "dis",
1014c7cf2933SEtienne Carriere 		     stpmic1_regulator_voltage_get(name));
1015c7cf2933SEtienne Carriere 	}
1016c7cf2933SEtienne Carriere }
1017c7cf2933SEtienne Carriere 
stpmic1_get_version(unsigned long * version)1018c7cf2933SEtienne Carriere int stpmic1_get_version(unsigned long *version)
1019c7cf2933SEtienne Carriere {
1020c7cf2933SEtienne Carriere 	uint8_t read_val = 0;
1021c7cf2933SEtienne Carriere 
1022c7cf2933SEtienne Carriere 	if (stpmic1_register_read(VERSION_STATUS_REG, &read_val))
1023c7cf2933SEtienne Carriere 		return -1;
1024c7cf2933SEtienne Carriere 
1025c7cf2933SEtienne Carriere 	*version = read_val;
1026c7cf2933SEtienne Carriere 	return 0;
1027c7cf2933SEtienne Carriere }
1028