1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #define DT_DRV_COMPAT nordic_npm6001_regulator
7 
8 #include <errno.h>
9 
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/regulator.h>
12 #include <zephyr/dt-bindings/regulator/npm6001.h>
13 #include <zephyr/sys/__assert.h>
14 #include <zephyr/sys/linear_range.h>
15 #include <zephyr/sys/util.h>
16 
17 /* nPM6001 voltage sources */
18 enum npm6001_sources {
19 	NPM6001_SOURCE_BUCK0,
20 	NPM6001_SOURCE_BUCK1,
21 	NPM6001_SOURCE_BUCK2,
22 	NPM6001_SOURCE_BUCK3,
23 	NPM6001_SOURCE_LDO0,
24 	NPM6001_SOURCE_LDO1,
25 };
26 
27 /* nPM6001 regulator related registers */
28 #define NPM6001_TASKS_START_BUCK3    0x02U
29 #define NPM6001_TASKS_START_LDO0     0x03U
30 #define NPM6001_TASKS_START_LDO1     0x04U
31 #define NPM6001_TASKS_STOP_BUCK3     0x08U
32 #define NPM6001_TASKS_STOP_LDO0      0x09U
33 #define NPM6001_TASKS_STOP_LDO1      0x0AU
34 #define NPM6001_TASKS_UPDATE_VOUTPWM 0x0EU
35 #define NPM6001_EVENTS_THWARN        0x1EU
36 #define NPM6001_EVENTS_BUCK0OC       0x1FU
37 #define NPM6001_EVENTS_BUCK1OC       0x20U
38 #define NPM6001_EVENTS_BUCK2OC       0x21U
39 #define NPM6001_EVENTS_BUCK3OC       0x22U
40 #define NPM6001_BUCK0VOUTULP         0x3AU
41 #define NPM6001_BUCK1VOUTULP         0x3CU
42 #define NPM6001_BUCK2VOUTULP         0x40U
43 #define NPM6001_BUCK3VOUT            0x45U
44 #define NPM6001_LDO0VOUT             0x46U
45 #define NPM6001_BUCK0CONFPWMMODE     0x4AU
46 #define NPM6001_BUCK1CONFPWMMODE     0x4BU
47 #define NPM6001_BUCK2CONFPWMMODE     0x4CU
48 #define NPM6001_BUCK3CONFPWMMODE     0x4DU
49 #define NPM6001_BUCKMODEPADCONF      0x4EU
50 #define NPM6001_PADDRIVESTRENGTH     0x53U
51 #define NPM6001_OVERRIDEPWRUPBUCK    0xABU
52 
53 /* nPM6001 LDO0VOUT values */
54 #define NPM6001_LDO0VOUT_SET1V8  0x06U
55 #define NPM6001_LDO0VOUT_SET2V1  0x0BU
56 #define NPM6001_LDO0VOUT_SET2V41 0x10U
57 #define NPM6001_LDO0VOUT_SET2V7  0x15U
58 #define NPM6001_LDO0VOUT_SET3V0  0x1AU
59 #define NPM6001_LDO0VOUT_SET3V3  0x1EU
60 
61 /* nPM6001 BUCKXCONFPWMMODE fields */
62 #define NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_MSK 0x8U
63 #define NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_POS 3
64 #define NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM     BIT(NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_POS)
65 
66 /* nPM6001 OVERRIDEPWRUPBUCK fields */
67 #define NPM6001_OVERRIDEPWRUPBUCK_BUCK1DISABLE_MSK 0x22U
68 #define NPM6001_OVERRIDEPWRUPBUCK_BUCK2DISABLE_MSK 0x44U
69 #define NPM6001_OVERRIDEPWRUPBUCK_BUCK1DISABLE     BIT(1)
70 #define NPM6001_OVERRIDEPWRUPBUCK_BUCK2DISABLE     BIT(2)
71 
72 struct regulator_npm6001_config {
73 	struct regulator_common_config common;
74 	struct i2c_dt_spec i2c;
75 	uint8_t source;
76 };
77 
78 struct regulator_npm6001_data {
79 	struct regulator_common_data data;
80 };
81 
82 struct regulator_npm6001_vmap {
83 	uint8_t reg_val;
84 	int32_t volt_uv;
85 };
86 
87 static const struct linear_range buck0_range = LINEAR_RANGE_INIT(1800000, 100000U, 0x0U, 0xFU);
88 
89 static const struct linear_range buck1_range = LINEAR_RANGE_INIT(700000, 50000U, 0x0U, 0xEU);
90 
91 static const struct linear_range buck2_range = LINEAR_RANGE_INIT(1200000, 50000U, 0xAU, 0xEU);
92 
93 static const struct linear_range buck3_range = LINEAR_RANGE_INIT(500000, 25000U, 0x0U, 0x70U);
94 
95 static const struct regulator_npm6001_vmap ldo0_voltages[] = {
96 	{NPM6001_LDO0VOUT_SET1V8, 1800000},  {NPM6001_LDO0VOUT_SET2V1, 2100000},
97 	{NPM6001_LDO0VOUT_SET2V41, 2410000}, {NPM6001_LDO0VOUT_SET2V7, 2700000},
98 	{NPM6001_LDO0VOUT_SET3V0, 3000000},  {NPM6001_LDO0VOUT_SET3V3, 3300000},
99 };
100 
regulator_npm6001_ldo0_list_voltage(const struct device * dev,unsigned int idx,int32_t * volt_uv)101 static int regulator_npm6001_ldo0_list_voltage(const struct device *dev, unsigned int idx,
102 					       int32_t *volt_uv)
103 {
104 	if (idx >= ARRAY_SIZE(ldo0_voltages)) {
105 		return -EINVAL;
106 	}
107 
108 	*volt_uv = ldo0_voltages[idx].volt_uv;
109 
110 	return 0;
111 }
112 
regulator_npm6001_buck012_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv,const struct linear_range * range,uint8_t vout_reg,uint8_t conf_reg)113 static int regulator_npm6001_buck012_set_voltage(const struct device *dev, int32_t min_uv,
114 						 int32_t max_uv, const struct linear_range *range,
115 						 uint8_t vout_reg, uint8_t conf_reg)
116 {
117 	const struct regulator_npm6001_config *config = dev->config;
118 	uint8_t conf, buf[3];
119 	uint16_t idx;
120 	int ret;
121 
122 	ret = linear_range_get_win_index(range, min_uv, max_uv, &idx);
123 	if (ret == -EINVAL) {
124 		return ret;
125 	}
126 
127 	/* force PWM mode when updating voltage */
128 	ret = i2c_reg_read_byte_dt(&config->i2c, conf_reg, &conf);
129 	if (ret < 0) {
130 		return ret;
131 	}
132 
133 	if ((conf & NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM) == 0U) {
134 		ret = i2c_reg_write_byte_dt(&config->i2c, conf_reg,
135 					    conf | NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM);
136 		if (ret < 0) {
137 			return ret;
138 		}
139 	}
140 
141 	/* write voltage in both ULP/PWM registers */
142 	buf[0] = vout_reg;
143 	buf[1] = (uint8_t)idx;
144 	buf[2] = (uint8_t)idx;
145 
146 	ret = i2c_write_dt(&config->i2c, buf, sizeof(buf));
147 	if (ret < 0) {
148 		return ret;
149 	}
150 
151 	ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_UPDATE_VOUTPWM, 1U);
152 	if (ret < 0) {
153 		return ret;
154 	}
155 
156 	/* restore HYS mode if enabled before */
157 	if ((conf & NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM) == 0U) {
158 		ret = i2c_reg_write_byte_dt(&config->i2c, conf_reg, conf);
159 		if (ret < 0) {
160 			return ret;
161 		}
162 	}
163 
164 	return 0;
165 }
166 
regulator_npm6001_buck3_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)167 static int regulator_npm6001_buck3_set_voltage(const struct device *dev, int32_t min_uv,
168 					       int32_t max_uv)
169 {
170 	const struct regulator_npm6001_config *config = dev->config;
171 	uint16_t idx;
172 	uint8_t conf;
173 	int ret;
174 
175 	ret = linear_range_get_win_index(&buck3_range, min_uv, max_uv, &idx);
176 	if (ret == -EINVAL) {
177 		return ret;
178 	}
179 
180 	/* force PWM mode when updating voltage */
181 	ret = i2c_reg_read_byte_dt(&config->i2c, NPM6001_BUCK3CONFPWMMODE, &conf);
182 	if (ret < 0) {
183 		return ret;
184 	}
185 
186 	if ((conf & NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM) == 0U) {
187 		ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCK3CONFPWMMODE,
188 					    conf | NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM);
189 		if (ret < 0) {
190 			return ret;
191 		}
192 	}
193 
194 	ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCK3VOUT, (uint8_t)idx);
195 	if (ret < 0) {
196 		return ret;
197 	}
198 
199 	/* restore HYS mode if enabled before */
200 	if ((conf & NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM) == 0U) {
201 		ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_BUCK3CONFPWMMODE, conf);
202 		if (ret < 0) {
203 			return ret;
204 		}
205 	}
206 
207 	return 0;
208 }
209 
regulator_npm6001_ldo0_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)210 static int regulator_npm6001_ldo0_set_voltage(const struct device *dev, int32_t min_uv,
211 					      int32_t max_uv)
212 {
213 	const struct regulator_npm6001_config *config = dev->config;
214 	uint8_t val;
215 	size_t i;
216 
217 	for (i = 0U; i < ARRAY_SIZE(ldo0_voltages); i++) {
218 		if ((min_uv <= ldo0_voltages[i].volt_uv) && (max_uv >= ldo0_voltages[i].volt_uv)) {
219 			val = ldo0_voltages[i].reg_val;
220 			break;
221 		}
222 	}
223 
224 	if (i == ARRAY_SIZE(ldo0_voltages)) {
225 		return -EINVAL;
226 	}
227 
228 	return i2c_reg_write_byte_dt(&config->i2c, NPM6001_LDO0VOUT, val);
229 }
230 
regulator_npm6001_buck0123_get_voltage(const struct device * dev,const struct linear_range * range,uint8_t vout_reg,int32_t * volt_uv)231 static int regulator_npm6001_buck0123_get_voltage(const struct device *dev,
232 						  const struct linear_range *range,
233 						  uint8_t vout_reg, int32_t *volt_uv)
234 {
235 	const struct regulator_npm6001_config *config = dev->config;
236 	uint8_t idx;
237 	int ret;
238 
239 	ret = i2c_reg_read_byte_dt(&config->i2c, vout_reg, &idx);
240 	if (ret < 0) {
241 		return ret;
242 	}
243 
244 	return linear_range_get_value(range, idx, volt_uv);
245 }
246 
regulator_npm6001_ldo0_get_voltage(const struct device * dev,int32_t * volt_uv)247 static int regulator_npm6001_ldo0_get_voltage(const struct device *dev, int32_t *volt_uv)
248 {
249 	const struct regulator_npm6001_config *config = dev->config;
250 	uint8_t val;
251 	int ret;
252 
253 	ret = i2c_reg_read_byte_dt(&config->i2c, NPM6001_LDO0VOUT, &val);
254 	if (ret < 0) {
255 		return ret;
256 	}
257 
258 	for (size_t i = 0U; i < ARRAY_SIZE(ldo0_voltages); i++) {
259 		if (val == ldo0_voltages[i].reg_val) {
260 			*volt_uv = ldo0_voltages[i].volt_uv;
261 			return 0;
262 		}
263 	}
264 
265 	__ASSERT(NULL, "Unexpected voltage");
266 
267 	return -EINVAL;
268 }
269 
regulator_npm6001_count_voltages(const struct device * dev)270 static unsigned int regulator_npm6001_count_voltages(const struct device *dev)
271 {
272 	const struct regulator_npm6001_config *config = dev->config;
273 
274 	switch (config->source) {
275 	case NPM6001_SOURCE_BUCK0:
276 		return linear_range_values_count(&buck0_range);
277 	case NPM6001_SOURCE_BUCK1:
278 		return linear_range_values_count(&buck1_range);
279 	case NPM6001_SOURCE_BUCK2:
280 		return linear_range_values_count(&buck2_range);
281 	case NPM6001_SOURCE_BUCK3:
282 		return linear_range_values_count(&buck3_range);
283 	case NPM6001_SOURCE_LDO0:
284 		return 6U;
285 	case NPM6001_SOURCE_LDO1:
286 		return 1U;
287 	default:
288 		__ASSERT(NULL, "Unexpected source");
289 	}
290 
291 	return 0;
292 }
293 
regulator_npm6001_list_voltage(const struct device * dev,unsigned int idx,int32_t * volt_uv)294 static int regulator_npm6001_list_voltage(const struct device *dev, unsigned int idx,
295 					  int32_t *volt_uv)
296 {
297 	const struct regulator_npm6001_config *config = dev->config;
298 
299 	switch (config->source) {
300 	case NPM6001_SOURCE_BUCK0:
301 		return linear_range_get_value(&buck0_range, idx, volt_uv);
302 	case NPM6001_SOURCE_BUCK1:
303 		return linear_range_get_value(&buck1_range, idx, volt_uv);
304 	case NPM6001_SOURCE_BUCK2:
305 		return linear_range_get_value(&buck2_range, idx + buck2_range.min_idx, volt_uv);
306 	case NPM6001_SOURCE_BUCK3:
307 		return linear_range_get_value(&buck3_range, idx, volt_uv);
308 	case NPM6001_SOURCE_LDO0:
309 		return regulator_npm6001_ldo0_list_voltage(dev, idx, volt_uv);
310 	case NPM6001_SOURCE_LDO1:
311 		*volt_uv = 1800000;
312 		break;
313 	default:
314 		__ASSERT(NULL, "Unexpected source");
315 	}
316 
317 	return 0;
318 }
319 
regulator_npm6001_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)320 static int regulator_npm6001_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv)
321 {
322 	const struct regulator_npm6001_config *config = dev->config;
323 
324 	switch (config->source) {
325 	case NPM6001_SOURCE_BUCK0:
326 		return regulator_npm6001_buck012_set_voltage(dev, min_uv, max_uv, &buck0_range,
327 							     NPM6001_BUCK0VOUTULP,
328 							     NPM6001_BUCK0CONFPWMMODE);
329 	case NPM6001_SOURCE_BUCK1:
330 		return regulator_npm6001_buck012_set_voltage(dev, min_uv, max_uv, &buck1_range,
331 							     NPM6001_BUCK1VOUTULP,
332 							     NPM6001_BUCK1CONFPWMMODE);
333 	case NPM6001_SOURCE_BUCK2:
334 		return regulator_npm6001_buck012_set_voltage(dev, min_uv, max_uv, &buck2_range,
335 							     NPM6001_BUCK2VOUTULP,
336 							     NPM6001_BUCK2CONFPWMMODE);
337 	case NPM6001_SOURCE_BUCK3:
338 		return regulator_npm6001_buck3_set_voltage(dev, min_uv, max_uv);
339 	case NPM6001_SOURCE_LDO0:
340 		return regulator_npm6001_ldo0_set_voltage(dev, min_uv, max_uv);
341 	case NPM6001_SOURCE_LDO1:
342 		if ((min_uv != 1800000) && (max_uv != 1800000)) {
343 			return -EINVAL;
344 		}
345 		break;
346 	default:
347 		__ASSERT(NULL, "Unexpected source");
348 	}
349 
350 	return 0;
351 }
352 
regulator_npm6001_get_voltage(const struct device * dev,int32_t * volt_uv)353 static int regulator_npm6001_get_voltage(const struct device *dev, int32_t *volt_uv)
354 {
355 	const struct regulator_npm6001_config *config = dev->config;
356 
357 	switch (config->source) {
358 	case NPM6001_SOURCE_BUCK0:
359 		return regulator_npm6001_buck0123_get_voltage(dev, &buck0_range,
360 							      NPM6001_BUCK0VOUTULP, volt_uv);
361 	case NPM6001_SOURCE_BUCK1:
362 		return regulator_npm6001_buck0123_get_voltage(dev, &buck1_range,
363 							      NPM6001_BUCK1VOUTULP, volt_uv);
364 	case NPM6001_SOURCE_BUCK2:
365 		return regulator_npm6001_buck0123_get_voltage(dev, &buck2_range,
366 							      NPM6001_BUCK2VOUTULP, volt_uv);
367 	case NPM6001_SOURCE_BUCK3:
368 		return regulator_npm6001_buck0123_get_voltage(dev, &buck3_range, NPM6001_BUCK3VOUT,
369 							      volt_uv);
370 	case NPM6001_SOURCE_LDO0:
371 		return regulator_npm6001_ldo0_get_voltage(dev, volt_uv);
372 	case NPM6001_SOURCE_LDO1:
373 		*volt_uv = 1800000U;
374 		break;
375 	default:
376 		__ASSERT(NULL, "Unexpected source");
377 	}
378 
379 	return 0;
380 }
381 
regulator_npm6001_set_mode(const struct device * dev,regulator_mode_t mode)382 static int regulator_npm6001_set_mode(const struct device *dev, regulator_mode_t mode)
383 {
384 	const struct regulator_npm6001_config *config = dev->config;
385 	uint8_t conf_reg;
386 
387 	if (mode > NPM6001_MODE_PWM) {
388 		return -ENOTSUP;
389 	}
390 
391 	switch (config->source) {
392 	case NPM6001_SOURCE_BUCK0:
393 		conf_reg = NPM6001_BUCK0CONFPWMMODE;
394 		break;
395 	case NPM6001_SOURCE_BUCK1:
396 		conf_reg = NPM6001_BUCK1CONFPWMMODE;
397 		break;
398 	case NPM6001_SOURCE_BUCK2:
399 		conf_reg = NPM6001_BUCK2CONFPWMMODE;
400 		break;
401 	case NPM6001_SOURCE_BUCK3:
402 		conf_reg = NPM6001_BUCK3CONFPWMMODE;
403 		break;
404 	default:
405 		return -ENOTSUP;
406 	}
407 
408 	return i2c_reg_update_byte_dt(&config->i2c, conf_reg,
409 				      NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_MSK,
410 				      mode << NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_POS);
411 }
412 
regulator_npm6001_get_mode(const struct device * dev,regulator_mode_t * mode)413 static int regulator_npm6001_get_mode(const struct device *dev, regulator_mode_t *mode)
414 {
415 	const struct regulator_npm6001_config *config = dev->config;
416 	uint8_t conf_reg, conf;
417 	int ret;
418 
419 	switch (config->source) {
420 	case NPM6001_SOURCE_BUCK0:
421 		conf_reg = NPM6001_BUCK0CONFPWMMODE;
422 		break;
423 	case NPM6001_SOURCE_BUCK1:
424 		conf_reg = NPM6001_BUCK1CONFPWMMODE;
425 		break;
426 	case NPM6001_SOURCE_BUCK2:
427 		conf_reg = NPM6001_BUCK2CONFPWMMODE;
428 		break;
429 	case NPM6001_SOURCE_BUCK3:
430 		conf_reg = NPM6001_BUCK3CONFPWMMODE;
431 		break;
432 	default:
433 		return -ENOTSUP;
434 	}
435 
436 	ret = i2c_reg_read_byte_dt(&config->i2c, conf_reg, &conf);
437 	if (ret < 0) {
438 		return ret;
439 	}
440 
441 	*mode = (conf & NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_MSK) >>
442 		NPM6001_BUCKXCONFPWMMODE_SETFORCEPWM_POS;
443 
444 	return 0;
445 }
446 
regulator_npm6001_enable(const struct device * dev)447 static int regulator_npm6001_enable(const struct device *dev)
448 {
449 	const struct regulator_npm6001_config *config = dev->config;
450 
451 	switch (config->source) {
452 	case NPM6001_SOURCE_BUCK1:
453 		return i2c_reg_update_byte_dt(&config->i2c, NPM6001_OVERRIDEPWRUPBUCK,
454 					      NPM6001_OVERRIDEPWRUPBUCK_BUCK1DISABLE_MSK, 0U);
455 	case NPM6001_SOURCE_BUCK2:
456 		return i2c_reg_update_byte_dt(&config->i2c, NPM6001_OVERRIDEPWRUPBUCK,
457 					      NPM6001_OVERRIDEPWRUPBUCK_BUCK2DISABLE_MSK, 0U);
458 	case NPM6001_SOURCE_BUCK3:
459 		return i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_START_BUCK3, 1U);
460 	case NPM6001_SOURCE_LDO0:
461 		return i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_START_LDO0, 1U);
462 	case NPM6001_SOURCE_LDO1:
463 		return i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_START_LDO1, 1U);
464 	default:
465 		return 0;
466 	}
467 }
468 
regulator_npm6001_disable(const struct device * dev)469 static int regulator_npm6001_disable(const struct device *dev)
470 {
471 	const struct regulator_npm6001_config *config = dev->config;
472 
473 	switch (config->source) {
474 	case NPM6001_SOURCE_BUCK1:
475 		return i2c_reg_update_byte_dt(&config->i2c, NPM6001_OVERRIDEPWRUPBUCK,
476 					      NPM6001_OVERRIDEPWRUPBUCK_BUCK1DISABLE_MSK,
477 					      NPM6001_OVERRIDEPWRUPBUCK_BUCK1DISABLE);
478 	case NPM6001_SOURCE_BUCK2:
479 		return i2c_reg_update_byte_dt(&config->i2c, NPM6001_OVERRIDEPWRUPBUCK,
480 					      NPM6001_OVERRIDEPWRUPBUCK_BUCK2DISABLE_MSK,
481 					      NPM6001_OVERRIDEPWRUPBUCK_BUCK2DISABLE);
482 	case NPM6001_SOURCE_BUCK3:
483 		return i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_STOP_BUCK3, 1U);
484 	case NPM6001_SOURCE_LDO0:
485 		return i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_STOP_LDO0, 1U);
486 	case NPM6001_SOURCE_LDO1:
487 		return i2c_reg_write_byte_dt(&config->i2c, NPM6001_TASKS_STOP_LDO1, 1U);
488 	default:
489 		return 0;
490 	}
491 }
492 
regulator_npm6001_get_error_flags(const struct device * dev,regulator_error_flags_t * flags)493 static int regulator_npm6001_get_error_flags(const struct device *dev,
494 					     regulator_error_flags_t *flags)
495 {
496 	const struct regulator_npm6001_config *config = dev->config;
497 	uint8_t oc_reg, val;
498 	int ret;
499 
500 	*flags = 0U;
501 
502 	/* read thermal warning */
503 	ret = i2c_reg_read_byte_dt(&config->i2c, NPM6001_EVENTS_THWARN, &val);
504 	if (ret < 0) {
505 		return ret;
506 	}
507 
508 	if (val != 0U) {
509 		/* clear thermal warning */
510 		ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_EVENTS_THWARN, 0U);
511 		if (ret < 0) {
512 			return ret;
513 		}
514 
515 		*flags |= REGULATOR_ERROR_OVER_TEMP;
516 	}
517 
518 	/* read overcurrent event */
519 	switch (config->source) {
520 	case NPM6001_SOURCE_BUCK0:
521 		oc_reg = NPM6001_EVENTS_BUCK0OC;
522 		break;
523 	case NPM6001_SOURCE_BUCK1:
524 		oc_reg = NPM6001_EVENTS_BUCK1OC;
525 		break;
526 	case NPM6001_SOURCE_BUCK2:
527 		oc_reg = NPM6001_EVENTS_BUCK2OC;
528 		break;
529 	case NPM6001_SOURCE_BUCK3:
530 		oc_reg = NPM6001_EVENTS_BUCK3OC;
531 		break;
532 	default:
533 		return 0;
534 	}
535 
536 	ret = i2c_reg_read_byte_dt(&config->i2c, oc_reg, &val);
537 	if (ret < 0) {
538 		return ret;
539 	}
540 
541 	if (val != 0U) {
542 		/* clear overcurrent event */
543 		ret = i2c_reg_write_byte_dt(&config->i2c, oc_reg, 0U);
544 		if (ret < 0) {
545 			return ret;
546 		}
547 
548 		*flags |= REGULATOR_ERROR_OVER_CURRENT;
549 	}
550 
551 	return 0;
552 }
553 
regulator_npm6001_init(const struct device * dev)554 static int regulator_npm6001_init(const struct device *dev)
555 {
556 	const struct regulator_npm6001_config *config = dev->config;
557 	bool is_enabled;
558 
559 	regulator_common_data_init(dev);
560 
561 	if (!i2c_is_ready_dt(&config->i2c)) {
562 		return -ENODEV;
563 	}
564 
565 	/* BUCK1/2 are ON by default */
566 	is_enabled = (config->source == NPM6001_SOURCE_BUCK1) ||
567 		     (config->source == NPM6001_SOURCE_BUCK2);
568 
569 	return regulator_common_init(dev, is_enabled);
570 }
571 
572 static const struct regulator_driver_api api = {
573 	.enable = regulator_npm6001_enable,
574 	.disable = regulator_npm6001_disable,
575 	.count_voltages = regulator_npm6001_count_voltages,
576 	.list_voltage = regulator_npm6001_list_voltage,
577 	.set_voltage = regulator_npm6001_set_voltage,
578 	.get_voltage = regulator_npm6001_get_voltage,
579 	.set_mode = regulator_npm6001_set_mode,
580 	.get_mode = regulator_npm6001_get_mode,
581 	.get_error_flags = regulator_npm6001_get_error_flags,
582 };
583 
584 #define REGULATOR_NPM6001_DEFINE(node_id, id, _source)                                             \
585 	static struct regulator_npm6001_data data_##id;                                            \
586                                                                                                    \
587 	static const struct regulator_npm6001_config config_##id = {                               \
588 		.common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id),                                \
589 		.i2c = I2C_DT_SPEC_GET(DT_GPARENT(node_id)),                                       \
590 		.source = _source,                                                                 \
591 	};                                                                                         \
592                                                                                                    \
593 	DEVICE_DT_DEFINE(node_id, regulator_npm6001_init, NULL, &data_##id, &config_##id,          \
594 			 POST_KERNEL, CONFIG_REGULATOR_NPM6001_INIT_PRIORITY, &api);
595 
596 #define REGULATOR_NPM6001_DEFINE_COND(inst, child, source)                                         \
597 	COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, child)),                                    \
598 		    (REGULATOR_NPM6001_DEFINE(DT_INST_CHILD(inst, child), child##inst, source)),   \
599 		    ())
600 
601 #define REGULATOR_NPM6001_DEFINE_ALL(inst)                                                         \
602 	REGULATOR_NPM6001_DEFINE_COND(inst, buck0, NPM6001_SOURCE_BUCK0)                           \
603 	REGULATOR_NPM6001_DEFINE_COND(inst, buck1, NPM6001_SOURCE_BUCK1)                           \
604 	REGULATOR_NPM6001_DEFINE_COND(inst, buck2, NPM6001_SOURCE_BUCK2)                           \
605 	REGULATOR_NPM6001_DEFINE_COND(inst, buck3, NPM6001_SOURCE_BUCK3)                           \
606 	REGULATOR_NPM6001_DEFINE_COND(inst, ldo0, NPM6001_SOURCE_LDO0)                             \
607 	REGULATOR_NPM6001_DEFINE_COND(inst, ldo1, NPM6001_SOURCE_LDO1)
608 
609 DT_INST_FOREACH_STATUS_OKAY(REGULATOR_NPM6001_DEFINE_ALL)
610