You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.3 KiB
89 lines
2.3 KiB
/* |
|
* Copyright (c) 2022-2023, Gerson Fernando Budke <nandojve@gmail.com> |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <zephyr/drivers/pinctrl.h> |
|
#include <zephyr/drivers/clock_control/atmel_sam_pmc.h> |
|
#include <soc_gpio.h> |
|
|
|
/** 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; |
|
}
|
|
|