1 /*
2  * Copyright (c) 2023 Martin Kiepfer <mrmarteng@teleschirm.org>
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <errno.h>
7 #include <stdbool.h>
8 
9 #include <zephyr/drivers/mfd/axp192.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/logging/log.h>
13 
14 LOG_MODULE_REGISTER(mfd_axp192, CONFIG_MFD_LOG_LEVEL);
15 
16 struct mfd_axp192_config {
17 	struct i2c_dt_spec i2c;
18 #ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
19 	bool vbusen_disable;
20 #endif
21 	uint8_t reg_chip_id;
22 	uint8_t vbus_config_reg;
23 	uint8_t chip_id;
24 	uint8_t val_vbusen_disable;
25 };
26 
27 #ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
28 
29 /* Chip ID value */
30 #define AXP192_CHIP_ID 0x03U
31 
32 /* Registers definitions */
33 #define AXP192_REG_CHIP_ID 0x03U
34 
35 /* AXP192 GPIO register addresses */
36 #define AXP192_EXTEN_DCDC2_CONTROL_REG 0x10U
37 #define AXP192_VBUS_CFG_REG            0x30U
38 #define AXP192_GPIO0_FUNC_REG          0x90U
39 #define AXP192_GPIO1_FUNC_REG          0x92U
40 #define AXP192_GPIO2_FUNC_REG          0x93U
41 #define AXP192_GPIO34_FUNC_REG         0x95U
42 #define AXP192_GPIO012_PINVAL_REG      0x94U
43 #define AXP192_GPIO34_PINVAL_REG       0x96U
44 #define AXP192_GPIO012_PULLDOWN_REG    0x97U
45 
46 /* VBUS control reg values */
47 #define AXP192_VBUS_CFG_VAL_VBUSEN_DISABLE 0x80U
48 
49 /* GPIO function control parameters */
50 #define AXP192_GPIO012_FUNC_VAL_OUTPUT_OD  0x00U
51 #define AXP192_GPIO012_FUNC_VAL_INPUT      0x01U
52 #define AXP192_GPIO012_FUNC_VAL_LDO        0x02U /* only applicable for GPIO0 */
53 #define AXP192_GPIO012_FUNC_VAL_ADC        0x04U
54 #define AXP192_GPIO012_FUNC_VAL_OUTPUT_LOW 0x05U
55 #define AXP192_GPIO012_FUNC_VAL_FLOAT      0x06U
56 #define AXP192_GPIO012_FUNC_MASK                                                                   \
57 	(AXP192_GPIO012_FUNC_VAL_OUTPUT_OD | AXP192_GPIO012_FUNC_VAL_INPUT |                       \
58 	 AXP192_GPIO012_FUNC_VAL_LDO | AXP192_GPIO012_FUNC_VAL_ADC |                               \
59 	 AXP192_GPIO012_FUNC_VAL_OUTPUT_LOW | AXP192_GPIO012_FUNC_VAL_FLOAT)
60 
61 #define AXP192_GPIO34_FUNC_ENA           0x80U
62 #define AXP192_GPIO3_FUNC_VAL_CHARGE_CTL 0x00U
63 #define AXP192_GPIO3_FUNC_VAL_OUTPUT_OD  0x01U
64 #define AXP192_GPIO3_FUNC_VAL_INPUT      0x02U
65 #define AXP192_GPIO3_FUNC_MASK                                                                     \
66 	(AXP192_GPIO34_FUNC_ENA | AXP192_GPIO3_FUNC_VAL_CHARGE_CTL |                               \
67 	 AXP192_GPIO3_FUNC_VAL_OUTPUT_OD | AXP192_GPIO3_FUNC_VAL_INPUT)
68 
69 #define AXP192_GPIO4_FUNC_VAL_CHARGE_CTL 0x00U
70 #define AXP192_GPIO4_FUNC_VAL_OUTPUT_OD  0x04U
71 #define AXP192_GPIO4_FUNC_VAL_INPUT      0x08U
72 #define AXP192_GPIO4_FUNC_VAL_ADC        0x0CU
73 #define AXP192_GPIO4_FUNC_MASK                                                                     \
74 	(AXP192_GPIO34_FUNC_ENA | AXP192_GPIO4_FUNC_VAL_CHARGE_CTL |                               \
75 	 AXP192_GPIO4_FUNC_VAL_OUTPUT_OD | AXP192_GPIO4_FUNC_VAL_INPUT)
76 
77 #define AXP192_EXTEN_ENA  0x04U
78 #define AXP192_EXTEN_MASK 0x04U
79 
80 /* Pull-Down enable parameters */
81 #define AXP192_GPIO0_PULLDOWN_ENABLE 0x01U
82 #define AXP192_GPIO1_PULLDOWN_ENABLE 0x02U
83 #define AXP192_GPIO2_PULLDOWN_ENABLE 0x04U
84 
85 /* GPIO Value parameters */
86 #define AXP192_GPIO0_INPUT_VAL      0x10U
87 #define AXP192_GPIO1_INPUT_VAL      0x20U
88 #define AXP192_GPIO2_INPUT_VAL      0x40U
89 #define AXP192_GPIO012_INTPUT_SHIFT 4U
90 #define AXP192_GPIO012_INTPUT_MASK                                                                 \
91 	(AXP192_GPIO0_INPUT_VAL | AXP192_GPIO1_INPUT_VAL | AXP192_GPIO2_INPUT_VAL)
92 #define AXP192_GPIO3_INPUT_VAL     0x10U
93 #define AXP192_GPIO4_INPUT_VAL     0x20U
94 #define AXP192_GPIO34_INTPUT_SHIFT 4U
95 #define AXP192_GPIO34_INTPUT_MASK  (AXP192_GPIO3_INPUT_VAL | AXP192_GPIO4_INPUT_VAL)
96 
97 #define AXP192_GPIO0_OUTPUT_VAL 0x01U
98 #define AXP192_GPIO1_OUTPUT_VAL 0x02U
99 #define AXP192_GPIO2_OUTPUT_VAL 0x04U
100 #define AXP192_GPIO012_OUTPUT_MASK                                                                 \
101 	(AXP192_GPIO0_OUTPUT_VAL | AXP192_GPIO1_OUTPUT_VAL | AXP192_GPIO2_OUTPUT_VAL)
102 
103 #define AXP192_GPIO3_OUTPUT_VAL   0x01U
104 #define AXP192_GPIO4_OUTPUT_VAL   0x02U
105 #define AXP192_GPIO34_OUTPUT_MASK (AXP192_GPIO3_OUTPUT_VAL | AXP192_GPIO4_OUTPUT_VAL)
106 
107 #define AXP192_GPIO5_OUTPUT_MASK  0x04U
108 #define AXP192_GPIO5_OUTPUT_VAL   0x04U
109 #define AXP192_GPIO5_OUTPUT_SHIFT 3U
110 
111 struct mfd_axp192_data {
112 	const struct device *gpio_mask_used[AXP192_GPIO_MAX_NUM];
113 	uint8_t gpio_mask_output;
114 };
115 
116 struct mfd_axp192_func_reg_desc {
117 	uint8_t reg;
118 	uint8_t mask;
119 };
120 
121 const struct mfd_axp192_func_reg_desc gpio_reg_desc[AXP192_GPIO_MAX_NUM] = {
122 	{
123 		/* GPIO0 */
124 		.reg = AXP192_GPIO0_FUNC_REG,
125 		.mask = AXP192_GPIO012_FUNC_MASK,
126 	},
127 	{
128 		/* GPIO1 */
129 		.reg = AXP192_GPIO1_FUNC_REG,
130 		.mask = AXP192_GPIO012_FUNC_MASK,
131 	},
132 	{
133 		/* GPIO2 */
134 		.reg = AXP192_GPIO2_FUNC_REG,
135 		.mask = AXP192_GPIO012_FUNC_MASK,
136 	},
137 	{
138 		/* GPIO3 */
139 		.reg = AXP192_GPIO34_FUNC_REG,
140 		.mask = AXP192_GPIO3_FUNC_MASK,
141 	},
142 	{
143 		/* GPIO4 */
144 		.reg = AXP192_GPIO34_FUNC_REG,
145 		.mask = AXP192_GPIO4_FUNC_MASK,
146 	},
147 };
148 #endif /* CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED */
149 
150 #ifdef CONFIG_DT_HAS_X_POWERS_AXP2101_ENABLED
151 
152 /* Chip ID value */
153 #define AXP2101_CHIP_ID		0x4AU
154 
155 /* Registers definitions */
156 #define AXP2101_REG_CHIP_ID	0x03U
157 
158 /* AXP210 GPIO register addresses */
159 #define AXP2101_VBUS_CFG_REG	0x00U
160 
161 /* VBUS control reg values */
162 #define AXP2101_VBUS_CFG_VAL_VBUSEN_DISABLE	0x00U
163 #endif /* CONFIG_DT_HAS_X_POWERS_AXP2101_ENABLED */
164 
mfd_axp192_init(const struct device * dev)165 static int mfd_axp192_init(const struct device *dev)
166 {
167 	const struct mfd_axp192_config *config = dev->config;
168 	uint8_t chip_id;
169 	int ret;
170 
171 	LOG_DBG("Initializing instance");
172 
173 	if (!i2c_is_ready_dt(&config->i2c)) {
174 		LOG_ERR("I2C bus not ready");
175 		return -ENODEV;
176 	}
177 
178 	/* Check if axp192 chip is available */
179 	ret = i2c_reg_read_byte_dt(&config->i2c, config->reg_chip_id, &chip_id);
180 	if (ret < 0) {
181 		return ret;
182 	}
183 	if (chip_id != config->chip_id) {
184 		LOG_ERR("Invalid Chip detected (%d)", chip_id);
185 		return -EINVAL;
186 	}
187 
188 #ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
189 	/* Disable N_VBUSEN */
190 	ret = i2c_reg_update_byte_dt(
191 		&config->i2c, config->vbus_config_reg, config->val_vbusen_disable,
192 		config->vbusen_disable ? config->val_vbusen_disable : 0);
193 	if (ret < 0) {
194 		return ret;
195 	}
196 #endif
197 
198 	return 0;
199 }
200 
201 #ifdef CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED
mfd_axp192_gpio_func_get(const struct device * dev,uint8_t gpio,enum axp192_gpio_func * func)202 int mfd_axp192_gpio_func_get(const struct device *dev, uint8_t gpio, enum axp192_gpio_func *func)
203 {
204 	const struct mfd_axp192_config *config = dev->config;
205 	int ret;
206 	uint8_t reg_fnc;
207 
208 	if (gpio >= AXP192_GPIO_MAX_NUM) {
209 		LOG_ERR("Invalid gpio (%d)", gpio);
210 		return -EINVAL;
211 	}
212 
213 	if (gpio < ARRAY_SIZE(gpio_reg_desc)) {
214 		ret = i2c_reg_read_byte_dt(&(config->i2c), gpio_reg_desc[gpio].reg, &reg_fnc);
215 		if (ret != 0) {
216 			return ret;
217 		}
218 	}
219 
220 	switch (gpio) {
221 	case 0U:
222 		__fallthrough;
223 	case 1U:
224 		__fallthrough;
225 	case 2U:
226 		/* GPIO 0-2*/
227 		switch (reg_fnc) {
228 		case AXP192_GPIO012_FUNC_VAL_INPUT:
229 			*func = AXP192_GPIO_FUNC_INPUT;
230 			break;
231 		case AXP192_GPIO012_FUNC_VAL_OUTPUT_OD:
232 			*func = AXP192_GPIO_FUNC_OUTPUT_OD;
233 			break;
234 		case AXP192_GPIO012_FUNC_VAL_OUTPUT_LOW:
235 			*func = AXP192_GPIO_FUNC_OUTPUT_LOW;
236 			break;
237 		case AXP192_GPIO012_FUNC_VAL_LDO:
238 			if (gpio == 0) {
239 				/* LDO is only applicable on GPIO0 */
240 				*func = AXP192_GPIO_FUNC_LDO;
241 			} else {
242 				ret = -ENOTSUP;
243 			}
244 			break;
245 		case AXP192_GPIO012_FUNC_VAL_ADC:
246 			*func = AXP192_GPIO_FUNC_ADC;
247 			break;
248 		case AXP192_GPIO012_FUNC_VAL_FLOAT:
249 			*func = AXP192_GPIO_FUNC_FLOAT;
250 			break;
251 		default:
252 			ret = -ENOTSUP;
253 			break;
254 		}
255 		break;
256 
257 	case 3U:
258 		/* GPIO3 */
259 		switch (reg_fnc) {
260 		case (AXP192_GPIO3_FUNC_VAL_INPUT | AXP192_GPIO34_FUNC_ENA):
261 			*func = AXP192_GPIO_FUNC_INPUT;
262 			break;
263 		case (AXP192_GPIO3_FUNC_VAL_OUTPUT_OD | AXP192_GPIO34_FUNC_ENA):
264 			*func = AXP192_GPIO_FUNC_OUTPUT_OD;
265 			break;
266 		case AXP192_GPIO3_FUNC_VAL_CHARGE_CTL:
267 			*func = AXP192_GPIO_FUNC_CHARGE_CTL;
268 			break;
269 		default:
270 			ret = -ENOTSUP;
271 			break;
272 		}
273 		break;
274 
275 	case 4U:
276 		/* GPIO4 */
277 		switch (reg_fnc) {
278 		case (AXP192_GPIO4_FUNC_VAL_INPUT | AXP192_GPIO34_FUNC_ENA):
279 			*func = AXP192_GPIO_FUNC_INPUT;
280 			break;
281 		case (AXP192_GPIO4_FUNC_VAL_OUTPUT_OD | AXP192_GPIO34_FUNC_ENA):
282 			*func = AXP192_GPIO_FUNC_OUTPUT_OD;
283 			break;
284 		case (AXP192_GPIO4_FUNC_VAL_ADC | AXP192_GPIO34_FUNC_ENA):
285 			*func = AXP192_GPIO_FUNC_ADC;
286 			break;
287 		case AXP192_GPIO4_FUNC_VAL_CHARGE_CTL:
288 			*func = AXP192_GPIO_FUNC_CHARGE_CTL;
289 			break;
290 		default:
291 			ret = -ENOTSUP;
292 			break;
293 		}
294 		break;
295 
296 	case 5U:
297 		/* EXTEN is an output only pin */
298 		*func = AXP192_GPIO_FUNC_OUTPUT_LOW;
299 		break;
300 
301 	default:
302 		ret = -EINVAL;
303 	}
304 
305 	return ret;
306 }
307 
mfd_axp192_gpio_func_ctrl(const struct device * dev,const struct device * client_dev,uint8_t gpio,enum axp192_gpio_func func)308 int mfd_axp192_gpio_func_ctrl(const struct device *dev, const struct device *client_dev,
309 			      uint8_t gpio, enum axp192_gpio_func func)
310 {
311 	const struct mfd_axp192_config *config = dev->config;
312 	struct mfd_axp192_data *data = dev->data;
313 	bool is_output = false;
314 	int ret = 0;
315 	uint8_t reg_cfg = 0;
316 
317 	if (!AXP192_GPIO_FUNC_VALID(func)) {
318 		LOG_ERR("Invalid function");
319 		return -EINVAL;
320 	}
321 
322 	if (gpio >= AXP192_GPIO_MAX_NUM) {
323 		LOG_ERR("Invalid gpio (%d)", gpio);
324 		return -EINVAL;
325 	}
326 
327 	if ((data->gpio_mask_used[gpio] != 0) && (data->gpio_mask_used[gpio] != client_dev)) {
328 		LOG_INF("Warning: Pin already configured. Please check dt configuration");
329 	}
330 
331 	switch (gpio) {
332 	case 0U:
333 		__fallthrough;
334 	case 1U:
335 		__fallthrough;
336 	case 2U:
337 		/* GPIO 0-2*/
338 		switch (func) {
339 		case AXP192_GPIO_FUNC_INPUT:
340 			reg_cfg = AXP192_GPIO012_FUNC_VAL_INPUT;
341 			break;
342 		case AXP192_GPIO_FUNC_OUTPUT_OD:
343 			reg_cfg = AXP192_GPIO012_FUNC_VAL_OUTPUT_OD;
344 			is_output = true;
345 			break;
346 		case AXP192_GPIO_FUNC_OUTPUT_LOW:
347 			reg_cfg = AXP192_GPIO012_FUNC_VAL_OUTPUT_LOW;
348 			is_output = true;
349 			break;
350 		case AXP192_GPIO_FUNC_LDO:
351 			if (gpio == 0) {
352 				/* LDO is only applicable on GPIO0 */
353 				reg_cfg = AXP192_GPIO012_FUNC_VAL_LDO;
354 			} else {
355 				ret = -ENOTSUP;
356 			}
357 			break;
358 		case AXP192_GPIO_FUNC_ADC:
359 			reg_cfg = AXP192_GPIO012_FUNC_VAL_ADC;
360 			break;
361 		case AXP192_GPIO_FUNC_FLOAT:
362 			reg_cfg = AXP192_GPIO012_FUNC_VAL_FLOAT;
363 			break;
364 		default:
365 			ret = -ENOTSUP;
366 			break;
367 		}
368 		break;
369 
370 	case 3U:
371 		/* GPIO3 */
372 		switch (func) {
373 		case AXP192_GPIO_FUNC_INPUT:
374 			reg_cfg = AXP192_GPIO3_FUNC_VAL_INPUT | AXP192_GPIO34_FUNC_ENA;
375 			break;
376 		case AXP192_GPIO_FUNC_OUTPUT_OD:
377 			reg_cfg = AXP192_GPIO3_FUNC_VAL_OUTPUT_OD | AXP192_GPIO34_FUNC_ENA;
378 			is_output = true;
379 			break;
380 		case AXP192_GPIO_FUNC_CHARGE_CTL:
381 			reg_cfg = AXP192_GPIO3_FUNC_VAL_CHARGE_CTL;
382 			break;
383 		default:
384 			ret = -ENOTSUP;
385 			break;
386 		}
387 		break;
388 
389 	case 4U:
390 		/* GPIO4 */
391 		switch (func) {
392 		case AXP192_GPIO_FUNC_INPUT:
393 			reg_cfg = AXP192_GPIO4_FUNC_VAL_INPUT | AXP192_GPIO34_FUNC_ENA;
394 			break;
395 		case AXP192_GPIO_FUNC_OUTPUT_OD:
396 			reg_cfg = AXP192_GPIO4_FUNC_VAL_OUTPUT_OD | AXP192_GPIO34_FUNC_ENA;
397 			is_output = true;
398 			break;
399 		case AXP192_GPIO_FUNC_ADC:
400 			reg_cfg = AXP192_GPIO4_FUNC_VAL_ADC | AXP192_GPIO34_FUNC_ENA;
401 			break;
402 		case AXP192_GPIO_FUNC_CHARGE_CTL:
403 			reg_cfg = AXP192_GPIO4_FUNC_VAL_CHARGE_CTL;
404 			break;
405 		default:
406 			ret = -ENOTSUP;
407 			break;
408 		}
409 		break;
410 
411 	case 5U:
412 		/* EXTEN is an output only pin */
413 		break;
414 
415 	default:
416 		ret = -EINVAL;
417 	}
418 
419 	if (ret != 0) {
420 		LOG_ERR("Invalid function (0x%x) for gpio %d", func, gpio);
421 		return ret;
422 	}
423 
424 	if (gpio < ARRAY_SIZE(gpio_reg_desc)) {
425 		ret = i2c_reg_update_byte_dt(&(config->i2c), gpio_reg_desc[gpio].reg,
426 					     gpio_reg_desc[gpio].mask, reg_cfg);
427 		if (ret != 0) {
428 			return ret;
429 		}
430 	}
431 
432 	/* Save gpio configuration state */
433 	data->gpio_mask_used[gpio] = client_dev;
434 	if (is_output) {
435 		data->gpio_mask_output |= (1u << gpio);
436 	} else {
437 		data->gpio_mask_output &= ~(1u << gpio);
438 	}
439 	LOG_DBG("GPIO %d configured successfully (func=0x%x)", gpio, reg_cfg);
440 
441 	return 0;
442 }
443 
mfd_axp192_gpio_pd_get(const struct device * dev,uint8_t gpio,bool * enabled)444 int mfd_axp192_gpio_pd_get(const struct device *dev, uint8_t gpio, bool *enabled)
445 {
446 	const struct mfd_axp192_config *config = dev->config;
447 	uint8_t gpio_val;
448 	uint8_t pd_reg_mask = 0;
449 	int ret = 0;
450 
451 	switch (gpio) {
452 	case 0U:
453 		pd_reg_mask = AXP192_GPIO0_PULLDOWN_ENABLE;
454 		break;
455 	case 1U:
456 		pd_reg_mask = AXP192_GPIO1_PULLDOWN_ENABLE;
457 		break;
458 	case 2U:
459 		pd_reg_mask = AXP192_GPIO2_PULLDOWN_ENABLE;
460 		break;
461 
462 	case 3U:
463 		__fallthrough;
464 	case 4U:
465 		__fallthrough;
466 	case 5U:
467 		LOG_DBG("Pull-Down not support on gpio %d", gpio);
468 		return -ENOTSUP;
469 
470 	default:
471 		LOG_ERR("Invalid gpio (%d)", gpio);
472 		return -EINVAL;
473 	}
474 
475 	ret = i2c_reg_read_byte_dt(&(config->i2c), AXP192_GPIO012_PULLDOWN_REG, &gpio_val);
476 
477 	if (ret == 0) {
478 		*enabled = ((gpio_val & pd_reg_mask) != 0);
479 		LOG_DBG("Pull-Down stats of gpio %d: %d", gpio, *enabled);
480 	}
481 
482 	return 0;
483 }
484 
mfd_axp192_gpio_pd_ctrl(const struct device * dev,uint8_t gpio,bool enable)485 int mfd_axp192_gpio_pd_ctrl(const struct device *dev, uint8_t gpio, bool enable)
486 {
487 	uint8_t reg_pd_val = 0;
488 	uint8_t reg_pd_mask = 0;
489 	const struct mfd_axp192_config *config = dev->config;
490 	int ret = 0;
491 
492 	/* Configure pull-down. Pull-down is only supported by GPIO3 and GPIO4 */
493 	switch (gpio) {
494 	case 0U:
495 		reg_pd_mask = AXP192_GPIO0_PULLDOWN_ENABLE;
496 		if (enable) {
497 			reg_pd_val = AXP192_GPIO0_PULLDOWN_ENABLE;
498 		}
499 		break;
500 
501 	case 1U:
502 		reg_pd_mask = AXP192_GPIO1_PULLDOWN_ENABLE;
503 		if (enable) {
504 			reg_pd_val = AXP192_GPIO1_PULLDOWN_ENABLE;
505 		}
506 		break;
507 
508 	case 2U:
509 		reg_pd_mask = AXP192_GPIO2_PULLDOWN_ENABLE;
510 		if (enable) {
511 			reg_pd_val = AXP192_GPIO2_PULLDOWN_ENABLE;
512 		}
513 		break;
514 
515 	case 3U:
516 		__fallthrough;
517 	case 4U:
518 		__fallthrough;
519 	case 5U:
520 		LOG_ERR("Pull-Down not support on gpio %d", gpio);
521 		return -ENOTSUP;
522 
523 	default:
524 		LOG_ERR("Invalid gpio (%d)", gpio);
525 		return -EINVAL;
526 	}
527 
528 	ret = i2c_reg_update_byte_dt(&(config->i2c), AXP192_GPIO012_PULLDOWN_REG, reg_pd_mask,
529 				     reg_pd_val);
530 
531 	return ret;
532 }
533 
mfd_axp192_gpio_read_port(const struct device * dev,uint8_t * value)534 int mfd_axp192_gpio_read_port(const struct device *dev, uint8_t *value)
535 {
536 	const struct mfd_axp192_config *config = dev->config;
537 	const struct mfd_axp192_data *data = dev->data;
538 	int ret;
539 	uint8_t gpio012_val;
540 	uint8_t gpio34_val;
541 	uint8_t gpio5_val;
542 	uint8_t gpio_input_val;
543 	uint8_t gpio_output_val;
544 
545 	/* read gpio0-2 */
546 	ret = i2c_reg_read_byte_dt(&(config->i2c), AXP192_GPIO012_PINVAL_REG, &gpio012_val);
547 	if (ret != 0) {
548 		return ret;
549 	}
550 
551 	/* read gpio3-4 */
552 	ret = i2c_reg_read_byte_dt(&(config->i2c), AXP192_GPIO34_PINVAL_REG, &gpio34_val);
553 	if (ret != 0) {
554 		return ret;
555 	}
556 
557 	/* read gpio5 */
558 	ret = i2c_reg_read_byte_dt(&(config->i2c), AXP192_EXTEN_DCDC2_CONTROL_REG, &gpio5_val);
559 	if (ret != 0) {
560 		return ret;
561 	}
562 
563 	LOG_DBG("GPIO012 pinval-reg=0x%x", gpio012_val);
564 	LOG_DBG("GPIO34 pinval-reg =0x%x", gpio34_val);
565 	LOG_DBG("GPIO5 pinval-reg =0x%x", gpio5_val);
566 	LOG_DBG("Output-Mask       =0x%x", data->gpio_mask_output);
567 
568 	gpio_input_val =
569 		((gpio012_val & AXP192_GPIO012_INTPUT_MASK) >> AXP192_GPIO012_INTPUT_SHIFT);
570 	gpio_input_val |=
571 		(((gpio34_val & AXP192_GPIO34_INTPUT_MASK) >> AXP192_GPIO34_INTPUT_SHIFT) << 3u);
572 
573 	gpio_output_val = (gpio012_val & AXP192_GPIO012_OUTPUT_MASK);
574 	gpio_output_val |= ((gpio34_val & AXP192_GPIO34_OUTPUT_MASK) << 3u);
575 	gpio_output_val |=
576 		(((gpio5_val & AXP192_GPIO5_OUTPUT_MASK) >> AXP192_GPIO5_OUTPUT_SHIFT) << 5u);
577 
578 	*value = gpio_input_val & ~(data->gpio_mask_output);
579 	*value |= (gpio_output_val & data->gpio_mask_output);
580 
581 	return 0;
582 }
583 
mfd_axp192_gpio_write_port(const struct device * dev,uint8_t value,uint8_t mask)584 int mfd_axp192_gpio_write_port(const struct device *dev, uint8_t value, uint8_t mask)
585 {
586 	const struct mfd_axp192_config *config = dev->config;
587 	int ret;
588 	uint8_t gpio_reg_val;
589 	uint8_t gpio_reg_mask;
590 
591 	/* Write gpio0-2. Mask out other port pins */
592 	gpio_reg_val = (value & AXP192_GPIO012_OUTPUT_MASK);
593 	gpio_reg_mask = (mask & AXP192_GPIO012_OUTPUT_MASK);
594 	if (gpio_reg_mask != 0) {
595 		ret = i2c_reg_update_byte_dt(&(config->i2c), AXP192_GPIO012_PINVAL_REG,
596 					     gpio_reg_mask, gpio_reg_val);
597 		if (ret != 0) {
598 			return ret;
599 		}
600 		LOG_DBG("GPIO012 pinval-reg=0x%x mask=0x%x", gpio_reg_val, gpio_reg_mask);
601 	}
602 
603 	/* Write gpio3-4. Mask out other port pins */
604 	gpio_reg_val = value >> 3U;
605 	gpio_reg_mask = (mask >> 3U) & AXP192_GPIO34_OUTPUT_MASK;
606 	if (gpio_reg_mask != 0) {
607 		ret = i2c_reg_update_byte_dt(&(config->i2c), AXP192_GPIO34_PINVAL_REG,
608 					     gpio_reg_mask, gpio_reg_val);
609 		if (ret != 0) {
610 			return ret;
611 		}
612 		LOG_DBG("GPIO34 pinval-reg =0x%x mask=0x%x", gpio_reg_val, gpio_reg_mask);
613 	}
614 
615 	/* Write gpio5. Mask out other port pins */
616 	if ((mask & BIT(5)) != 0) {
617 		gpio_reg_mask = AXP192_EXTEN_MASK;
618 		gpio_reg_val = (value & BIT(5)) ? AXP192_EXTEN_ENA : 0U;
619 		ret = i2c_reg_update_byte_dt(&(config->i2c), AXP192_EXTEN_DCDC2_CONTROL_REG,
620 					     gpio_reg_mask, gpio_reg_val);
621 		if (ret != 0) {
622 			return ret;
623 		}
624 		LOG_DBG("GPIO5 pinval-reg =0x%x mask=0x%x\n", gpio_reg_val, gpio_reg_mask);
625 	}
626 
627 	return 0;
628 }
629 #endif
630 
631 #define MFD_AXP192_CONST_CONFIG(model)                                                             \
632 	.reg_chip_id = AXP##model##_REG_CHIP_ID,                                                   \
633 	.vbus_config_reg = AXP##model##_VBUS_CFG_REG,                                              \
634 	.chip_id = AXP##model##_CHIP_ID,                                                           \
635 	.val_vbusen_disable = AXP##model##_CHIP_ID,
636 
637 #define MFD_AXP192_AXP2101_DEFINE(node, model)                                                     \
638 	static const struct mfd_axp192_config config##node = {                                     \
639 		.i2c = I2C_DT_SPEC_GET(node),                                                      \
640 		IF_ENABLED(CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED,                                  \
641 		(.vbusen_disable = DT_PROP_OR(node, vbusen_disable, false),))                      \
642 		MFD_AXP192_CONST_CONFIG(model)                                                     \
643 	};                                                                                         \
644                                                                                                    \
645 	IF_ENABLED(CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED,                                          \
646 		   (static struct mfd_axp192_data data##node;))                                    \
647                                                                                                    \
648 	DEVICE_DT_DEFINE(node, mfd_axp192_init, NULL,                                              \
649 			 COND_CODE_1(CONFIG_DT_HAS_X_POWERS_AXP192_ENABLED,                        \
650 				     (&data##node), (NULL)),                                       \
651 			 &config##node, POST_KERNEL, CONFIG_MFD_INIT_PRIORITY, NULL);
652 
653 DT_FOREACH_STATUS_OKAY_VARGS(x_powers_axp192, MFD_AXP192_AXP2101_DEFINE, 192);
654 DT_FOREACH_STATUS_OKAY_VARGS(x_powers_axp2101, MFD_AXP192_AXP2101_DEFINE, 2101);
655