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