1 /*
2  * Copyright (c) 2023-2024 Analog Devices, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/dt-bindings/pinctrl/max32-pinctrl.h>
8 #include <zephyr/drivers/pinctrl.h>
9 
10 #include <gpio.h>
11 
12 #define ADI_MAX32_GET_PORT_ADDR_OR_NONE(nodelabel)                                                 \
13 	IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),                                        \
14 		   (DT_REG_ADDR(DT_NODELABEL(nodelabel)),))
15 
16 /** GPIO port addresses */
17 static const uint32_t gpios[] = {
18 	ADI_MAX32_GET_PORT_ADDR_OR_NONE(gpio0)
19 	ADI_MAX32_GET_PORT_ADDR_OR_NONE(gpio1)
20 	ADI_MAX32_GET_PORT_ADDR_OR_NONE(gpio2)
21 	ADI_MAX32_GET_PORT_ADDR_OR_NONE(gpio3)
22 	ADI_MAX32_GET_PORT_ADDR_OR_NONE(gpio4)
23 	ADI_MAX32_GET_PORT_ADDR_OR_NONE(gpio5)
24 };
25 
pinctrl_configure_pin(pinctrl_soc_pin_t soc_pin)26 static int pinctrl_configure_pin(pinctrl_soc_pin_t soc_pin)
27 {
28 	uint32_t port;
29 	uint32_t pin;
30 	uint32_t afx;
31 	int pincfg;
32 	mxc_gpio_cfg_t gpio_cfg;
33 
34 	port = MAX32_PINMUX_PORT(soc_pin.pinmux);
35 	pin = MAX32_PINMUX_PIN(soc_pin.pinmux);
36 	afx = MAX32_PINMUX_MODE(soc_pin.pinmux);
37 	pincfg = soc_pin.pincfg;
38 
39 	if (gpios[port] == 0) {
40 		return -EINVAL;
41 	}
42 
43 	gpio_cfg.port = (mxc_gpio_regs_t *)gpios[port];
44 	gpio_cfg.mask = BIT(pin);
45 
46 	if (pincfg & BIT(MAX32_BIAS_PULL_UP_SHIFT)) {
47 		gpio_cfg.pad = MXC_GPIO_PAD_PULL_UP;
48 	} else if (pincfg & BIT(MAX32_BIAS_PULL_DOWN_SHIFT)) {
49 		gpio_cfg.pad = MXC_GPIO_PAD_PULL_DOWN;
50 	} else {
51 		gpio_cfg.pad = MXC_GPIO_PAD_NONE;
52 	}
53 
54 	if (pincfg & BIT(MAX32_INPUT_ENABLE_SHIFT)) {
55 		gpio_cfg.func = MXC_GPIO_FUNC_IN;
56 	} else if (pincfg & BIT(MAX32_OUTPUT_ENABLE_SHIFT)) {
57 		gpio_cfg.func = MXC_GPIO_FUNC_OUT;
58 	} else {
59 		/* Add +1 to index match */
60 		gpio_cfg.func = (mxc_gpio_func_t)(afx + 1);
61 	}
62 
63 	if (pincfg & BIT(MAX32_POWER_SOURCE_SHIFT)) {
64 		gpio_cfg.vssel = MXC_GPIO_VSSEL_VDDIOH;
65 	} else {
66 		gpio_cfg.vssel = MXC_GPIO_VSSEL_VDDIO;
67 	}
68 
69 	gpio_cfg.drvstr = (pincfg >> MAX32_DRV_STRENGTH_SHIFT) & MAX32_DRV_STRENGTH_MASK;
70 
71 	if (MXC_GPIO_Config(&gpio_cfg) != 0) {
72 		return -ENOTSUP;
73 	}
74 
75 	if (pincfg & BIT(MAX32_OUTPUT_ENABLE_SHIFT)) {
76 		if (pincfg & BIT(MAX32_OUTPUT_HIGH_SHIFT)) {
77 			MXC_GPIO_OutSet(gpio_cfg.port, BIT(pin));
78 		} else {
79 			MXC_GPIO_OutClr(gpio_cfg.port, BIT(pin));
80 		}
81 	}
82 
83 	return 0;
84 }
85 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)86 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
87 {
88 	ARG_UNUSED(reg);
89 
90 	int ret;
91 
92 	for (uint8_t i = 0U; i < pin_cnt; i++) {
93 		ret = pinctrl_configure_pin(*pins++);
94 		if (ret) {
95 			return ret;
96 		}
97 	}
98 
99 	return 0;
100 }
101