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