diff --git a/boards/arm/frdm_k22f/pinmux.c b/boards/arm/frdm_k22f/pinmux.c index 1342f91df9d29..8a2209bf34731 100644 --- a/boards/arm/frdm_k22f/pinmux.c +++ b/boards/arm/frdm_k22f/pinmux.c @@ -38,22 +38,6 @@ static int frdm_k22f_pinmux_init(const struct device *dev) __ASSERT_NO_MSG(device_is_ready(porte)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL -#error "No UART0 is used" -#endif - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) && CONFIG_SERIAL - /* UART1 RX, TX */ - pinmux_pin_set(porte, 0, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(porte, 1, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) && CONFIG_SERIAL - /* UART2 RX, TX */ - pinmux_pin_set(portd, 2, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portd, 3, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(ftm0), nxp_kinetis_ftm_pwm, okay) && CONFIG_PWM /* Red, green, blue LEDs as PWM channels*/ pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAlt3)); diff --git a/boards/arm/frdm_k64f/pinmux.c b/boards/arm/frdm_k64f/pinmux.c index 1636231e4228a..d254dfd7017ce 100644 --- a/boards/arm/frdm_k64f/pinmux.c +++ b/boards/arm/frdm_k64f/pinmux.c @@ -38,26 +38,6 @@ static int frdm_k64f_pinmux_init(const struct device *dev) __ASSERT_NO_MSG(device_is_ready(porte)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL - /* UART0 RX, TX */ - pinmux_pin_set(portb, 16, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portb, 17, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) && CONFIG_SERIAL - /* UART2 RX, TX */ - pinmux_pin_set(portd, 0, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portd, 1, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portd, 2, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portd, 3, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay) && CONFIG_SERIAL - /* UART3 RX, TX */ - pinmux_pin_set(portc, 16, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portc, 17, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - #if DT_NODE_HAS_STATUS(DT_NODELABEL(spi0), okay) && CONFIG_SPI /* SPI0 CS0, SCK, SOUT, SIN */ pinmux_pin_set(portd, 0, PORT_PCR_MUX(kPORT_MuxAlt2)); diff --git a/boards/arm/frdm_kl25z/pinmux.c b/boards/arm/frdm_kl25z/pinmux.c index 8ecd70c62a944..d2fb116d9fc07 100644 --- a/boards/arm/frdm_kl25z/pinmux.c +++ b/boards/arm/frdm_kl25z/pinmux.c @@ -38,12 +38,6 @@ static int frdm_kl25z_pinmux_init(const struct device *dev) __ASSERT_NO_MSG(device_is_ready(porte)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL - /* UART0 RX, TX */ - pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAlt2)); - pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAlt2)); -#endif - #if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c0), okay) && CONFIG_I2C /* I2C0 SCL, SDA */ pinmux_pin_set(porte, 24, PORT_PCR_MUX(kPORT_MuxAlt5) diff --git a/boards/arm/hexiwear_k64/pinmux.c b/boards/arm/hexiwear_k64/pinmux.c index aa1c8a9593439..d593f7271c6cc 100644 --- a/boards/arm/hexiwear_k64/pinmux.c +++ b/boards/arm/hexiwear_k64/pinmux.c @@ -62,18 +62,6 @@ static int hexiwear_k64_pinmux_init(const struct device *dev) | PORT_PCR_ODE_MASK); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL - /* UART0 RX, TX */ - pinmux_pin_set(portb, 16, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(portb, 17, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && CONFIG_SERIAL - /* UART4 RX, TX - BLE */ - pinmux_pin_set(porte, 24, PORT_PCR_MUX(kPORT_MuxAlt3)); - pinmux_pin_set(porte, 25, PORT_PCR_MUX(kPORT_MuxAlt3)); -#endif - #if defined(CONFIG_MAX30101) && DT_NODE_HAS_STATUS(DT_NODELABEL(gpioa), okay) const struct device *gpioa = device_get_binding(DT_LABEL(DT_NODELABEL(gpioa))); diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840-pinctrl.dtsi b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840-pinctrl.dtsi new file mode 100644 index 0000000000000..0aee691f2a2a2 --- /dev/null +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840-pinctrl.dtsi @@ -0,0 +1,27 @@ +&pinctrl { + /* UART0 */ + uart0_default: uart0_default { + pincfg = ; + }; + + uart0_sleep: uart0_sleep { + pincfg = ; + }; + + /* UART1 */ + uart1_default: uart1_default { + pincfg = ; + }; + + uart1_sleep: uart1_sleep { + pincfg = ; + }; +}; diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts index d991f386756e1..bbc5e720ae35a 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts @@ -6,6 +6,7 @@ /dts-v1/; #include +#include "nrf52840dk_nrf52840-pinctrl.dtsi" / { model = "Nordic nRF52840 DK NRF52840"; @@ -144,20 +145,19 @@ compatible = "nordic,nrf-uarte"; status = "okay"; current-speed = <115200>; - tx-pin = <6>; - rx-pin = <8>; - rx-pull-up; - rts-pin = <5>; - cts-pin = <7>; - cts-pull-up; + + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; }; arduino_serial: &uart1 { status = "okay"; current-speed = <115200>; - rx-pin = <33>; - rx-pull-up; - tx-pin = <34>; + + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; }; arduino_i2c: &i2c0 { diff --git a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig index 0202d7ba16da3..100d91ed3203b 100644 --- a/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig +++ b/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840_defconfig @@ -25,3 +25,5 @@ CONFIG_UART_CONSOLE=y # additional board options CONFIG_GPIO_AS_PINRESET=y + +CONFIG_PINCTRL=y diff --git a/boards/arm/twr_kv58f220m/pinmux.c b/boards/arm/twr_kv58f220m/pinmux.c index ca5031247d71e..3c112418871fb 100644 --- a/boards/arm/twr_kv58f220m/pinmux.c +++ b/boards/arm/twr_kv58f220m/pinmux.c @@ -46,12 +46,6 @@ static int twr_kv58f220m_pinmux_init(const struct device *dev) | PORT_PCR_ODE_MASK); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL - /* UART0 RX, TX */ - pinmux_pin_set(portb, 0, PORT_PCR_MUX(kPORT_MuxAlt7)); - pinmux_pin_set(portb, 1, PORT_PCR_MUX(kPORT_MuxAlt7)); -#endif - return 0; } diff --git a/boards/arm/usb_kw24d512/pinmux.c b/boards/arm/usb_kw24d512/pinmux.c index fd23091163f9a..69af39ff139e1 100644 --- a/boards/arm/usb_kw24d512/pinmux.c +++ b/boards/arm/usb_kw24d512/pinmux.c @@ -38,12 +38,6 @@ static int usb_kw24d512_pinmux_init(const struct device *dev) __ASSERT_NO_MSG(device_is_ready(porte)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) && CONFIG_SERIAL - /* UART0 RX, TX */ - pinmux_pin_set(porta, 1, PORT_PCR_MUX(kPORT_MuxAlt2)); - pinmux_pin_set(porta, 2, PORT_PCR_MUX(kPORT_MuxAlt2)); -#endif - #if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI /* SPI1 CS0, SCK, SOUT, SIN */ pinmux_pin_set(portb, 10, PORT_PCR_MUX(kPORT_MuxAlt2)); diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index f6b3ffa030b44..a4a55ab4037b2 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -26,6 +26,7 @@ add_subdirectory_ifdef(CONFIG_IPM ipm) add_subdirectory_ifdef(CONFIG_LED led) add_subdirectory_ifdef(CONFIG_LED_STRIP led_strip) add_subdirectory_ifdef(CONFIG_MODEM modem) +add_subdirectory_ifdef(CONFIG_PINCTRL pinctrl) add_subdirectory_ifdef(CONFIG_PINMUX pinmux) add_subdirectory_ifdef(CONFIG_PWM pwm) add_subdirectory_ifdef(CONFIG_SENSOR sensor) diff --git a/drivers/Kconfig b/drivers/Kconfig index 00c0e5c1a1605..b002ce2b40ee7 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -45,6 +45,8 @@ source "drivers/i2s/Kconfig" source "drivers/pwm/Kconfig" +source "drivers/pinctrl/Kconfig" + source "drivers/pinmux/Kconfig" source "drivers/adc/Kconfig" diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt new file mode 100644 index 0000000000000..29eac9f5ba818 --- /dev/null +++ b/drivers/pinctrl/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_USERSPACE pinctrl_handlers.c) + +zephyr_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig new file mode 100644 index 0000000000000..dfa98adcc60af --- /dev/null +++ b/drivers/pinctrl/Kconfig @@ -0,0 +1,21 @@ +# pinctrl configuration options + +# Copyright (c) 2021 Piotr Mienkowski +# SPDX-License-Identifier: Apache-2.0 + +menuconfig PINCTRL + bool "Pin Controller driver" + help + Enable pinctrl driver. + +if PINCTRL + +config PINCTRL_SAM + def_bool y + depends on SOC_FAMILY_SAM + help + Enable Atmel SAM pinctrl driver. + +source "drivers/pinctrl/Kconfig.nrf" + +endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.nrf b/drivers/pinctrl/Kconfig.nrf new file mode 100644 index 0000000000000..724e5d090ba42 --- /dev/null +++ b/drivers/pinctrl/Kconfig.nrf @@ -0,0 +1,9 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_NRF + bool "nRF pin controller driver" + depends on SOC_FAMILY_NRF + default y + help + nRF pin controller driver diff --git a/drivers/pinctrl/pinctrl_handlers.c b/drivers/pinctrl/pinctrl_handlers.c new file mode 100644 index 0000000000000..6b9bfac0e5043 --- /dev/null +++ b/drivers/pinctrl/pinctrl_handlers.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021 Piotr Mienkowski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int z_vrfy_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec) +{ + Z_SYSCALL_MEMORY_READ(pin_spec, sizeof(pinctrl_soc_pins_t)); + + return z_impl_pinctrl_pin_configure(pin_spec); +} +#include diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c new file mode 100644 index 0000000000000..ec5d931f7dc61 --- /dev/null +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#if CONFIG_NRF_UARTE_PERIPHERAL +#include +#endif + +#if 0 && CONFIG_NRF_UARTE_PERIPHERAL +static void pinctrl_nrf_uarte_config(NRF_UARTE_Type *uarte, + const uint32_t *pincfgs, + size_t pincfgs_cnt) +{ + uint32_t pseltxd = NRF_UARTE_PSEL_DISCONNECTED; + uint32_t pselrxd = NRF_UARTE_PSEL_DISCONNECTED; + uint32_t pselrts = NRF_UARTE_PSEL_DISCONNECTED; + uint32_t pselcts = NRF_UARTE_PSEL_DISCONNECTED; + + for (size_t i = 0U; i < pincfgs_cnt; i++) { + switch (PINCTRL_NRF_GET_FUN(pincfgs[i])) { + case PINCTRL_NRF_FUN_UART_TX: + pseltxd = PINCTRL_NRF_GET_PIN(pincfgs[i]); + break; + case PINCTRL_NRF_FUN_UART_RX: + pselrxd = PINCTRL_NRF_GET_PIN(pincfgs[i]); + break; + case PINCTRL_NRF_FUN_UART_RTS: + pselrts = PINCTRL_NRF_GET_PIN(pincfgs[i]); + break; + case PINCTRL_NRF_FUN_UART_CTS: + pselcts = PINCTRL_NRF_GET_PIN(pincfgs[i]); + break; + default: + break; + } + } + + nrf_uarte_txrx_pins_set(uarte, pseltxd, pselrxd); + nrf_uarte_hwfc_pins_set(uarte, pselrts, pselcts); + + nrf_gpio_pin_write(pseltxd, 1); +} +#endif + +int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec) +{ +#if 0 + /* configure peripheral pin selection */ + switch (dev->pinctrl->reg) { +#if CONFIG_NRF_UARTE_PERIPHERAL +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart0), okay) + case DT_REG_ADDR(DT_NODELABEL(uart0)): +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) + case DT_REG_ADDR(DT_NODELABEL(uart1)): +#endif + pinctrl_nrf_uarte_config((NRF_UARTE_Type *)dev->pinctrl->reg, + state->pincfgs, + state->pincfgs_cnt); + break; +#endif + default: + return -ENOTSUP; + } + + /* configure pins GPIO settings */ + for (size_t i = 0U; i < state->pincfgs_cnt; i++) { + nrf_gpio_cfg(PINCTRL_NRF_GET_PIN(state->pincfgs[i]), + PINCTRL_NRF_GET_DIR(state->pincfgs[i]), + PINCTRL_NRF_GET_INP(state->pincfgs[i]), + PINCTRL_NRF_GET_PULL(state->pincfgs[i]), + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + } +#endif + + return 0; +} diff --git a/drivers/pinctrl/pinctrl_sam.c b/drivers/pinctrl/pinctrl_sam.c new file mode 100644 index 0000000000000..f80503cd8341a --- /dev/null +++ b/drivers/pinctrl/pinctrl_sam.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021 Piotr Mienkowski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec) +{ + soc_gpio_configure((const struct soc_gpio_pin *)pin_spec); + + return 0; +} diff --git a/drivers/pinmux/pinmux_mcux.c b/drivers/pinmux/pinmux_mcux.c index e4754578dab18..826932678146d 100644 --- a/drivers/pinmux/pinmux_mcux.c +++ b/drivers/pinmux/pinmux_mcux.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,13 @@ struct pinmux_mcux_config { PORT_Type *base; }; +int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec) +{ + pinmux_pin_set(pin_spec->port, pin_spec->pin, PORT_PCR_MUX(pin_spec->mux)); + + return 0; +} + static int pinmux_mcux_set(const struct device *dev, uint32_t pin, uint32_t func) { diff --git a/drivers/serial/Kconfig.usart_sam b/drivers/serial/Kconfig.usart_sam index 5e2c022b87933..1750cb8eefe19 100644 --- a/drivers/serial/Kconfig.usart_sam +++ b/drivers/serial/Kconfig.usart_sam @@ -8,5 +8,6 @@ config USART_SAM depends on SOC_FAMILY_SAM select SERIAL_HAS_DRIVER select SERIAL_SUPPORT_INTERRUPT + select PINCTRL help This option enables the USARTx driver for Atmel SAM MCUs. diff --git a/drivers/serial/uart_mcux.c b/drivers/serial/uart_mcux.c index 011e85ee2d2de..798c886f82f33 100644 --- a/drivers/serial/uart_mcux.c +++ b/drivers/serial/uart_mcux.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,7 @@ struct uart_mcux_config { #ifdef CONFIG_UART_INTERRUPT_DRIVEN void (*irq_config_func)(const struct device *dev); #endif + const struct pinctrl_config pincfg; }; struct uart_mcux_data { @@ -40,6 +42,8 @@ static int uart_mcux_configure(const struct device *dev, uint32_t clock_freq; status_t retval; + pinctrl_set_pin_state(config->pincfg.states[0]); + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq)) { return -EINVAL; @@ -359,10 +363,13 @@ static const struct uart_driver_api uart_mcux_driver_api = { }; #define UART_MCUX_DECLARE_CFG(n, IRQ_FUNC_INIT) \ + PINCTRL_DT_INST_CONFIG_DEFINE(n); \ + \ static const struct uart_mcux_config uart_mcux_##n##_config = { \ .base = (UART_Type *)DT_INST_REG_ADDR(n), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\ + .pincfg = PINCTRL_DT_INST_CONFIG_NAME(n), \ IRQ_FUNC_INIT \ } diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 17f79a90a4803..1b5ed051c00cc 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include @@ -160,13 +160,9 @@ struct uarte_nrfx_data { */ struct uarte_nrfx_config { NRF_UARTE_Type *uarte_regs; /* Instance address */ + const struct pinctrl_config pincfg; uint32_t flags; - uint32_t pseltxd; /* PSEL.TXD register value */ - uint32_t pselrxd; /* PSEL.RXD register value */ - uint32_t pselcts; /* PSEL.CTS register value */ - uint32_t pselrts; /* PSEL.RTS register value */ - nrf_gpio_pin_pull_t rxd_pull; /* RXD pin pull configuration */ - nrf_gpio_pin_pull_t cts_pull; /* CTS pin pull configuration */ + bool disable_rx; #ifdef CONFIG_UART_ASYNC_API nrfx_timer_t timer; #endif @@ -798,9 +794,10 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf, int32_t timeout) { struct uarte_nrfx_data *data = get_dev_data(dev); + const struct uarte_nrfx_config *cfg = get_dev_config(dev); NRF_UARTE_Type *uarte = get_uarte_instance(dev); - if (nrf_uarte_rx_pin_get(uarte) == NRF_UARTE_PSEL_DISCONNECTED) { + if (cfg->disable_rx) { __ASSERT(false, "TX only UARTE instance"); return -ENOTSUP; } @@ -1674,25 +1671,7 @@ static int uarte_instance_init(const struct device *dev, data->dev = dev; - nrf_gpio_pin_write(cfg->pseltxd, 1); - nrf_gpio_cfg_output(cfg->pseltxd); - - if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) { - nrf_gpio_cfg_input(cfg->pselrxd, cfg->rxd_pull); - } - - nrf_uarte_txrx_pins_set(uarte, cfg->pseltxd, cfg->pselrxd); - - if (cfg->pselcts != NRF_UARTE_PSEL_DISCONNECTED) { - nrf_gpio_cfg_input(cfg->pselcts, cfg->cts_pull); - } - - if (cfg->pselrts != NRF_UARTE_PSEL_DISCONNECTED) { - nrf_gpio_pin_write(cfg->pselrts, 1); - nrf_gpio_cfg_output(cfg->pselrts); - } - - nrf_uarte_hwfc_pins_set(uarte, cfg->pselrts, cfg->pselcts); + pinctrl_set_pin_state(cfg->pincfg.states[0]); err = uarte_nrfx_configure(dev, &get_dev_data(dev)->uart_config); if (err) { @@ -1720,7 +1699,7 @@ static int uarte_instance_init(const struct device *dev, /* Enable receiver and transmitter */ nrf_uarte_enable(uarte); - if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) { + if (!cfg->disable_rx) { nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDRX); nrf_uarte_rx_buffer_set(uarte, &data->rx_data, 1); @@ -1750,46 +1729,6 @@ static int uarte_instance_init(const struct device *dev, } #ifdef CONFIG_PM_DEVICE - -static void uarte_nrfx_pins_enable(const struct device *dev, bool enable) -{ - const struct uarte_nrfx_config *cfg = get_dev_config(dev); - - if (!(cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT)) { - return; - } - - if (enable) { - nrf_gpio_pin_write(cfg->pseltxd, 1); - nrf_gpio_cfg_output(cfg->pseltxd); - if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) { - nrf_gpio_cfg_input(cfg->pselrxd, cfg->rxd_pull); - } - - if (IS_RTS_PIN_SET(cfg->flags)) { - nrf_gpio_pin_write(cfg->pselrts, 1); - nrf_gpio_cfg_output(cfg->pselrts); - } - - if (IS_CTS_PIN_SET(cfg->flags)) { - nrf_gpio_cfg_input(cfg->pselcts, cfg->cts_pull); - } - } else { - nrf_gpio_cfg_default(cfg->pseltxd); - if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) { - nrf_gpio_cfg_default(cfg->pselrxd); - } - - if (IS_RTS_PIN_SET(cfg->flags)) { - nrf_gpio_cfg_default(cfg->pselrts); - } - - if (IS_CTS_PIN_SET(cfg->flags)) { - nrf_gpio_cfg_default(cfg->pselcts); - } - } -} - /** @brief Pend until TX is stopped. * * There are 2 configurations that must be handled: @@ -1832,10 +1771,16 @@ static int uarte_nrfx_pm_control(const struct device *dev, #if defined(CONFIG_UART_ASYNC_API) || defined(UARTE_INTERRUPT_DRIVEN) struct uarte_nrfx_data *data = get_dev_data(dev); #endif + const struct uarte_nrfx_config *cfg = get_dev_config(dev); + int ret; switch (action) { case PM_DEVICE_ACTION_RESUME: - uarte_nrfx_pins_enable(dev, true); + ret = pinctrl_state_set(dev, PINCTRL_STATE_ID_DEFAULT); + if (ret < 0) { + return ret; + } + nrf_uarte_enable(uarte); #ifdef CONFIG_UART_ASYNC_API @@ -1846,7 +1791,7 @@ static int uarte_nrfx_pm_control(const struct device *dev, return 0; } #endif - if (nrf_uarte_rx_pin_get(uarte) != NRF_UARTE_PSEL_DISCONNECTED) { + if (!cfg->disable_rx) { nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDRX); nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTRX); @@ -1899,7 +1844,11 @@ static int uarte_nrfx_pm_control(const struct device *dev, wait_for_tx_stopped(dev); uart_disable(dev); - uarte_nrfx_pins_enable(dev, false); + + ret = pinctrl_state_set(dev, PINCTRL_STATE_ID_SLEEP); + if (ret < 0) { + return ret; + } break; default: return -ENOTSUP; @@ -1913,19 +1862,6 @@ static int uarte_nrfx_pm_control(const struct device *dev, #define UARTE_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(UARTE(idx), prop) #define UARTE_PROP(idx, prop) DT_PROP(UARTE(idx), prop) -#define UARTE_PSEL(idx, pin_prop) \ - COND_CODE_1(UARTE_HAS_PROP(idx, pin_prop), \ - (UARTE_PROP(idx, pin_prop)), \ - (NRF_UARTE_PSEL_DISCONNECTED)) - -#define UARTE_PULL(idx, pull_up_prop) \ - COND_CODE_1(UARTE_PROP(idx, pull_up_prop), \ - (NRF_GPIO_PIN_PULLUP), \ - (NRF_GPIO_PIN_NOPULL)) - -#define HWFC_AVAILABLE(idx) \ - (UARTE_HAS_PROP(idx, rts_pin) || UARTE_HAS_PROP(idx, cts_pin)) - #define UARTE_IRQ_CONFIGURE(idx, isr_handler) \ do { \ IRQ_CONNECT(DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority), \ @@ -1933,13 +1869,6 @@ static int uarte_nrfx_pm_control(const struct device *dev, irq_enable(DT_IRQN(UARTE(idx))); \ } while (0) -#define HWFC_CONFIG_CHECK(idx) \ - BUILD_ASSERT( \ - (UARTE_PROP(idx, hw_flow_control) && HWFC_AVAILABLE(idx)) \ - || \ - !UARTE_PROP(idx, hw_flow_control) \ - ) - /* Low power mode is used when rx pin is not defined or in async mode if * kconfig option is enabled. */ @@ -1950,7 +1879,7 @@ static int uarte_nrfx_pm_control(const struct device *dev, (1))) ? 0 : UARTE_CFG_FLAG_LOW_POWER) #define UART_NRF_UARTE_DEVICE(idx) \ - HWFC_CONFIG_CHECK(idx); \ + PINCTRL_DT_CONFIG_DEFINE(UARTE(idx)); \ UARTE_INT_DRIVEN(idx); \ UARTE_ASYNC(idx); \ static struct uarte_nrfx_data uarte_##idx##_data = { \ @@ -1962,6 +1891,7 @@ static int uarte_nrfx_pm_control(const struct device *dev, }; \ static const struct uarte_nrfx_config uarte_##idx##z_config = { \ .uarte_regs = (NRF_UARTE_Type *)DT_REG_ADDR(UARTE(idx)), \ + .pincfg = PINCTRL_DT_CONFIG_NAME(UARTE(idx)), \ .flags = \ (UARTE_HAS_PROP(idx, rts_pin) ? \ UARTE_CFG_FLAG_RTS_PIN_SET : 0) | \ @@ -1972,12 +1902,7 @@ static int uarte_nrfx_pm_control(const struct device *dev, (IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT) ? \ UARTE_CFG_FLAG_PPI_ENDTX : 0) | \ USE_LOW_POWER(idx), \ - .pseltxd = UARTE_PROP(idx, tx_pin), /* must be set */ \ - .pselrxd = UARTE_PSEL(idx, rx_pin), /* optional */ \ - .pselcts = UARTE_PSEL(idx, cts_pin), /* optional */ \ - .pselrts = UARTE_PSEL(idx, rts_pin), /* optional */ \ - .rxd_pull = UARTE_PULL(idx, rx_pull_up), \ - .cts_pull = UARTE_PULL(idx, cts_pull_up), \ + .disable_rx = DT_PROP_OR(UARTE(idx), disable_rx, false), \ IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \ (.timer = NRFX_TIMER_INSTANCE( \ CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \ diff --git a/drivers/serial/usart_sam.c b/drivers/serial/usart_sam.c index 63e4267388ba2..158771883ed06 100644 --- a/drivers/serial/usart_sam.c +++ b/drivers/serial/usart_sam.c @@ -20,13 +20,13 @@ #include #include #include +#include /* Device constant configuration parameters */ struct usart_sam_dev_cfg { Usart *regs; uint32_t periph_id; - struct soc_gpio_pin pin_rx; - struct soc_gpio_pin pin_tx; + const struct pinctrl_config pincfg; #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_config_func_t irq_config_func; @@ -64,8 +64,7 @@ static int usart_sam_init(const struct device *dev) soc_pmc_peripheral_enable(cfg->periph_id); /* Connect pins to the peripheral */ - soc_gpio_configure(&cfg->pin_rx); - soc_gpio_configure(&cfg->pin_tx); + pinctrl_set_pin_state(cfg->pincfg.states[0]); /* Reset and disable USART */ usart->US_CR = US_CR_RSTRX | US_CR_RSTTX @@ -324,12 +323,13 @@ static const struct uart_driver_api usart_sam_driver_api = { }; #define USART_SAM_DECLARE_CFG(n, IRQ_FUNC_INIT) \ + PINCTRL_DT_INST_CONFIG_DEFINE(n); \ + \ static const struct usart_sam_dev_cfg usart##n##_sam_config = { \ .regs = (Usart *)DT_INST_REG_ADDR(n), \ .periph_id = DT_INST_PROP(n, peripheral_id), \ \ - .pin_rx = ATMEL_SAM_DT_INST_PIN(n, 0), \ - .pin_tx = ATMEL_SAM_DT_INST_PIN(n, 1), \ + .pincfg = PINCTRL_DT_INST_CONFIG_NAME(n), \ \ IRQ_FUNC_INIT \ } diff --git a/dts/arm/nordic/nrf_common.dtsi b/dts/arm/nordic/nrf_common.dtsi index 3a3ae156fe33d..39cdef203cdec 100644 --- a/dts/arm/nordic/nrf_common.dtsi +++ b/dts/arm/nordic/nrf_common.dtsi @@ -6,6 +6,7 @@ #include #include +#include #include /* @@ -23,3 +24,9 @@ */ status = "disabled"; }; + +/ { + pinctrl: pinctrl { + compatible = "nordic,nrf-pinctrl"; + }; +}; diff --git a/dts/bindings/pinctrl/nordic,nrf-pinctrl.yaml b/dts/bindings/pinctrl/nordic,nrf-pinctrl.yaml new file mode 100644 index 0000000000000..275e121b7a35c --- /dev/null +++ b/dts/bindings/pinctrl/nordic,nrf-pinctrl.yaml @@ -0,0 +1,16 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + nRF pin controller + +compatible: "nordic,nrf-pinctrl" + +include: base.yaml + +child-binding: + description: nRF pin controller pin configuration nodes. + properties: + pincfg: + required: true + type: array diff --git a/dts/bindings/pinctrl/pinctrl-device.yaml b/dts/bindings/pinctrl/pinctrl-device.yaml new file mode 100644 index 0000000000000..5fe76354d9094 --- /dev/null +++ b/dts/bindings/pinctrl/pinctrl-device.yaml @@ -0,0 +1,45 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + This file needs to be included by devices that need to specify a set of pin + controller states. The maximum number of supported states is 5 (pinctrl-0 ... + pinctrl-4) but it can be incremented if required. + + The bindings file for each pin controller driver implementation should provide + more information on what is the expected pin configuration format. + +properties: + pinctrl-0: + type: phandles + required: true + description: | + Pin configuration/s for the first state. Content is specific to the + selected pin controller driver implementation. + + pinctrl-1: + type: phandles + description: | + Pin configuration/s for the second state. See pinctrl-0. + + pinctrl-2: + type: phandles + description: | + Pin configuration/s for the third state. See pinctrl-0. + + pinctrl-3: + type: phandles + description: | + Pin configuration/s for the fourth state. See pinctrl-0. + + pinctrl-4: + type: phandles + description: | + Pin configuration/s for the fifth state. See pinctrl-0. + + pinctrl-names: + type: string-array + required: true + description: | + Names for the provided states. The length of names needs to match the + number of states. diff --git a/dts/bindings/serial/nordic,nrf-uart-common.yaml b/dts/bindings/serial/nordic,nrf-uart-common.yaml index 0c85fff21d187..148586a9168de 100644 --- a/dts/bindings/serial/nordic,nrf-uart-common.yaml +++ b/dts/bindings/serial/nordic,nrf-uart-common.yaml @@ -1,4 +1,4 @@ -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: @@ -7,42 +7,10 @@ properties: interrupts: required: true - tx-pin: - type: int - required: true - description: | - The TX pin to use. - - For pins P0.0 through P0.31, use the pin number. For example, - to use P0.16 for TX, set: - - tx-pin = <16>; - - For pins P1.0 through P1.31, add 32 to the pin number. For - example, to use P1.2 for TX, set: - - tx-pin = <34>; /* 32 + 2 */ - - rx-pin: - type: int - required: false - description: | - The RX pin to use. The pin numbering scheme is the same as the - tx-pin property's. - - rts-pin: - type: int - required: false - description: | - The RTS pin to use. The pin numbering scheme is the same as the - tx-pin property's. - - cts-pin: - type: int - required: false + disable-rx: + type: boolean description: | - The CTS pin to use. The pin numbering scheme is the same as the - tx-pin property's. + Disable UART reception capabilities. current-speed: description: | @@ -67,13 +35,3 @@ properties: - 460800 - 921600 - 1000000 - - rx-pull-up: - type: boolean - required: false - description: Enable pull-up resistor on the RX pin. - - cts-pull-up: - type: boolean - required: false - description: Enable pull-up resistor on the CTS pin. diff --git a/include/drivers/pinctrl.h b/include/drivers/pinctrl.h new file mode 100644 index 0000000000000..6d97cec674e82 --- /dev/null +++ b/include/drivers/pinctrl.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2021 Piotr Mienkowski + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public APIs for PINCTRL drivers + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief PINCTRL Driver APIs + * @defgroup pinctrl_interface PINCTRL Driver APIs + * @ingroup io_interfaces + * @{ + */ + +/** + * @typedef pinctrl_soc_pins_t + * + * @brief Provides a type to hold PINCTRL information specified in devicetree + * + * This type is sufficient to hold a PINCTRL device pointer, pin number, + * and the subset of the flags used to control PINCTRL configuration + * which may be given in devicetree. + */ + +struct pinctrl_state { + const pinctrl_soc_pins_t *pins; + size_t num_pins; +}; + +/** Pin controller configuration for a given device. */ +struct pinctrl_config { + /** List of states. */ + const struct pinctrl_state *states; + /** Number of states. */ + size_t states_cnt; +}; + +/** + * @brief Obtain the variable name storing pinctrl config for the given DT node + * identifier. + * + * @param node Node identifier. + */ + +/** + * @def PINCTRL_DT_SPEC_GET(node, n) + * + * @brief Static initializer for a @p pinctrl_dt_pin_spec + * + * This returns a static initializer for a @p pinctrl_dt_pin_spec structure + * given a devicetree node identifier and a state ID. + * + * Example devicetree fragment: + * + * nodelabel: node { + * pinctrl-0 = <&pincfg_a>, <&pincfg_b>, <&pincfg_c>; + * pinctrl-1 = <&pincfg_ax>, <&pincfg_bx>; + * } + * + * Example usage: + * + * const pinctrl_soc_pins_t spec[] = + * PINCTRL_DT_SPEC_GET(DT_NODELABEL(nodelabel), 0); + * + * It is an error to use this macro unless the node exists, has the given + * property, and that property specifies a list of valid phandles to pin + * configuration node. + * + * @param node devicetree node identifier + * @param n an integer id that corresponds to pinctrl-n property. + * @return static initializer for an array of `pinctrl_soc_pins_t` + */ + +/** + * @brief Configure a single pin from a @p pinctrl_dt_pin_spec. + * + * @param pin_spec Pin configuration obtained from the device tree. + * + * @retval 0 If successful. + */ +__syscall int pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec); + +int z_impl_pinctrl_pin_configure(const pinctrl_soc_pins_t *pin_spec); + +/** + * @brief Configure pin list from a @p pinctrl_dt_pin_spec array. + * + * @param pin_spec An array of pin spec elements obtained from the device tree. + * @param pin_spec_length number of elements in pin_spec array. + * + * @retval 0 If successful. + */ +static inline int pinctrl_pin_list_configure( + const pinctrl_soc_pins_t pin_spec[], + size_t pin_spec_length) +{ + int ret = 0; + + for (size_t i = 0; i < pin_spec_length; i++) { + ret = pinctrl_pin_configure(&pin_spec[i]); + if (ret != 0) { + break; + } + } + + return ret; +} + +static inline int pinctrl_set_pin_state(const struct pinctrl_state pins) +{ + return pinctrl_pin_list_configure(pins.pins, pins.num_pins); +} + +#define Z_PINCTRL_DT_PER_PIN(node, prop, idx) \ + PINCTRL_SOC_PINS_ELEM_INIT(DT_PROP_BY_IDX(node, prop, idx)) + +/* Allow soc_pinctrl.h to override Z_PINCTRL_DT_SPEC_GET */ +#ifndef Z_PINCTRL_DT_SPEC_GET +#define Z_PINCTRL_DT_SPEC_GET(node, n) \ +{ DT_FOREACH_PROP_ELEM(node, pinctrl_##n, Z_PINCTRL_DT_PER_PIN) } +#endif + +/* Name of form soc_pins__dts_ord_ */ +#define Z_PINCTRL_DT_SOC_PINS_NAME(pin_idx, node) \ + _CONCAT(soc_pins_, _CONCAT(pin_idx, DEVICE_DT_NAME_GET(node))) + +#define Z_PINCTRL_DT_SOC_PINS_DEFINE(pin_idx, node) \ +static const pinctrl_soc_pins_t Z_PINCTRL_DT_SOC_PINS_NAME(pin_idx, node)[] = \ + Z_PINCTRL_DT_SPEC_GET(node, pin_idx); + +#define Z_PINCTRL_DT_SOC_PINS_INIT(pin_idx, node) \ +{ \ + .num_pins = ARRAY_SIZE(Z_PINCTRL_DT_SOC_PINS_NAME(pin_idx, node)),\ + .pins = Z_PINCTRL_DT_SOC_PINS_NAME(pin_idx, node), \ +}, + +#define Z_PINCTRL_DT_STATES_NAME(node) \ + _CONCAT(__pinctrl_states, DEVICE_DT_NAME_GET(node)) + +#define Z_PINCTRL_DT_STATES_DEFINE(node) \ + UTIL_LISTIFY(DT_NUM_PINCTRL_STATES(node), \ + Z_PINCTRL_DT_SOC_PINS_DEFINE, node) \ + static const struct pinctrl_state \ + Z_PINCTRL_DT_STATES_NAME(node)[] = { \ + UTIL_LISTIFY(DT_NUM_PINCTRL_STATES(node), \ + Z_PINCTRL_DT_SOC_PINS_INIT, node) \ + } + +#define PINCTRL_DT_CONFIG_NAME(node) \ + _CONCAT(__pinctrl_config, DEVICE_DT_NAME_GET(node)) + +#define PINCTRL_DT_INST_CONFIG_NAME(inst) \ + PINCTRL_DT_CONFIG_NAME(DT_DRV_INST(inst)) + +#define PINCTRL_DT_CONFIG_DEFINE(node) \ + Z_PINCTRL_DT_STATES_DEFINE(node); \ + static const struct pinctrl_config PINCTRL_DT_CONFIG_NAME(node) = \ + { \ + .states = Z_PINCTRL_DT_STATES_NAME(node), \ + .states_cnt = DT_NUM_PINCTRL_STATES(node), \ + } + +#define PINCTRL_DT_INST_CONFIG_DEFINE(inst) \ + PINCTRL_DT_CONFIG_DEFINE(DT_DRV_INST(inst)) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_ */ diff --git a/include/drivers/pinctrl/nrf.h b/include/drivers/pinctrl/nrf.h new file mode 100644 index 0000000000000..4a4c256f13ce3 --- /dev/null +++ b/include/drivers/pinctrl/nrf.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Public APIs for pin control drivers + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_NRF_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_NRF_H_ + +/** + * @brief Pin Controller Interface (nRF) + * @defgroup pinctrl_interface_nrf Pin Controller Interface + * @ingroup pinctrl_interface + * @{ + */ + +#include +#include + +#include "states.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Pin control state for nRF. */ +struct pinctrl_state { + /** State identifier. */ + enum pinctrl_state_id id; + /** Pin configurations. */ + const uint32_t *pincfgs; + /** Number of pin configurations. */ + size_t pincfgs_cnt; +}; + +/** + * @brief Utility macro to obtain port and pin combination. + * + * @param pincfg Pin configuration bit field. + */ +#define PINCTRL_NRF_GET_PIN(pincfg) \ + (((pincfg) >> PINCTRL_NRF_PIN_POS) & PINCTRL_NRF_PIN_MSK) + +/** + * @brief Utility macro to obtain pin direction. + * + * @param pincfg Pin configuration bit field. + */ +#define PINCTRL_NRF_GET_DIR(pincfg) \ + (((pincfg) >> PINCTRL_NRF_DIR_POS) & PINCTRL_NRF_DIR_MSK) + +/** + * @brief Utility macro to obtain input buffer configuration. + * + * @param pincfg Pin configuration bit field. + */ +#define PINCTRL_NRF_GET_INP(pincfg) \ + (((pincfg) >> PINCTRL_NRF_INP_POS) & PINCTRL_NRF_INP_MSK) + +/** + * @brief Utility macro to obtain pin pull configuration. + * + * @param pincfg Pin configuration bit field. + */ +#define PINCTRL_NRF_GET_PULL(pincfg) \ + (((pincfg) >> PINCTRL_NRF_PULL_POS) & PINCTRL_NRF_PULL_MSK) + +/** + * @brief Utility macro to obtain pin function. + * + * @param pincfg Pin configuration bit field. + */ +#define PINCTRL_NRF_GET_FUN(pincfg) \ + (((pincfg) >> PINCTRL_NRF_FUN_POS) & PINCTRL_NRF_FUN_MSK) + +/** + * @brief Obtain the variable name storing the state information for the given + * state index and DT node identifier. + * + * @param state_idx State index. + * @param node_id Node identifier. + */ +#define Z_PINCTRL_STATE_NAME(state_idx, node_id) \ + _CONCAT(__pinctrl_ ## state_idx, DEVICE_DT_NAME_GET(node_id)) + +/** + * @brief Helper macro to define a pin control state. + * + * @param state_idx State index. + * @param node_id Node identifier. + */ +#define Z_PINCTRL_STATE_DEFINE(state_idx, node_id) \ + COND_CODE_1(DT_PINCTRL_HAS_IDX(node_id, state_idx), \ + (static const struct pinctrl_state \ + Z_PINCTRL_STATE_NAME(state_idx, node_id) = { \ + .id = Z_PINCTRL_STATE_ID(state_idx, node_id), \ + .pincfgs = (const uint32_t[])DT_PROP( \ + DT_PINCTRL_BY_IDX(node_id, state_idx, 0), pincfg), \ + .pincfgs_cnt = DT_PROP_LEN( \ + DT_PINCTRL_BY_IDX(node_id, state_idx, 0), pincfg), \ + };), ()) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_PINCTRL_NRF_H_ */ diff --git a/include/dt-bindings/pinctrl/nrf-pinctrl.h b/include/dt-bindings/pinctrl/nrf-pinctrl.h new file mode 100644 index 0000000000000..8b4ab393e3201 --- /dev/null +++ b/include/dt-bindings/pinctrl/nrf-pinctrl.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_NRF_PINCTRL_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_NRF_PINCTRL_H_ + +/** + * @name nRF pinctrl pin functions. + * @{ + */ +#define PINCTRL_NRF_FUN_UART_TX 0U +#define PINCTRL_NRF_FUN_UART_RX 1U +#define PINCTRL_NRF_FUN_UART_RTS 2U +#define PINCTRL_NRF_FUN_UART_CTS 3U +/** @} */ + +/** + * @name nRF pinctrl pin direction. + * @note Values match nrf_gpio_pin_dir_t. + * @{ + */ +/** Input. */ +#define PINCTRL_NRF_DIR_INP 0 +/** Output. */ +#define PINCTRL_NRF_DIR_OUT 1 +/** @} */ + +/** + * @name nRF pinctrl input buffer. + * @note Values match nrf_gpio_pin_input_t. + * @{ + */ +/** Connect input */ +#define PINCTRL_NRF_INP_ICONN 0 +/** Disconnect input */ +#define PINCTRL_NRF_INP_IDISC 1 +/** @} */ + +/** + * @name nRF pinctrl pull-up/down. + * @note Values match nrf_gpio_pin_pull_t. + * @{ + */ +/** Pull-up disabled. */ +#define PINCTRL_NRF_PULL_PN 0 +/** Pull-down enabled. */ +#define PINCTRL_NRF_PULL_PD 1 +/** Pull-up enabled. */ +#define PINCTRL_NRF_PULL_PU 2 +/** @} */ + +/** + * @name Positions and masks for the pincfg bit field. + * @{ + */ +#define PINCTRL_NRF_PIN_POS 0U +#define PINCTRL_NRF_PIN_MSK 0x3FU +#define PINCTRL_NRF_DIR_POS 6U +#define PINCTRL_NRF_DIR_MSK 0x1U +#define PINCTRL_NRF_INP_POS 7U +#define PINCTRL_NRF_INP_MSK 0x1U +#define PINCTRL_NRF_PULL_POS 8U +#define PINCTRL_NRF_PULL_MSK 0x3U +#define PINCTRL_NRF_FUN_POS 16U +#define PINCTRL_NRF_FUN_MSK 0xFFFFU +/** @} */ + +/** + * @brief Utility macro to build nRF pinctrl configuration entry for a pin. + * + * The information is encoded in a bitfield organized as follows: + * + * - 31..16: Pin function. + * - 15..10: Reserved. + * - 9..8: Pin pull configuration. + * - 7: Pin input buffer configuration. + * - 6: Pin direction. + * - 5..0: Pin number (combination of port and pin). + * + * @param port Port (0 or 1). + * @param pin Pin (0..32). + * @param dir Pin direction configuration. + * @param inp Pin input buffer configuration. + * @param pull Pin pull configuration. + * @param fun Pin function configuration. + */ +#define PINCTRL_NRF(port, pin, dir, inp, pull, fun) \ + ((((((port) * 32U) + (pin)) & PINCTRL_NRF_PIN_MSK) << PINCTRL_NRF_PIN_POS) | \ + (((PINCTRL_NRF_DIR_ ## dir) & PINCTRL_NRF_DIR_MSK) << PINCTRL_NRF_DIR_POS) | \ + (((PINCTRL_NRF_INP_ ## inp) & PINCTRL_NRF_INP_MSK) << PINCTRL_NRF_INP_POS) | \ + (((PINCTRL_NRF_PULL_ ## pull) & PINCTRL_NRF_PULL_MSK) << PINCTRL_NRF_PULL_POS) | \ + (((PINCTRL_NRF_FUN_ ## fun) & PINCTRL_NRF_FUN_MSK) << PINCTRL_NRF_FUN_POS)) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_NRF_PINCTRL_H_ */ diff --git a/soc/arm/atmel_sam/common/soc_pinctrl.h b/soc/arm/atmel_sam/common/soc_pinctrl.h new file mode 100644 index 0000000000000..355ea35f52810 --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_pinctrl.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Piotr Mienkowski + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Atmel SAM MCU family Pin Controller macros. + */ + +#ifndef ATMEL_SAM_SOC_PINCTRL_H_ +#define ATMEL_SAM_SOC_PINCTRL_H_ + +#include +#include + +typedef struct soc_gpio_pin pinctrl_soc_pins_t; + +#if defined(CONFIG_SOC_SERIES_SAM4L) +#define ATMEL_PIO_TYPE Gpio +#else +#define ATMEL_PIO_TYPE Pio +#endif + +#define PINCTRL_SOC_PINS_ELEM_INIT(node_id) \ +{ \ + .mask = 1 << DT_PHA(node_id, atmel_pins, pin), \ + .regs = (ATMEL_PIO_TYPE *)DT_REG_ADDR(DT_PHANDLE(node_id, atmel_pins)), \ + .periph_id = DT_PHA(node_id, atmel_pins, peripheral), \ + .flags = DT_PHA(node_id, atmel_pins, peripheral) << SOC_GPIO_FUNC_POS | \ + DT_PROP(node_id, bias_pull_up) << SOC_GPIO_PULLUP_POS | \ + DT_PROP(node_id, bias_pull_down) << SOC_GPIO_PULLUP_POS | \ + DT_PROP(node_id, drive_open_drain) << SOC_GPIO_OPENDRAIN_POS \ +}, + +#endif /* ATMEL_SAM_SOC_PINCTRL_H_ */ diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 14e9bba101e41..3000cdd796891 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -3,6 +3,9 @@ add_subdirectory(${SOC_SERIES}) add_subdirectory(common) +# This is for access to pinmux macros +zephyr_include_directories(common) + zephyr_sources( validate_base_addresses.c validate_enabled_instances.c diff --git a/soc/arm/nordic_nrf/common/soc_pinctrl.h b/soc/arm/nordic_nrf/common/soc_pinctrl.h new file mode 100644 index 0000000000000..e89865de8b5bd --- /dev/null +++ b/soc/arm/nordic_nrf/common/soc_pinctrl.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SOC_NRF_KINETIS_SOC_PINCTRL_H_ +#define SOC_NRF_KINETIS_SOC_PINCTRL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t pinctrl_soc_pins_t; + +#define PINCTRL_SOC_PINS_ELEM_INIT(node, prop, idx) \ +DT_PROP_BY_IDX(node, prop, idx), + +#define Z_PINCTRL_DT_SPEC_GET(node, pin_indx) \ +{ DT_FOREACH_PROP_ELEM(DT_PROP_BY_IDX(node, pinctrl_##pin_indx, 0), pincfg, PINCTRL_SOC_PINS_ELEM_INIT) } + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_NRF_KINETIS_SOC_PINCTRL_H_ */ diff --git a/soc/arm/nxp_kinetis/CMakeLists.txt b/soc/arm/nxp_kinetis/CMakeLists.txt index 64b24a7cd1bb0..1db1ea6b6bc89 100644 --- a/soc/arm/nxp_kinetis/CMakeLists.txt +++ b/soc/arm/nxp_kinetis/CMakeLists.txt @@ -4,6 +4,9 @@ zephyr_sources_ifdef(CONFIG_KINETIS_FLASH_CONFIG flash_configuration.c) add_subdirectory(${SOC_SERIES}) +# This is for access to pinmux macros +zephyr_include_directories(common) + zephyr_linker_sources_ifdef(CONFIG_KINETIS_FLASH_CONFIG ROM_START SORT_KEY ${CONFIG_KINETIS_FLASH_CONFIG_OFFSET} diff --git a/soc/arm/nxp_kinetis/common/soc_pinctrl.h b/soc/arm/nxp_kinetis/common/soc_pinctrl.h new file mode 100644 index 0000000000000..5f1f80a5525b0 --- /dev/null +++ b/soc/arm/nxp_kinetis/common/soc_pinctrl.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef SOC_NXP_KINETIS_SOC_PINCTRL_H_ +#define SOC_NXP_KINETIS_SOC_PINCTRL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct nxp_kinetis_pinctrl { + const struct device *port; + uint8_t pin; + uint8_t mux; +}; + +typedef struct nxp_kinetis_pinctrl pinctrl_soc_pins_t; + +#define PINCTRL_SOC_PINS_ELEM_INIT(node) \ +{ \ + .port = DEVICE_DT_GET(DT_PARENT(node)), \ + .pin = DT_PROP_BY_IDX(node, nxp_kinetis_port_pins, 0), \ + .mux = DT_PROP_BY_IDX(node, nxp_kinetis_port_pins, 1), \ +}, + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_NXP_KINETIS_SOC_PINCTRL_H_ */