1 /*
2  * Copyright (c) 2021 NXP
3  * Copyright (c) 2023 Martin Kiepfer <mrmarteng@teleschirm.org>
4  * Copyright (c) 2024 Lothar Felten <lothar.felten@gmail.com>
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <errno.h>
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/drivers/i2c.h>
12 #include <zephyr/drivers/regulator.h>
13 #include <zephyr/sys/linear_range.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/dt-bindings/regulator/axp192.h>
16 #include <zephyr/logging/log.h>
17 #include <zephyr/logging/log_instance.h>
18 #include <zephyr/drivers/mfd/axp192.h>
19 
20 LOG_MODULE_REGISTER(regulator_axp192, CONFIG_REGULATOR_LOG_LEVEL);
21 
22 /* AXP192 register defines */
23 #define AXP192_REG_EXTEN_DCDC2_CONTROL   0x10U
24 #define AXP192_REG_DCDC123_LDO23_CONTROL 0x12U
25 #define AXP192_REG_DCDC2_VOLTAGE         0x23U
26 #define AXP192_REG_DCDC2_SLOPE           0x25U
27 #define AXP192_REG_DCDC1_VOLTAGE         0x26U
28 #define AXP192_REG_DCDC3_VOLTAGE         0x27U
29 #define AXP192_REG_LDO23_VOLTAGE         0x28U
30 #define AXP192_REG_DCDC123_WORKMODE      0x80U
31 #define AXP192_REG_GPIO0_CONTROL         0x90U
32 #define AXP192_REG_LDOIO0_VOLTAGE        0x91U
33 
34 /* AXP2101 register defines */
35 #define AXP2101_REG_CHGLED            0x69U
36 #define AXP2101_REG_DCDC12345_CONTROL 0x80U
37 #define AXP2101_REG_DCDCS_PWM_CONTROL 0x81U
38 #define AXP2101_REG_DCDC1_VOLTAGE     0x82U
39 #define AXP2101_REG_DCDC2_VOLTAGE     0x83U
40 #define AXP2101_REG_DCDC3_VOLTAGE     0x84U
41 #define AXP2101_REG_DCDC4_VOLTAGE     0x85U
42 #define AXP2101_REG_DCDC5_VOLTAGE     0x86U
43 #define AXP2101_REG_LDOGRP1_CONTROL   0x90U
44 #define AXP2101_REG_LDOGRP2_CONTROL   0x91U
45 #define AXP2101_REG_ALDO1_VOLTAGE     0x92U
46 #define AXP2101_REG_ALDO2_VOLTAGE     0x93U
47 #define AXP2101_REG_ALDO3_VOLTAGE     0x94U
48 #define AXP2101_REG_ALDO4_VOLTAGE     0x95U
49 #define AXP2101_REG_BLDO1_VOLTAGE     0x96U
50 #define AXP2101_REG_BLDO2_VOLTAGE     0x97U
51 #define AXP2101_REG_CPUSLDO_VOLTAGE   0x98U
52 #define AXP2101_REG_DLDO1_VOLTAGE     0x99U
53 #define AXP2101_REG_DLDO2_VOLTAGE     0x9AU
54 
55 #define AXP2101_CHGLED_CTRL_MASK   0x3
56 #define AXP2101_CHGLED_CTRL_OFFSET 1
57 
58 #define AXP2101_VBUS_CFG_REG                0
59 #define AXP2101_VBUS_CFG_VAL_VBUSEN_DISABLE 0
60 
61 #define AXP_NODE_HAS_CHILD(node, child) DT_NODE_HAS_STATUS_OKAY(DT_CHILD(node, child)) |
62 #define AXP192_ANY_HAS_CHILD(child)                                                                \
63 	(DT_FOREACH_STATUS_OKAY_VARGS(x_powers_axp192_regulator, AXP_NODE_HAS_CHILD, child) 0)
64 #define AXP2101_ANY_HAS_CHILD(child)                                                               \
65 	(DT_FOREACH_STATUS_OKAY_VARGS(x_powers_axp2101_regulator, AXP_NODE_HAS_CHILD, child) 0)
66 
67 struct regulator_axp192_desc {
68 	const uint8_t enable_reg;
69 	const uint8_t enable_mask;
70 	const uint8_t enable_val;
71 	const uint8_t vsel_reg;
72 	const uint8_t vsel_mask;
73 	const uint8_t vsel_bitpos;
74 	const int32_t max_ua;
75 	const uint8_t workmode_reg;
76 	const uint8_t workmode_mask;
77 	const uint8_t workmode_pwm_val;
78 	const uint8_t num_ranges;
79 	const struct linear_range *ranges;
80 };
81 
82 struct regulator_axp192_data {
83 	struct regulator_common_data data;
84 };
85 
86 struct regulator_axp192_config {
87 	struct regulator_common_config common;
88 	const struct regulator_axp192_desc *desc;
89 	const struct device *mfd;
90 	const struct i2c_dt_spec i2c;
91 };
92 
93 static const struct linear_range axp192_dcdc1_ranges[] = {
94 	LINEAR_RANGE_INIT(700000U, 25000U, 0x00U, 0x7FU),
95 };
96 
97 __maybe_unused static const struct regulator_axp192_desc axp192_dcdc1_desc = {
98 	.enable_reg = AXP192_REG_DCDC123_LDO23_CONTROL,
99 	.enable_mask = 0x01U,
100 	.enable_val = 0x01U,
101 	.vsel_reg = AXP192_REG_DCDC1_VOLTAGE,
102 	.vsel_mask = 0x7FU,
103 	.vsel_bitpos = 0U,
104 	.max_ua = 1200000U,
105 	.workmode_reg = AXP192_REG_DCDC123_WORKMODE,
106 	.workmode_mask = 0x08U,
107 	.workmode_pwm_val = 0x08U,
108 	.ranges = axp192_dcdc1_ranges,
109 	.num_ranges = ARRAY_SIZE(axp192_dcdc1_ranges),
110 };
111 
112 static const struct linear_range axp192_dcdc2_ranges[] = {
113 	LINEAR_RANGE_INIT(700000U, 25000U, 0x00U, 0x3FU),
114 };
115 
116 __maybe_unused static const struct regulator_axp192_desc axp192_dcdc2_desc = {
117 	.enable_reg = AXP192_REG_EXTEN_DCDC2_CONTROL,
118 	.enable_mask = 0x01U,
119 	.enable_val = 0x01U,
120 	.vsel_reg = AXP192_REG_DCDC2_VOLTAGE,
121 	.vsel_mask = 0x3FU,
122 	.vsel_bitpos = 0U,
123 	.max_ua = 1600000U,
124 	.workmode_reg = AXP192_REG_DCDC123_WORKMODE,
125 	.workmode_mask = 0x04U,
126 	.workmode_pwm_val = 0x04U,
127 	.ranges = axp192_dcdc2_ranges,
128 	.num_ranges = ARRAY_SIZE(axp192_dcdc2_ranges),
129 };
130 
131 static const struct linear_range axp192_dcdc3_ranges[] = {
132 	LINEAR_RANGE_INIT(700000U, 25000U, 0x00U, 0x7FU),
133 };
134 
135 __maybe_unused static const struct regulator_axp192_desc axp192_dcdc3_desc = {
136 	.enable_reg = AXP192_REG_DCDC123_LDO23_CONTROL,
137 	.enable_mask = 0x02U,
138 	.enable_val = 0x02U,
139 	.vsel_reg = AXP192_REG_DCDC3_VOLTAGE,
140 	.vsel_mask = 0x7FU,
141 	.vsel_bitpos = 0U,
142 	.max_ua = 700000U,
143 	.workmode_reg = AXP192_REG_DCDC123_WORKMODE,
144 	.workmode_mask = 0x02U,
145 	.workmode_pwm_val = 0x02U,
146 	.ranges = axp192_dcdc3_ranges,
147 	.num_ranges = ARRAY_SIZE(axp192_dcdc3_ranges),
148 };
149 
150 static const struct linear_range axp192_ldoio0_ranges[] = {
151 	LINEAR_RANGE_INIT(1800000u, 100000u, 0x00u, 0x0Fu),
152 };
153 
154 __maybe_unused static const struct regulator_axp192_desc axp192_ldoio0_desc = {
155 	.enable_reg = AXP192_REG_GPIO0_CONTROL,
156 	.enable_mask = 0x07u,
157 	.enable_val = 0x03u,
158 	.vsel_reg = AXP192_REG_LDOIO0_VOLTAGE,
159 	.vsel_mask = 0xF0u,
160 	.vsel_bitpos = 4u,
161 	.max_ua = 50000u,
162 	.workmode_reg = 0u,
163 	.workmode_mask = 0u,
164 	.ranges = axp192_ldoio0_ranges,
165 	.num_ranges = ARRAY_SIZE(axp192_ldoio0_ranges),
166 };
167 
168 static const struct linear_range axp192_ldo2_ranges[] = {
169 	LINEAR_RANGE_INIT(1800000U, 100000U, 0x00U, 0x0FU),
170 };
171 
172 __maybe_unused static const struct regulator_axp192_desc axp192_ldo2_desc = {
173 	.enable_reg = AXP192_REG_DCDC123_LDO23_CONTROL,
174 	.enable_mask = 0x04U,
175 	.enable_val = 0x04U,
176 	.vsel_reg = AXP192_REG_LDO23_VOLTAGE,
177 	.vsel_mask = 0xF0U,
178 	.vsel_bitpos = 4U,
179 	.max_ua = 200000U,
180 	.workmode_reg = 0U,
181 	.workmode_mask = 0U,
182 	.ranges = axp192_ldo2_ranges,
183 	.num_ranges = ARRAY_SIZE(axp192_ldo2_ranges),
184 };
185 
186 static const struct linear_range axp192_ldo3_ranges[] = {
187 	LINEAR_RANGE_INIT(1800000U, 100000U, 0x00U, 0x0FU),
188 };
189 
190 __maybe_unused static const struct regulator_axp192_desc axp192_ldo3_desc = {
191 	.enable_reg = AXP192_REG_DCDC123_LDO23_CONTROL,
192 	.enable_mask = 0x08U,
193 	.enable_val = 0x08U,
194 	.vsel_reg = AXP192_REG_LDO23_VOLTAGE,
195 	.vsel_mask = 0x0FU,
196 	.vsel_bitpos = 0U,
197 	.max_ua = 200000U,
198 	.workmode_reg = 0U,
199 	.workmode_mask = 0U,
200 	.ranges = axp192_ldo3_ranges,
201 	.num_ranges = ARRAY_SIZE(axp192_ldo3_ranges),
202 };
203 
204 static const struct linear_range axp2101_dcdc1_ranges[] = {
205 	LINEAR_RANGE_INIT(1500000U, 100000U, 0U, 19U),
206 };
207 
208 __maybe_unused static const struct regulator_axp192_desc axp2101_dcdc1_desc = {
209 	.enable_reg = AXP2101_REG_DCDC12345_CONTROL,
210 	.enable_mask = 0x01U,
211 	.enable_val = 0x01U,
212 	.vsel_reg = AXP2101_REG_DCDC1_VOLTAGE,
213 	.vsel_mask = 0x1FU,
214 	.vsel_bitpos = 0U,
215 	.max_ua = 2000000U,
216 	.ranges = axp2101_dcdc1_ranges,
217 	.num_ranges = ARRAY_SIZE(axp2101_dcdc1_ranges),
218 	.workmode_reg = AXP2101_REG_DCDCS_PWM_CONTROL,
219 	.workmode_mask = BIT(2),
220 	.workmode_pwm_val = BIT(2),
221 };
222 
223 static const struct linear_range axp2101_dcdc2_ranges[] = {
224 	LINEAR_RANGE_INIT(500000U, 10000U, 0U, 70U),
225 	LINEAR_RANGE_INIT(1220000U, 20000U, 71U, 87U),
226 };
227 
228 __maybe_unused static const struct regulator_axp192_desc axp2101_dcdc2_desc = {
229 	.enable_reg = AXP2101_REG_DCDC12345_CONTROL,
230 	.enable_mask = 0x02U,
231 	.enable_val = 0x02U,
232 	.vsel_reg = AXP2101_REG_DCDC2_VOLTAGE,
233 	.vsel_mask = 0x7FU,
234 	.vsel_bitpos = 0U,
235 	.max_ua = 2000000U,
236 	.ranges = axp2101_dcdc2_ranges,
237 	.num_ranges = ARRAY_SIZE(axp2101_dcdc2_ranges),
238 	.workmode_reg = AXP2101_REG_DCDCS_PWM_CONTROL,
239 	.workmode_mask = BIT(3),
240 	.workmode_pwm_val = BIT(3),
241 };
242 
243 static const struct linear_range axp2101_dcdc3_ranges[] = {
244 	LINEAR_RANGE_INIT(500000U, 10000U, 0U, 70U),
245 	LINEAR_RANGE_INIT(1220000U, 20000U, 71U, 87U),
246 	LINEAR_RANGE_INIT(1600000U, 100000U, 88U, 106U),
247 };
248 
249 __maybe_unused static const struct regulator_axp192_desc axp2101_dcdc3_desc = {
250 	.enable_reg = AXP2101_REG_DCDC12345_CONTROL,
251 	.enable_mask = 0x04U,
252 	.enable_val = 0x04U,
253 	.vsel_reg = AXP2101_REG_DCDC3_VOLTAGE,
254 	.vsel_mask = 0x7FU,
255 	.vsel_bitpos = 0U,
256 	.max_ua = 2000000U,
257 	.ranges = axp2101_dcdc3_ranges,
258 	.num_ranges = ARRAY_SIZE(axp2101_dcdc3_ranges),
259 	.workmode_reg = AXP2101_REG_DCDCS_PWM_CONTROL,
260 	.workmode_mask = BIT(4),
261 	.workmode_pwm_val = BIT(4),
262 };
263 
264 static const struct linear_range axp2101_dcdc4_ranges[] = {
265 	LINEAR_RANGE_INIT(500000U, 10000U, 0U, 70U),
266 	LINEAR_RANGE_INIT(1220000U, 20000U, 71U, 102U),
267 };
268 
269 __maybe_unused static const struct regulator_axp192_desc axp2101_dcdc4_desc = {
270 	.enable_reg = AXP2101_REG_DCDC12345_CONTROL,
271 	.enable_mask = 0x08U,
272 	.enable_val = 0x08U,
273 	.vsel_reg = AXP2101_REG_DCDC4_VOLTAGE,
274 	.vsel_mask = 0x7FU,
275 	.vsel_bitpos = 0U,
276 	.max_ua = 1500000U,
277 	.ranges = axp2101_dcdc4_ranges,
278 	.num_ranges = ARRAY_SIZE(axp2101_dcdc4_ranges),
279 	.workmode_reg = AXP2101_REG_DCDCS_PWM_CONTROL,
280 	.workmode_mask = BIT(5),
281 	.workmode_pwm_val = BIT(5),
282 };
283 
284 static const struct linear_range axp2101_dcdc5_ranges[] = {
285 	LINEAR_RANGE_INIT(1400000U, 100000U, 0U, 23U),
286 };
287 
288 __maybe_unused static const struct regulator_axp192_desc axp2101_dcdc5_desc = {
289 	.enable_reg = AXP2101_REG_DCDC12345_CONTROL,
290 	.enable_mask = 0x10U,
291 	.enable_val = 0x10U,
292 	.vsel_reg = AXP2101_REG_DCDC5_VOLTAGE,
293 	.vsel_mask = 0x1FU,
294 	.vsel_bitpos = 0U,
295 	.max_ua = 1000000U,
296 	.ranges = axp2101_dcdc5_ranges,
297 	.num_ranges = ARRAY_SIZE(axp2101_dcdc5_ranges),
298 };
299 
300 static const struct linear_range axp2101_abldox_ranges[] = {
301 	LINEAR_RANGE_INIT(500000U, 100000U, 0U, 30U),
302 };
303 
304 __maybe_unused static const struct regulator_axp192_desc axp2101_aldo1_desc = {
305 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
306 	.enable_mask = 0x01U,
307 	.enable_val = 0x01U,
308 	.vsel_reg = AXP2101_REG_ALDO1_VOLTAGE,
309 	.vsel_mask = 0x1FU,
310 	.vsel_bitpos = 0U,
311 	.max_ua = 300000U,
312 	.ranges = axp2101_abldox_ranges,
313 	.num_ranges = ARRAY_SIZE(axp2101_abldox_ranges),
314 };
315 
316 __maybe_unused static const struct regulator_axp192_desc axp2101_aldo2_desc = {
317 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
318 	.enable_mask = 0x02U,
319 	.enable_val = 0x02U,
320 	.vsel_reg = AXP2101_REG_ALDO2_VOLTAGE,
321 	.vsel_mask = 0x1FU,
322 	.vsel_bitpos = 0U,
323 	.max_ua = 300000U,
324 	.ranges = axp2101_abldox_ranges,
325 	.num_ranges = ARRAY_SIZE(axp2101_abldox_ranges),
326 };
327 
328 __maybe_unused static const struct regulator_axp192_desc axp2101_aldo3_desc = {
329 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
330 	.enable_mask = 0x04U,
331 	.enable_val = 0x04U,
332 	.vsel_reg = AXP2101_REG_ALDO3_VOLTAGE,
333 	.vsel_mask = 0x1FU,
334 	.vsel_bitpos = 0U,
335 	.max_ua = 300000U,
336 	.ranges = axp2101_abldox_ranges,
337 	.num_ranges = ARRAY_SIZE(axp2101_abldox_ranges),
338 };
339 
340 __maybe_unused static const struct regulator_axp192_desc axp2101_aldo4_desc = {
341 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
342 	.enable_mask = 0x08U,
343 	.enable_val = 0x08U,
344 	.vsel_reg = AXP2101_REG_ALDO4_VOLTAGE,
345 	.vsel_mask = 0x1FU,
346 	.vsel_bitpos = 0U,
347 	.max_ua = 300000U,
348 	.ranges = axp2101_abldox_ranges,
349 	.num_ranges = ARRAY_SIZE(axp2101_abldox_ranges),
350 };
351 
352 __maybe_unused static const struct regulator_axp192_desc axp2101_bldo1_desc = {
353 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
354 	.enable_mask = 0x10U,
355 	.enable_val = 0x10U,
356 	.vsel_reg = AXP2101_REG_BLDO1_VOLTAGE,
357 	.vsel_mask = 0x1FU,
358 	.vsel_bitpos = 0U,
359 	.max_ua = 300000U,
360 	.ranges = axp2101_abldox_ranges,
361 	.num_ranges = ARRAY_SIZE(axp2101_abldox_ranges),
362 	.workmode_reg = 0U,
363 	.workmode_mask = 0U,
364 };
365 
366 __maybe_unused static const struct regulator_axp192_desc axp2101_bldo2_desc = {
367 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
368 	.enable_mask = 0x20U,
369 	.enable_val = 0x20U,
370 	.vsel_reg = AXP2101_REG_BLDO2_VOLTAGE,
371 	.vsel_mask = 0x1FU,
372 	.vsel_bitpos = 0U,
373 	.max_ua = 300000U,
374 	.ranges = axp2101_abldox_ranges,
375 	.num_ranges = ARRAY_SIZE(axp2101_abldox_ranges),
376 	.workmode_reg = 0U,
377 	.workmode_mask = 0U,
378 };
379 
380 static const struct linear_range axp2101_cpusldo_ranges[] = {
381 	LINEAR_RANGE_INIT(500000U, 50000U, 0U, 19U),
382 };
383 
384 __maybe_unused static const struct regulator_axp192_desc axp2101_cpusldo_desc = {
385 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
386 	.enable_mask = 0x40U,
387 	.enable_val = 0x40U,
388 	.vsel_reg = AXP2101_REG_CPUSLDO_VOLTAGE,
389 	.vsel_mask = 0x1FU,
390 	.vsel_bitpos = 0U,
391 	.max_ua = 30000U,
392 	.ranges = axp2101_cpusldo_ranges,
393 	.num_ranges = ARRAY_SIZE(axp2101_cpusldo_ranges),
394 	.workmode_reg = 0U,
395 	.workmode_mask = 0U,
396 };
397 
398 static const struct linear_range axp2101_dldo1_ranges[] = {
399 	LINEAR_RANGE_INIT(500000U, 100000U, 0U, 28U),
400 };
401 
402 __maybe_unused static const struct regulator_axp192_desc axp2101_dldo1_desc = {
403 	.enable_reg = AXP2101_REG_LDOGRP1_CONTROL,
404 	.enable_mask = 0x80U,
405 	.enable_val = 0x80U,
406 	.vsel_reg = AXP2101_REG_DLDO1_VOLTAGE,
407 	.vsel_mask = 0x1FU,
408 	.vsel_bitpos = 0U,
409 	.max_ua = 300000U,
410 	.ranges = axp2101_dldo1_ranges,
411 	.num_ranges = ARRAY_SIZE(axp2101_dldo1_ranges),
412 	.workmode_reg = 0U,
413 	.workmode_mask = 0U,
414 };
415 
416 static const struct linear_range axp2101_dldo2_ranges[] = {
417 	LINEAR_RANGE_INIT(500000U, 50000U, 0U, 19U),
418 };
419 
420 __maybe_unused static const struct regulator_axp192_desc axp2101_dldo2_desc = {
421 	.enable_reg = AXP2101_REG_LDOGRP2_CONTROL,
422 	.enable_mask = 0x01U,
423 	.enable_val = 0x01U,
424 	.vsel_reg = AXP2101_REG_DLDO2_VOLTAGE,
425 	.vsel_mask = 0x1FU,
426 	.vsel_bitpos = 0U,
427 	.max_ua = 300000U,
428 	.ranges = axp2101_dldo2_ranges,
429 	.num_ranges = ARRAY_SIZE(axp2101_dldo2_ranges),
430 	.workmode_reg = 0U,
431 	.workmode_mask = 0U,
432 };
433 
axp192_enable(const struct device * dev)434 static int axp192_enable(const struct device *dev)
435 {
436 	const struct regulator_axp192_config *config = dev->config;
437 	int ret;
438 
439 	LOG_DBG("Enabling regulator");
440 	LOG_DBG("[0x%02x]=0x%02x mask=0x%02x", config->desc->enable_reg,
441 		     config->desc->enable_val, config->desc->enable_mask);
442 
443 #if AXP192_ANY_HAS_CHILD(ldoio0)
444 	/* special case for LDOIO0, which is multiplexed with GPIO0 */
445 	if (config->desc->enable_reg == AXP192_REG_GPIO0_CONTROL) {
446 		ret = mfd_axp192_gpio_func_ctrl(config->mfd, dev, 0, AXP192_GPIO_FUNC_LDO);
447 	} else {
448 #endif
449 		ret = i2c_reg_update_byte_dt(&config->i2c, config->desc->enable_reg,
450 					     config->desc->enable_mask, config->desc->enable_val);
451 #if AXP192_ANY_HAS_CHILD(ldoio0)
452 	}
453 #endif
454 
455 	if (ret != 0) {
456 		LOG_ERR("Failed to enable regulator");
457 	}
458 
459 	return ret;
460 }
461 
axp192_disable(const struct device * dev)462 static int axp192_disable(const struct device *dev)
463 {
464 	const struct regulator_axp192_config *config = dev->config;
465 	int ret;
466 
467 	LOG_DBG("Disabling regulator");
468 	LOG_DBG("[0x%02x]=0 mask=0x%x", config->desc->enable_reg,
469 		     config->desc->enable_mask);
470 
471 #if AXP192_ANY_HAS_CHILD(ldoio0)
472 	/* special case for LDOIO0, which is multiplexed with GPIO0 */
473 	if (config->desc->enable_reg == AXP192_REG_GPIO0_CONTROL) {
474 		ret = mfd_axp192_gpio_func_ctrl(config->mfd, dev, 0, AXP192_GPIO_FUNC_OUTPUT_LOW);
475 	} else {
476 #endif
477 		ret = i2c_reg_update_byte_dt(&config->i2c, config->desc->enable_reg,
478 					     config->desc->enable_mask, 0u);
479 #if AXP192_ANY_HAS_CHILD(ldoio0)
480 	}
481 #endif
482 
483 	if (ret != 0) {
484 		LOG_ERR("Failed to disable regulator");
485 	}
486 
487 	return ret;
488 }
489 
axp192_count_voltages(const struct device * dev)490 static unsigned int axp192_count_voltages(const struct device *dev)
491 {
492 	const struct regulator_axp192_config *config = dev->config;
493 
494 	return linear_range_group_values_count(config->desc->ranges, config->desc->num_ranges);
495 }
496 
axp192_list_voltage(const struct device * dev,unsigned int idx,int32_t * volt_uv)497 static int axp192_list_voltage(const struct device *dev, unsigned int idx, int32_t *volt_uv)
498 {
499 	const struct regulator_axp192_config *config = dev->config;
500 
501 	return linear_range_group_get_value(config->desc->ranges, config->desc->num_ranges, idx,
502 					    volt_uv);
503 }
504 
axp192_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)505 static int axp192_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv)
506 {
507 	const struct regulator_axp192_config *config = dev->config;
508 	uint16_t idx;
509 	int ret;
510 
511 	LOG_DBG("voltage = [min=%d, max=%d]", min_uv, max_uv);
512 
513 	/* set voltage */
514 	ret = linear_range_group_get_win_index(config->desc->ranges, config->desc->num_ranges,
515 					       min_uv, max_uv, &idx);
516 	if (ret != 0) {
517 		LOG_ERR("No voltage range window could be detected");
518 		return ret;
519 	}
520 
521 	idx <<= config->desc->vsel_bitpos;
522 
523 	LOG_DBG("[0x%x]=0x%x mask=0x%x", config->desc->vsel_reg, idx,
524 		     config->desc->vsel_mask);
525 	ret = i2c_reg_update_byte_dt(&config->i2c, config->desc->vsel_reg, config->desc->vsel_mask,
526 				     (uint8_t)idx);
527 	if (ret != 0) {
528 		LOG_ERR("Failed to set regulator voltage");
529 	}
530 
531 	return ret;
532 }
533 
axp192_get_voltage(const struct device * dev,int32_t * volt_uv)534 static int axp192_get_voltage(const struct device *dev, int32_t *volt_uv)
535 {
536 	const struct regulator_axp192_config *config = dev->config;
537 	int ret;
538 	uint8_t raw_reg;
539 
540 	/* read voltage */
541 	ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->vsel_reg, &raw_reg);
542 	if (ret != 0) {
543 		return ret;
544 	}
545 
546 	raw_reg = (raw_reg & config->desc->vsel_mask) >> config->desc->vsel_bitpos;
547 
548 	ret = linear_range_group_get_value(config->desc->ranges, config->desc->num_ranges, raw_reg,
549 					   volt_uv);
550 
551 	return ret;
552 }
553 
axp192_set_mode(const struct device * dev,regulator_mode_t mode)554 static int axp192_set_mode(const struct device *dev, regulator_mode_t mode)
555 {
556 	const struct regulator_axp192_config *config = dev->config;
557 	int ret;
558 
559 	/* setting workmode is only possible for DCDC1-3 */
560 	if ((mode == AXP192_DCDC_MODE_PWM) && (config->desc->workmode_reg != 0)) {
561 
562 		/* configure PWM mode */
563 		LOG_DBG("PWM mode enabled");
564 		ret = i2c_reg_update_byte_dt(&config->i2c, config->desc->workmode_reg,
565 					     config->desc->workmode_mask,
566 					     config->desc->workmode_pwm_val);
567 		if (ret != 0) {
568 			return ret;
569 		}
570 	} else if (mode == AXP192_DCDC_MODE_AUTO) {
571 
572 		/* configure AUTO mode (default) */
573 		if (config->desc->workmode_reg != 0) {
574 			ret = i2c_reg_update_byte_dt(&config->i2c, config->desc->workmode_reg,
575 						     config->desc->workmode_mask, 0u);
576 			if (ret != 0) {
577 				return ret;
578 			}
579 		} else {
580 
581 			/* AUTO is default mode for LDOs that cannot be configured */
582 			return 0;
583 		}
584 	} else {
585 		LOG_ERR("Setting DCDC workmode failed");
586 		return -ENOTSUP;
587 	}
588 
589 	return 0;
590 }
591 
axp192_get_current_limit(const struct device * dev,int32_t * curr_ua)592 static int axp192_get_current_limit(const struct device *dev, int32_t *curr_ua)
593 {
594 	const struct regulator_axp192_config *config = dev->config;
595 
596 	*curr_ua = config->desc->max_ua;
597 
598 	return 0;
599 }
600 
601 static DEVICE_API(regulator, api) = {
602 	.enable = axp192_enable,
603 	.disable = axp192_disable,
604 	.count_voltages = axp192_count_voltages,
605 	.list_voltage = axp192_list_voltage,
606 	.set_voltage = axp192_set_voltage,
607 	.get_voltage = axp192_get_voltage,
608 	.set_mode = axp192_set_mode,
609 	.get_current_limit = axp192_get_current_limit,
610 };
611 
regulator_axp192_init(const struct device * dev)612 static int regulator_axp192_init(const struct device *dev)
613 {
614 	const struct regulator_axp192_config *config = dev->config;
615 	uint8_t enabled_val;
616 	bool is_enabled;
617 	int ret = 0;
618 
619 	regulator_common_data_init(dev);
620 
621 	if (!device_is_ready(config->mfd)) {
622 		LOG_ERR("Parent instance not ready!");
623 		return -ENODEV;
624 	}
625 
626 	/* read regulator state */
627 	ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->enable_reg, &enabled_val);
628 	if (ret != 0) {
629 		LOG_ERR("Reading enable status failed!");
630 		return ret;
631 	}
632 	is_enabled = ((enabled_val & config->desc->enable_mask) == config->desc->enable_val);
633 	LOG_DBG("is_enabled: %d", is_enabled);
634 
635 	return regulator_common_init(dev, is_enabled);
636 }
637 
638 #define REGULATOR_AXP192_DEFINE(node_id, id, name)                                                 \
639 	static struct regulator_axp192_data data_##id;                                             \
640 	static const struct regulator_axp192_config config_##id = {                                \
641 		.common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id),                                \
642 		.desc = &id##_desc,                                                                \
643 		.mfd = DEVICE_DT_GET(DT_GPARENT(node_id)),                                         \
644 		.i2c = I2C_DT_SPEC_GET(DT_GPARENT(node_id))};                                      \
645 	DEVICE_DT_DEFINE(node_id, regulator_axp192_init, NULL, &data_##id, &config_##id,           \
646 			 POST_KERNEL, CONFIG_REGULATOR_AXP192_AXP2101_INIT_PRIORITY, &api);
647 
648 #define REGULATOR_AXP192_DEFINE_COND(node, child)                                                  \
649 	COND_CODE_1(DT_NODE_EXISTS(DT_CHILD(node, child)),                                         \
650 		    (REGULATOR_AXP192_DEFINE(DT_CHILD(node, child), axp192_##child, child)), ())
651 
652 #define REGULATOR_AXP2101_DEFINE_COND(node, child)                                                 \
653 	COND_CODE_1(DT_NODE_EXISTS(DT_CHILD(node, child)),                                         \
654 		    (REGULATOR_AXP192_DEFINE(DT_CHILD(node, child), axp2101_##child, child)), ())
655 
656 #define REGULATOR_AXP192_DEFINE_ALL(node)                                                          \
657 	REGULATOR_AXP192_DEFINE_COND(node, dcdc1)                                                  \
658 	REGULATOR_AXP192_DEFINE_COND(node, dcdc2)                                                  \
659 	REGULATOR_AXP192_DEFINE_COND(node, dcdc3)                                                  \
660 	REGULATOR_AXP192_DEFINE_COND(node, ldoio0)                                                 \
661 	REGULATOR_AXP192_DEFINE_COND(node, ldo2)                                                   \
662 	REGULATOR_AXP192_DEFINE_COND(node, ldo3)
663 
664 #define REGULATOR_AXP2101_DEFINE_ALL(node)                                                         \
665 	REGULATOR_AXP2101_DEFINE_COND(node, dcdc1)                                                 \
666 	REGULATOR_AXP2101_DEFINE_COND(node, dcdc2)                                                 \
667 	REGULATOR_AXP2101_DEFINE_COND(node, dcdc3)                                                 \
668 	REGULATOR_AXP2101_DEFINE_COND(node, dcdc4)                                                 \
669 	REGULATOR_AXP2101_DEFINE_COND(node, dcdc5)                                                 \
670 	REGULATOR_AXP2101_DEFINE_COND(node, aldo1)                                                 \
671 	REGULATOR_AXP2101_DEFINE_COND(node, aldo2)                                                 \
672 	REGULATOR_AXP2101_DEFINE_COND(node, aldo3)                                                 \
673 	REGULATOR_AXP2101_DEFINE_COND(node, aldo4)                                                 \
674 	REGULATOR_AXP2101_DEFINE_COND(node, bldo1)                                                 \
675 	REGULATOR_AXP2101_DEFINE_COND(node, bldo2)                                                 \
676 	REGULATOR_AXP2101_DEFINE_COND(node, cpusldo)                                               \
677 	REGULATOR_AXP2101_DEFINE_COND(node, dldo1)                                                 \
678 	REGULATOR_AXP2101_DEFINE_COND(node, dldo2)
679 
680 DT_FOREACH_STATUS_OKAY(x_powers_axp192_regulator, REGULATOR_AXP192_DEFINE_ALL)
681 DT_FOREACH_STATUS_OKAY(x_powers_axp2101_regulator, REGULATOR_AXP2101_DEFINE_ALL)
682