1 /*
2  * Copyright (c) 2022, Gerson Fernando Budke <nandojve@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/pinctrl.h>
8 #include <soc_port.h>
9 
10 /** Utility macro that expands to the PORT port address if it exists */
11 #define SAM_PORT_ADDR_OR_NONE(nodelabel)					\
12 	IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),			\
13 		   (DT_REG_ADDR(DT_NODELABEL(nodelabel)),))
14 
15 /** SAM0 port addresses */
16 static const uint32_t sam_port_addrs[] = {
17 	SAM_PORT_ADDR_OR_NONE(porta)
18 	SAM_PORT_ADDR_OR_NONE(portb)
19 	SAM_PORT_ADDR_OR_NONE(portc)
20 	SAM_PORT_ADDR_OR_NONE(portd)
21 	SAM_PORT_ADDR_OR_NONE(porte)
22 	SAM_PORT_ADDR_OR_NONE(portf)
23 };
24 
pinctrl_configure_pin(pinctrl_soc_pin_t pin)25 static void pinctrl_configure_pin(pinctrl_soc_pin_t pin)
26 {
27 	struct soc_port_pin soc_pin;
28 	uint8_t  port_idx, port_func;
29 
30 	port_idx = SAM_PINMUX_PORT_GET(pin);
31 	__ASSERT_NO_MSG(port_idx < ARRAY_SIZE(sam_port_addrs));
32 	port_func = SAM_PINMUX_FUNC_GET(pin);
33 
34 	soc_pin.regs = (PortGroup *) sam_port_addrs[port_idx];
35 	soc_pin.pinum = SAM_PINMUX_PIN_GET(pin);
36 	soc_pin.flags = SAM_PINCTRL_FLAGS_GET(pin) << SOC_PORT_FLAGS_POS;
37 
38 	if (port_func == SAM_PINMUX_FUNC_periph) {
39 		soc_pin.flags |= (SAM_PINMUX_PERIPH_GET(pin)
40 				  << SOC_PORT_FUNC_POS)
41 			      |  SOC_PORT_PMUXEN_ENABLE;
42 	}
43 
44 	soc_port_configure(&soc_pin);
45 }
46 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)47 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
48 			   uintptr_t reg)
49 {
50 	ARG_UNUSED(reg);
51 
52 	for (uint8_t i = 0U; i < pin_cnt; i++) {
53 		pinctrl_configure_pin(*pins++);
54 	}
55 
56 	return 0;
57 }
58