From 035aa45038e5bd464acaee28dba7faf380735fcf Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Tue, 1 Jun 2021 11:38:21 +0200 Subject: [PATCH 1/7] soc: atmel_sam: Add _INST to ATMEL_SAM_DT_PIN* macros The macros are used to get the pin(s) of a given driver instance. Add _INST prefix to match convention used by the devicetree.h. The original macros can now be used to obtain pin(s) of an arbitrary device instance identified by the nodelabel. Signed-off-by: Piotr Mienkowski --- drivers/adc/adc_sam_afec.c | 2 +- drivers/ethernet/eth_sam_gmac.c | 2 +- drivers/i2c/i2c_sam4l_twim.c | 3 +- drivers/i2c/i2c_sam_twi.c | 3 +- drivers/i2c/i2c_sam_twihs.c | 3 +- drivers/i2s/i2s_sam_ssc.c | 2 +- drivers/sensor/qdec_sam/qdec_sam.c | 2 +- drivers/serial/uart_sam.c | 4 +- drivers/serial/usart_sam.c | 4 +- drivers/spi/spi_sam.c | 4 +- soc/arm/atmel_sam/common/atmel_sam_dt.h | 90 ++++++++++++++----------- 11 files changed, 65 insertions(+), 54 deletions(-) diff --git a/drivers/adc/adc_sam_afec.c b/drivers/adc/adc_sam_afec.c index cecec1e377af0..67dbc51580ce0 100644 --- a/drivers/adc/adc_sam_afec.c +++ b/drivers/adc/adc_sam_afec.c @@ -356,7 +356,7 @@ static void adc_sam_isr(const struct device *dev) .regs = (Afec *)DT_INST_REG_ADDR(n), \ .cfg_func = adc##n##_sam_cfg_func, \ .periph_id = DT_INST_PROP(n, peripheral_id), \ - .afec_trg_pin = ATMEL_SAM_DT_PIN(n, 0), \ + .afec_trg_pin = ATMEL_SAM_DT_INST_PIN(n, 0), \ }; \ \ static struct adc_sam_data adc##n##_sam_data = { \ diff --git a/drivers/ethernet/eth_sam_gmac.c b/drivers/ethernet/eth_sam_gmac.c index 7c792a2bf7807..71e097d5816c9 100644 --- a/drivers/ethernet/eth_sam_gmac.c +++ b/drivers/ethernet/eth_sam_gmac.c @@ -2214,7 +2214,7 @@ static void eth0_irq_config(void) } #ifdef CONFIG_SOC_FAMILY_SAM -static const struct soc_gpio_pin pins_eth0[] = ATMEL_SAM_DT_PINS(0); +static const struct soc_gpio_pin pins_eth0[] = ATMEL_SAM_DT_INST_PINS(0); #endif static const struct eth_sam_dev_cfg eth0_config = { diff --git a/drivers/i2c/i2c_sam4l_twim.c b/drivers/i2c/i2c_sam4l_twim.c index 2443241f613dd..ce3e940989d20 100644 --- a/drivers/i2c/i2c_sam4l_twim.c +++ b/drivers/i2c/i2c_sam4l_twim.c @@ -614,8 +614,7 @@ static const struct i2c_driver_api i2c_sam_twim_driver_api = { DEVICE_DT_INST_GET(n), 0); \ } \ \ - static const struct soc_gpio_pin pins_twim##n[] = \ - {ATMEL_SAM_DT_PIN(n, 0), ATMEL_SAM_DT_PIN(n, 1)}; \ + static const struct soc_gpio_pin pins_twim##n[] = ATMEL_SAM_DT_INST_PINS(n); \ \ static const struct i2c_sam_twim_dev_cfg i2c##n##_sam_config = {\ .regs = (Twim *)DT_INST_REG_ADDR(n), \ diff --git a/drivers/i2c/i2c_sam_twi.c b/drivers/i2c/i2c_sam_twi.c index 99533cf3c7835..bdc414830cb04 100644 --- a/drivers/i2c/i2c_sam_twi.c +++ b/drivers/i2c/i2c_sam_twi.c @@ -346,8 +346,7 @@ static const struct i2c_driver_api i2c_sam_twi_driver_api = { DEVICE_DT_INST_GET(n), 0); \ } \ \ - static const struct soc_gpio_pin pins_twi##n[] = \ - {ATMEL_SAM_DT_PIN(n, 0), ATMEL_SAM_DT_PIN(n, 1)}; \ + static const struct soc_gpio_pin pins_twi##n[] = ATMEL_SAM_DT_INST_PINS(n); \ \ static const struct i2c_sam_twi_dev_cfg i2c##n##_sam_config = { \ .regs = (Twi *)DT_INST_REG_ADDR(n), \ diff --git a/drivers/i2c/i2c_sam_twihs.c b/drivers/i2c/i2c_sam_twihs.c index f41c10848da13..a997dd7708f89 100644 --- a/drivers/i2c/i2c_sam_twihs.c +++ b/drivers/i2c/i2c_sam_twihs.c @@ -333,8 +333,7 @@ static const struct i2c_driver_api i2c_sam_twihs_driver_api = { DEVICE_DT_INST_GET(n), 0); \ } \ \ - static const struct soc_gpio_pin pins_twihs##n[] = \ - {ATMEL_SAM_DT_PIN(n, 0), ATMEL_SAM_DT_PIN(n, 1)}; \ + static const struct soc_gpio_pin pins_twihs##n[] = ATMEL_SAM_DT_INST_PINS(n); \ \ static const struct i2c_sam_twihs_dev_cfg i2c##n##_sam_config = {\ .regs = (Twihs *)DT_INST_REG_ADDR(n), \ diff --git a/drivers/i2s/i2s_sam_ssc.c b/drivers/i2s/i2s_sam_ssc.c index 8ca18148a7dc3..2cde7f7f1b9df 100644 --- a/drivers/i2s/i2s_sam_ssc.c +++ b/drivers/i2s/i2s_sam_ssc.c @@ -976,7 +976,7 @@ static void i2s0_sam_irq_config(void) DEVICE_DT_INST_GET(0), 0); } -static const struct soc_gpio_pin i2s0_pins[] = ATMEL_SAM_DT_PINS(0); +static const struct soc_gpio_pin i2s0_pins[] = ATMEL_SAM_DT_INST_PINS(0); static const struct i2s_sam_dev_cfg i2s0_sam_config = { .dev_dma = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(0, tx)), diff --git a/drivers/sensor/qdec_sam/qdec_sam.c b/drivers/sensor/qdec_sam/qdec_sam.c index 007778c51bdcc..97f381d1c88a5 100644 --- a/drivers/sensor/qdec_sam/qdec_sam.c +++ b/drivers/sensor/qdec_sam/qdec_sam.c @@ -123,7 +123,7 @@ static const struct sensor_driver_api qdec_sam_driver_api = { }; #define QDEC_SAM_INIT(n) \ - static const struct soc_gpio_pin pins_tc##n[] = ATMEL_SAM_DT_PINS(n); \ + static const struct soc_gpio_pin pins_tc##n[] = ATMEL_SAM_DT_INST_PINS(n); \ \ static const struct qdec_sam_dev_cfg qdec##n##_sam_config = { \ .regs = (Tc *)DT_INST_REG_ADDR(n), \ diff --git a/drivers/serial/uart_sam.c b/drivers/serial/uart_sam.c index f0eba1d725e60..d7250f3bbd3c2 100644 --- a/drivers/serial/uart_sam.c +++ b/drivers/serial/uart_sam.c @@ -327,8 +327,8 @@ static const struct uart_driver_api uart_sam_driver_api = { .regs = (Uart *)DT_INST_REG_ADDR(n), \ .periph_id = DT_INST_PROP(n, peripheral_id), \ \ - .pin_rx = ATMEL_SAM_DT_PIN(n, 0), \ - .pin_tx = ATMEL_SAM_DT_PIN(n, 1), \ + .pin_rx = ATMEL_SAM_DT_INST_PIN(n, 0), \ + .pin_tx = ATMEL_SAM_DT_INST_PIN(n, 1), \ \ IRQ_FUNC_INIT \ } diff --git a/drivers/serial/usart_sam.c b/drivers/serial/usart_sam.c index df48e89127475..63e4267388ba2 100644 --- a/drivers/serial/usart_sam.c +++ b/drivers/serial/usart_sam.c @@ -328,8 +328,8 @@ static const struct uart_driver_api usart_sam_driver_api = { .regs = (Usart *)DT_INST_REG_ADDR(n), \ .periph_id = DT_INST_PROP(n, peripheral_id), \ \ - .pin_rx = ATMEL_SAM_DT_PIN(n, 0), \ - .pin_tx = ATMEL_SAM_DT_PIN(n, 1), \ + .pin_rx = ATMEL_SAM_DT_INST_PIN(n, 0), \ + .pin_tx = ATMEL_SAM_DT_INST_PIN(n, 1), \ \ IRQ_FUNC_INIT \ } diff --git a/drivers/spi/spi_sam.c b/drivers/spi/spi_sam.c index 8b440f06d78fa..2d87c7c1fed66 100644 --- a/drivers/spi/spi_sam.c +++ b/drivers/spi/spi_sam.c @@ -457,8 +457,8 @@ static const struct spi_driver_api spi_sam_driver_api = { static const struct spi_sam_config spi_sam_config_##n = { \ .regs = (Spi *)DT_INST_REG_ADDR(n), \ .periph_id = DT_INST_PROP(n, peripheral_id), \ - .num_pins = ATMEL_SAM_DT_NUM_PINS(n), \ - .pins = ATMEL_SAM_DT_PINS(n), \ + .num_pins = ATMEL_SAM_DT_INST_NUM_PINS(n), \ + .pins = ATMEL_SAM_DT_INST_PINS(n), \ } #define SPI_SAM_DEVICE_INIT(n) \ diff --git a/soc/arm/atmel_sam/common/atmel_sam_dt.h b/soc/arm/atmel_sam/common/atmel_sam_dt.h index bfdc7fa2b4fd6..2ffa46356845a 100644 --- a/soc/arm/atmel_sam/common/atmel_sam_dt.h +++ b/soc/arm/atmel_sam/common/atmel_sam_dt.h @@ -16,74 +16,88 @@ /* Devicetree related macros to construct pin mux config data */ /* Get a node id from a pinctrl-0 prop at index 'i' */ -#define NODE_ID_FROM_PINCTRL_0(inst, i) \ - DT_INST_PHANDLE_BY_IDX(inst, pinctrl_0, i) +#define NODE_ID_FROM_PINCTRL_0(node_id, i) \ + DT_PHANDLE_BY_IDX(node_id, pinctrl_0, i) /* Get PIN associated with pinctrl-0 pin at index 'i' */ -#define ATMEL_SAM_PIN(inst, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(inst, i), atmel_pins, pin) +#define ATMEL_SAM_PIN(node_id, i) \ + DT_PHA(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins, pin) /* Get PIO register address associated with pinctrl-0 pin at index 'i' */ -#define ATMEL_SAM_PIN_TO_PIO_REG_ADDR(inst, i) \ - DT_REG_ADDR(DT_PHANDLE(NODE_ID_FROM_PINCTRL_0(inst, i), atmel_pins)) +#define ATMEL_SAM_PIN_TO_PIO_REG_ADDR(node_id, i) \ + DT_REG_ADDR(DT_PHANDLE(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins)) /* Get peripheral id for PIO associated with pinctrl-0 pin at index 'i' */ -#define ATMEL_SAM_PIN_2_PIO_PERIPH_ID(inst, i) \ - DT_PROP_BY_PHANDLE(NODE_ID_FROM_PINCTRL_0(inst, i),\ +#define ATMEL_SAM_PIN_2_PIO_PERIPH_ID(node_id, i) \ + DT_PROP_BY_PHANDLE(NODE_ID_FROM_PINCTRL_0(node_id, i),\ atmel_pins, peripheral_id) /* Get peripheral cfg associated wiith pinctrl-0 pin at index 'i' */ -#define ATMEL_SAM_PIN_PERIPH(inst, i) \ - DT_PHA(NODE_ID_FROM_PINCTRL_0(inst, i), atmel_pins, peripheral) +#define ATMEL_SAM_PIN_PERIPH(node_id, i) \ + DT_PHA(NODE_ID_FROM_PINCTRL_0(node_id, i), atmel_pins, peripheral) /* Helper function for ATMEL_SAM_PIN_FLAGS */ -#define ATMEL_SAM_PIN_FLAG(inst, i, flag) \ - DT_PROP(NODE_ID_FROM_PINCTRL_0(inst, i), flag) +#define ATMEL_SAM_PIN_FLAG(node_id, i, flag) \ + DT_PROP(NODE_ID_FROM_PINCTRL_0(node_id, i), flag) /* Convert DT flags to SoC flags */ -#define ATMEL_SAM_PIN_FLAGS(inst, i) \ - (ATMEL_SAM_PIN_FLAG(inst, i, bias_pull_up) << SOC_GPIO_PULLUP_POS | \ - ATMEL_SAM_PIN_FLAG(inst, i, bias_pull_down) << SOC_GPIO_PULLUP_POS | \ - ATMEL_SAM_PIN_FLAG(inst, i, drive_open_drain) << SOC_GPIO_OPENDRAIN_POS) - -/* Construct a soc_pio_pin element for pin cfg */ -#define ATMEL_SAM_DT_PIO(inst, idx) \ - { \ - 1 << ATMEL_SAM_PIN(inst, idx), \ - (Pio *)ATMEL_SAM_PIN_TO_PIO_REG_ADDR(inst, idx), \ - ATMEL_SAM_PIN_2_PIO_PERIPH_ID(inst, idx), \ - ATMEL_SAM_PIN_PERIPH(inst, idx) << SOC_GPIO_FUNC_POS | \ - ATMEL_SAM_PIN_FLAGS(inst, idx) \ - } +#define ATMEL_SAM_PIN_FLAGS(node_id, i) \ + (ATMEL_SAM_PIN_FLAG(node_id, i, bias_pull_up) << SOC_GPIO_PULLUP_POS | \ + ATMEL_SAM_PIN_FLAG(node_id, i, bias_pull_down) << SOC_GPIO_PULLUP_POS | \ + ATMEL_SAM_PIN_FLAG(node_id, i, drive_open_drain) << SOC_GPIO_OPENDRAIN_POS) +#if defined(CONFIG_SOC_SERIES_SAM4L) /* Construct a soc_gpio_pin element for pin cfg */ -#define ATMEL_SAM_DT_GPIO(inst, idx) \ +#define ATMEL_SAM_DT_GPIO(node_id, idx) \ { \ - 1 << ATMEL_SAM_PIN(inst, idx), \ - (Gpio *)ATMEL_SAM_PIN_TO_PIO_REG_ADDR(inst, idx), \ - ATMEL_SAM_PIN_2_PIO_PERIPH_ID(inst, idx), \ - ATMEL_SAM_PIN_PERIPH(inst, idx) << SOC_GPIO_FUNC_POS | \ - ATMEL_SAM_PIN_FLAGS(inst, idx) \ + 1 << ATMEL_SAM_PIN(node_id, idx), \ + (Gpio *)ATMEL_SAM_PIN_TO_PIO_REG_ADDR(node_id, idx), \ + ATMEL_SAM_PIN_2_PIO_PERIPH_ID(node_id, idx), \ + ATMEL_SAM_PIN_PERIPH(node_id, idx) << SOC_GPIO_FUNC_POS | \ + ATMEL_SAM_PIN_FLAGS(node_id, idx) \ } -#if defined(CONFIG_SOC_SERIES_SAM4L) +#define ATMEL_SAM_DT_INST_GPIO(inst, idx) \ + ATMEL_SAM_DT_GPIO(DT_DRV_INST(inst), idx) + #define ATMEL_SAM_DT_PIN ATMEL_SAM_DT_GPIO +#define ATMEL_SAM_DT_INST_PIN ATMEL_SAM_DT_INST_GPIO #else +/* Construct a soc_pio_pin element for pin cfg */ +#define ATMEL_SAM_DT_PIO(node_id, idx) \ + { \ + 1 << ATMEL_SAM_PIN(node_id, idx), \ + (Pio *)ATMEL_SAM_PIN_TO_PIO_REG_ADDR(node_id, idx), \ + ATMEL_SAM_PIN_2_PIO_PERIPH_ID(node_id, idx), \ + ATMEL_SAM_PIN_PERIPH(node_id, idx) << SOC_GPIO_FUNC_POS | \ + ATMEL_SAM_PIN_FLAGS(node_id, idx) \ + } + +#define ATMEL_SAM_DT_INST_PIO(inst, idx) \ + ATMEL_SAM_DT_PIO(DT_DRV_INST(inst), idx) + #define ATMEL_SAM_DT_PIN ATMEL_SAM_DT_PIO +#define ATMEL_SAM_DT_INST_PIN ATMEL_SAM_DT_INST_PIO #endif /* Get the number of pins for pinctrl-0 */ -#define ATMEL_SAM_DT_NUM_PINS(inst) DT_INST_PROP_LEN(inst, pinctrl_0) +#define ATMEL_SAM_DT_NUM_PINS(node_id) DT_PROP_LEN(node_id, pinctrl_0) + +#define ATMEL_SAM_DT_INST_NUM_PINS(inst) \ + ATMEL_SAM_DT_NUM_PINS(DT_DRV_INST(inst)) /* internal macro to structure things for use with UTIL_LISTIFY */ -#define ATMEL_SAM_DT_PIN_ELEM(idx, inst) ATMEL_SAM_DT_PIN(inst, idx), +#define ATMEL_SAM_DT_PIN_ELEM(idx, node_id) ATMEL_SAM_DT_PIN(node_id, idx), /* Construct an array intializer for soc_gpio_pin for a device instance */ -#define ATMEL_SAM_DT_PINS(inst) \ - { UTIL_LISTIFY(ATMEL_SAM_DT_NUM_PINS(inst), \ - ATMEL_SAM_DT_PIN_ELEM, inst) \ +#define ATMEL_SAM_DT_PINS(node_id) \ + { UTIL_LISTIFY(ATMEL_SAM_DT_NUM_PINS(node_id), \ + ATMEL_SAM_DT_PIN_ELEM, node_id) \ } +#define ATMEL_SAM_DT_INST_PINS(inst) \ + ATMEL_SAM_DT_PINS(DT_DRV_INST(inst)) + /* Devicetree macros related to clock */ #define ATMEL_SAM_DT_CPU_CLK_FREQ_HZ \ From 21fe6656f7329db26a97f32726360805f72817ce Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Tue, 1 Jun 2021 16:02:29 +0200 Subject: [PATCH 2/7] api: Add pinctlr driver API Signed-off-by: Piotr Mienkowski --- include/drivers/pinctrl.h | 114 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 include/drivers/pinctrl.h diff --git a/include/drivers/pinctrl.h b/include/drivers/pinctrl.h new file mode 100644 index 0000000000000..2fcef97d01a21 --- /dev/null +++ b/include/drivers/pinctrl.h @@ -0,0 +1,114 @@ +/* + * 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_dt_pin_spec_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. + */ + +/** + * @def PINCTRL_DT_SPEC_GET(node_id, 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_dt_pin_spec_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_id devicetree node identifier + * @param n an integer id that corresponds to pinctrl-n property. + * @return static initializer for an array of `pinctrl_dt_pin_spec_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_dt_pin_spec_t *pin_spec); + +int z_impl_pinctrl_pin_configure(const pinctrl_dt_pin_spec_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_dt_pin_spec_t pin_spec[], + unsigned int pin_spec_length) +{ + int ret = 0; + + for (int i = 0; i < pin_spec_length; i++) { + ret = pinctrl_pin_configure(&pin_spec[i]); + if (ret != 0) { + break; + } + } + + return ret; +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PINCTRL_H_ */ From 5588d5f9408fb450dd043f28fc2dfa87bbeada9b Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Tue, 1 Jun 2021 16:04:26 +0200 Subject: [PATCH 3/7] drivers: Add pinctrl_sam driver Add pinctrl_sam driver and required infrastructure. Signed-off-by: Piotr Mienkowski --- drivers/CMakeLists.txt | 1 + drivers/Kconfig | 2 ++ drivers/pinctrl/CMakeLists.txt | 6 ++++++ drivers/pinctrl/Kconfig | 27 ++++++++++++++++++++++++++ drivers/pinctrl/pinctrl_handlers.c | 16 +++++++++++++++ drivers/pinctrl/pinctrl_sam.c | 15 ++++++++++++++ soc/arm/atmel_sam/common/soc_pinctrl.h | 22 +++++++++++++++++++++ 7 files changed, 89 insertions(+) create mode 100644 drivers/pinctrl/CMakeLists.txt create mode 100644 drivers/pinctrl/Kconfig create mode 100644 drivers/pinctrl/pinctrl_handlers.c create mode 100644 drivers/pinctrl/pinctrl_sam.c create mode 100644 soc/arm/atmel_sam/common/soc_pinctrl.h diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 483895f2266ff..b75d239a8caf1 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -24,6 +24,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 546a3aaaa4467..319fb71d81730 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -43,6 +43,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..45c1d354c5ffe --- /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_STM32 pinctrl_stm32.c) +zephyr_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig new file mode 100644 index 0000000000000..db3ebde5fb3c8 --- /dev/null +++ b/drivers/pinctrl/Kconfig @@ -0,0 +1,27 @@ +# HW Info driver 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_STM32 + bool "STM32 pinctrl" + default y + depends on SOC_FAMILY_STM32 + help + Enable STM32 pinctrl driver. + +config PINCTRL_SAM + bool "Atmel SAM device ID" + default y + depends on SOC_FAMILY_SAM + help + Enable Atmel SAM pinctrl driver. + +endif diff --git a/drivers/pinctrl/pinctrl_handlers.c b/drivers/pinctrl/pinctrl_handlers.c new file mode 100644 index 0000000000000..63408032511f6 --- /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_dt_pin_spec_t *pin_spec) +{ + Z_SYSCALL_MEMORY_READ(pin_spec, sizeof(pinctrl_dt_pin_spec_t)); + + return z_impl_pinctrl_pin_configure((const struct pinctrl_dt_pin_spec *)pin_spec); +} +#include diff --git a/drivers/pinctrl/pinctrl_sam.c b/drivers/pinctrl/pinctrl_sam.c new file mode 100644 index 0000000000000..081d741e3ad49 --- /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_dt_pin_spec_t *pin_spec) +{ + soc_gpio_configure((const struct soc_gpio_pin *)pin_spec); + + return 0; +} 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..391d0daf55497 --- /dev/null +++ b/soc/arm/atmel_sam/common/soc_pinctrl.h @@ -0,0 +1,22 @@ +/* + * 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_dt_pin_spec_t; + +/* TODO Add support for n parameter */ +#define PINCTRL_DT_SPEC_GET(node_id, n) \ + ATMEL_SAM_DT_PINS(node_id) + +#endif /* ATMEL_SAM_SOC_PINCTRL_H_ */ From bd244a33a75c61d45ae991190e9739ea00809a74 Mon Sep 17 00:00:00 2001 From: Piotr Mienkowski Date: Tue, 1 Jun 2021 16:05:28 +0200 Subject: [PATCH 4/7] pinctrl: update usart_sam driver to use new API Signed-off-by: Piotr Mienkowski --- drivers/serial/Kconfig.usart_sam | 1 + drivers/serial/usart_sam.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) 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/usart_sam.c b/drivers/serial/usart_sam.c index 63e4267388ba2..6a846fead9625 100644 --- a/drivers/serial/usart_sam.c +++ b/drivers/serial/usart_sam.c @@ -20,13 +20,14 @@ #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; + unsigned int num_pins; + const pinctrl_dt_pin_spec_t *pins; #ifdef CONFIG_UART_INTERRUPT_DRIVEN uart_irq_config_func_t irq_config_func; @@ -64,8 +65,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_pin_list_configure(cfg->pins, cfg->num_pins); /* Reset and disable USART */ usart->US_CR = US_CR_RSTRX | US_CR_RSTTX @@ -324,12 +324,15 @@ static const struct uart_driver_api usart_sam_driver_api = { }; #define USART_SAM_DECLARE_CFG(n, IRQ_FUNC_INIT) \ + static const pinctrl_dt_pin_spec_t pins_usart##n[] = \ + PINCTRL_DT_SPEC_GET(DT_DRV_INST(n), 0); \ + \ 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), \ + .pins = pins_usart##n, \ + .num_pins = ARRAY_SIZE(pins_usart##n), \ \ IRQ_FUNC_INIT \ } From 52605a1a7fc54cfaa9686d4ebe90e3c000f863be Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 31 Mar 2021 09:50:46 -0500 Subject: [PATCH 5/7] pinmux: mcux: Add support for ... Signed-off-by: Kumar Gala --- drivers/pinmux/pinmux_mcux.c | 8 ++++ soc/arm/nxp_kinetis/CMakeLists.txt | 3 ++ soc/arm/nxp_kinetis/common/soc_pinctrl.h | 47 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 soc/arm/nxp_kinetis/common/soc_pinctrl.h diff --git a/drivers/pinmux/pinmux_mcux.c b/drivers/pinmux/pinmux_mcux.c index e4754578dab18..d5fea668d5aae 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_dt_pin_spec_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/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..ed982a28a150b --- /dev/null +++ b/soc/arm/nxp_kinetis/common/soc_pinctrl.h @@ -0,0 +1,47 @@ +/* + * 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_dt_pin_spec_t; + +#define NXP_KINETIS_PIN(i, node, n) \ + DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(node, pinctrl_##n, i), nxp_kinetis_port_pins, 0) + +#define NXP_KINETIS_MUX(i, node, n) \ + DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(node, pinctrl_##n, i), nxp_kinetis_port_pins, 1) + +#define NXP_KINETIS_GET_PORT_DEV(i, node, n) \ + DEVICE_DT_GET(DT_PARENT(DT_PHANDLE_BY_IDX(node, pinctrl_##n, i))) + +#define NXP_KINETIS_PIN_ELEM(i, node, n) \ + { \ + .port = NXP_KINETIS_GET_PORT_DEV(i, node, n), \ + .pin = NXP_KINETIS_PIN(i, node, n), \ + .mux = NXP_KINETIS_MUX(i, node, n), \ + }, + +#define PINCTRL_DT_SPEC_GET(node, n) \ +{ UTIL_LISTIFY(DT_PROP_LEN(node, pinctrl_##n), NXP_KINETIS_PIN_ELEM, node, n) } + +#ifdef __cplusplus +} +#endif + +#endif /* SOC_NXP_KINETIS_SOC_PINCTRL_H_ */ From 5504207bd0528ee76fa0109d0b5196fe2210af36 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 1 Apr 2021 16:33:46 -0500 Subject: [PATCH 6/7] drivers: serial: Convert uart_mcux.c to new pinctrl API Signed-off-by: Kumar Gala --- drivers/serial/uart_mcux.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/serial/uart_mcux.c b/drivers/serial/uart_mcux.c index 011e85ee2d2de..d96e952e43ada 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,8 @@ struct uart_mcux_config { #ifdef CONFIG_UART_INTERRUPT_DRIVEN void (*irq_config_func)(const struct device *dev); #endif + const pinctrl_dt_pin_spec_t *pins; + size_t num_pins; }; struct uart_mcux_data { @@ -40,6 +43,8 @@ static int uart_mcux_configure(const struct device *dev, uint32_t clock_freq; status_t retval; + pinctrl_pin_list_configure(config->pins, config->num_pins); + if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq)) { return -EINVAL; @@ -359,10 +364,15 @@ static const struct uart_driver_api uart_mcux_driver_api = { }; #define UART_MCUX_DECLARE_CFG(n, IRQ_FUNC_INIT) \ +static const pinctrl_dt_pin_spec_t uart_pins_##n[] = \ + PINCTRL_DT_SPEC_GET(DT_DRV_INST(n), 0); \ + \ 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),\ + .pins = uart_pins_##n, \ + .num_pins = ARRAY_SIZE(uart_pins_##n), \ IRQ_FUNC_INIT \ } From 0aa39f88a7321915459b6d1973e44ae052c437cf Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 10 Jun 2021 14:00:09 -0500 Subject: [PATCH 7/7] boards: arm: nxp: use driver to set uart pins Signed-off-by: Kumar Gala --- boards/arm/frdm_k22f/pinmux.c | 16 ---------------- boards/arm/frdm_k64f/pinmux.c | 20 -------------------- boards/arm/frdm_kl25z/pinmux.c | 6 ------ boards/arm/hexiwear_k64/pinmux.c | 12 ------------ boards/arm/twr_kv58f220m/pinmux.c | 6 ------ boards/arm/usb_kw24d512/pinmux.c | 6 ------ 6 files changed, 66 deletions(-) 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/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));