/* * Copyright (c) 2022-2023, Gerson Fernando Budke * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include /** Utility macro that expands to the GPIO port address if it exists */ #define SAM_PORT_ADDR_OR_NONE(nodelabel) \ IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \ (DT_REG_ADDR(DT_NODELABEL(nodelabel)),)) /** Utility macro that expands to the GPIO Peripheral ID if it exists */ #define SAM_PORT_CLOCKS_OR_NONE(nodelabel) \ IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)), \ (SAM_DT_CLOCK_PMC_CFG(0, DT_NODELABEL(nodelabel)),)) /** SAM port addresses */ static const uint32_t sam_port_addrs[] = { #ifdef ID_GPIO SAM_PORT_ADDR_OR_NONE(gpioa) SAM_PORT_ADDR_OR_NONE(gpiob) SAM_PORT_ADDR_OR_NONE(gpioc) #else SAM_PORT_ADDR_OR_NONE(pioa) SAM_PORT_ADDR_OR_NONE(piob) SAM_PORT_ADDR_OR_NONE(pioc) SAM_PORT_ADDR_OR_NONE(piod) SAM_PORT_ADDR_OR_NONE(pioe) SAM_PORT_ADDR_OR_NONE(piof) #endif }; /** SAM port clocks */ static const struct atmel_sam_pmc_config sam_port_clocks[] = { #ifdef ID_GPIO SAM_PORT_CLOCKS_OR_NONE(gpioa) SAM_PORT_CLOCKS_OR_NONE(gpiob) SAM_PORT_CLOCKS_OR_NONE(gpioc) #else SAM_PORT_CLOCKS_OR_NONE(pioa) SAM_PORT_CLOCKS_OR_NONE(piob) SAM_PORT_CLOCKS_OR_NONE(pioc) SAM_PORT_CLOCKS_OR_NONE(piod) SAM_PORT_CLOCKS_OR_NONE(pioe) SAM_PORT_CLOCKS_OR_NONE(piof) #endif }; static void pinctrl_configure_pin(pinctrl_soc_pin_t pin) { struct soc_gpio_pin soc_pin; uint8_t port_idx, port_func; port_idx = SAM_PINMUX_PORT_GET(pin); __ASSERT_NO_MSG(port_idx < ARRAY_SIZE(sam_port_addrs)); port_func = SAM_PINMUX_FUNC_GET(pin); #ifdef ID_GPIO soc_pin.regs = (Gpio *) sam_port_addrs[port_idx]; #else soc_pin.regs = (Pio *) sam_port_addrs[port_idx]; #endif soc_pin.periph_id = sam_port_clocks[port_idx].peripheral_id; soc_pin.mask = 1 << SAM_PINMUX_PIN_GET(pin); soc_pin.flags = SAM_PINCTRL_FLAGS_GET(pin) << SOC_GPIO_FLAGS_POS; if (port_func == SAM_PINMUX_FUNC_periph) { soc_pin.flags |= (SAM_PINMUX_PERIPH_GET(pin) << SOC_GPIO_FUNC_POS); } soc_gpio_configure(&soc_pin); } int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { ARG_UNUSED(reg); for (uint8_t i = 0U; i < pin_cnt; i++) { pinctrl_configure_pin(*pins++); } return 0; }