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, ®_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