From 10aa57857d0875328c2cb068f4a36ea2aacd99e7 Mon Sep 17 00:00:00 2001 From: Gerson Fernando Budke Date: Thu, 10 Mar 2022 22:41:29 -0300 Subject: [PATCH] drivers: pinctrl: Update Atmel sam0 driver to new API This update current Atmel sam0 pinctrl initiative to current Zephyr pinctrl API. It update current devicetree bindings and add the sam0 pinctrl driver. Signed-off-by: Gerson Fernando Budke --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.sam0 | 11 ++ drivers/pinctrl/pinctrl_sam0.c | 57 +++++++++ dts/bindings/pinctrl/atmel,sam0-pinctrl.yaml | 121 ++++++++++++++---- .../drivers/pinctrl/pinctrl_soc_sam_common.h | 19 ++- soc/arm/atmel_sam0/Kconfig.defconfig | 7 + soc/arm/atmel_sam0/common/pinctrl_soc.h | 17 +++ soc/arm/atmel_sam0/common/soc_port.h | 20 +-- 9 files changed, 219 insertions(+), 35 deletions(-) create mode 100644 drivers/pinctrl/Kconfig.sam0 create mode 100644 drivers/pinctrl/pinctrl_sam0.c create mode 100644 soc/arm/atmel_sam0/common/pinctrl_soc.h diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index c6e21f9b1b3..a922c5ee83c 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_NRF pinctrl_nrf.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RCAR_PFC pfc_rcar.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SAM pinctrl_sam.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_SAM0 pinctrl_sam0.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_STM32 pinctrl_stm32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_KINETIS pinctrl_kinetis.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCHP_XEC pinctrl_mchp_xec.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index f871264cb5b..833ac288d9f 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -35,6 +35,7 @@ source "drivers/pinctrl/Kconfig.nrf" source "drivers/pinctrl/Kconfig.rcar" source "drivers/pinctrl/Kconfig.rpi_pico" source "drivers/pinctrl/Kconfig.sam" +source "drivers/pinctrl/Kconfig.sam0" source "drivers/pinctrl/Kconfig.stm32" source "drivers/pinctrl/Kconfig.kinetis" source "drivers/pinctrl/Kconfig.xec" diff --git a/drivers/pinctrl/Kconfig.sam0 b/drivers/pinctrl/Kconfig.sam0 new file mode 100644 index 00000000000..18a4d2402bd --- /dev/null +++ b/drivers/pinctrl/Kconfig.sam0 @@ -0,0 +1,11 @@ +# Copyright (c) 2022, Gerson Fernando Budke +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_ATMEL_SAM0_PINCTRL := atmel,sam0-pinctrl + +config PINCTRL_SAM0 + bool "Atmel SAM0 pin controller driver" + depends on SOC_FAMILY_SAM0 + default $(dt_compat_enabled,$(DT_COMPAT_ATMEL_SAM0_PINCTRL)) + help + Atmel pin controller driver is used on SAM0 SoC series diff --git a/drivers/pinctrl/pinctrl_sam0.c b/drivers/pinctrl/pinctrl_sam0.c new file mode 100644 index 00000000000..12adfc2a16e --- /dev/null +++ b/drivers/pinctrl/pinctrl_sam0.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022, Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/** Utility macro that expands to the PORT 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)),)) + +/** SAM0 port addresses */ +static const uint32_t sam_port_addrs[] = { + SAM_PORT_ADDR_OR_NONE(porta) + SAM_PORT_ADDR_OR_NONE(portb) + SAM_PORT_ADDR_OR_NONE(portc) + SAM_PORT_ADDR_OR_NONE(portd) + SAM_PORT_ADDR_OR_NONE(porte) + SAM_PORT_ADDR_OR_NONE(portf) +}; + +static void pinctrl_configure_pin(pinctrl_soc_pin_t pin) +{ + struct soc_port_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); + + soc_pin.regs = (PortGroup *) sam_port_addrs[port_idx]; + soc_pin.pinum = SAM_PINMUX_PIN_GET(pin); + soc_pin.flags = SAM_PINCTRL_FLAGS_GET(pin) << SOC_PORT_FLAGS_POS; + + if (port_func == SAM_PINMUX_FUNC_periph) { + soc_pin.flags |= (SAM_PINMUX_PERIPH_GET(pin) + << SOC_PORT_FUNC_POS) + | SOC_PORT_PMUXEN_ENABLE; + } + + soc_port_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; +} diff --git a/dts/bindings/pinctrl/atmel,sam0-pinctrl.yaml b/dts/bindings/pinctrl/atmel,sam0-pinctrl.yaml index 8a1081feb21..d3ad25a9f41 100644 --- a/dts/bindings/pinctrl/atmel,sam0-pinctrl.yaml +++ b/dts/bindings/pinctrl/atmel,sam0-pinctrl.yaml @@ -1,34 +1,91 @@ # Copyright (c) 2020, Linaro Limited -# Copyright (c) 2021, Gerson Fernando Budke +# Copyright (c) 2021-2022, Gerson Fernando Budke # SPDX-License-Identifier: Apache-2.0 description: | Atmel SAM0 Pinctrl container node - The Atmel SAM0 pins implements following pin configuration option: + The Atmel SAM0 pin controller is a singleton node responsible for controlling + pin function selection and pin properties. For example, you can use this node + to route SERCOM0 as UART were RX to pin PAD1 and enable the pull-up resistor + on the pin. - * bias-pull-up - * bias-pull-down - * drive-strength - * input-enable - * output-enable - * pinmux-enable + The node has the 'pinctrl' node label set in your SoC's devicetree, so you can + modify it like this: - These options define devicetree flags that are converted to SoC flags at - ATMEL_SAM0_PIN_FLAGS(). + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the 'pinctrl' + node, as shown in this example: + + /** You can put this in places like a -pinctrl.dtsi file in + * your board directory, or a devicetree overlay in your application. + */ + + /** include pre-defined combinations for the SoC variant used by the board */ + #include + + &pinctrl { + /* configuration for the usart0 "default" state */ + sercom0_uart_default: sercom0_uart_default { + /* group 1 */ + group1 { + /* configure PA6 as USART0 TX and PA8 as USART0 CTS */ + pinmux = , ; + }; + /* group 2 */ + group2 { + /* configure PA5 as USART0 RX and PA7 as USART0 RTS */ + pinmux = , ; + /* both PA5 and PA7 have pull-up enabled */ + bias-pull-up; + }; + }; + }; + + The 'usart0_default' child node encodes the pin configurations for a + particular state of a device; in this case, the default (that is, active) + state. + + As shown, pin configurations are organized in groups within each child node. + Each group can specify a list of pin function selections in the 'pinmux' + property. + + A group can also specify shared pin properties common to all the specified + pins, such as the 'bias-pull-up' property in group 2. Here is a list of + supported standard pin properties: + + - bias-pull-up: Enable pull-up resistor. + - bias-pull-down: Enable pull-down resistor. + - drive-strength: Increase sink current. + - input-enable: Enable input on pin. + - output-enable: Enable output on a pin without actively driving it. + + To link pin configurations with a device, use a pinctrl-N property for some + number N, like this example you could place in your board's DTS file: + + #include "board-pinctrl.dtsi" + + &usart0 { + pinctrl-0 = <&usart0_default>; + pinctrl-names = "default"; + }; compatible: "atmel,sam0-pinctrl" include: - name: base.yaml - - name: pincfg-node.yaml + - name: pincfg-node-group.yaml child-binding: - property-allowlist: - - bias-pull-up - - bias-pull-down - - drive-strength - - input-enable - - output-enable + child-binding: + property-allowlist: + - bias-pull-up + - bias-pull-down + - drive-strength + - input-enable + - output-enable properties: reg: @@ -43,13 +100,27 @@ properties: const: 1 child-binding: - description: Atmel pins + description: | + Each child node defines the configuration for a particular state. + child-binding: + description: | + The grandchild nodes group pins that share the same pin configuration. properties: - "atmel,pins": - type: phandle-array - - pinmux-enable: - required: false - type: boolean + pinmux: + required: true + type: array description: | - Assign pin to an embedded device peripheral + An array of pins sharing the same group properties. The pins should + be defined using pre-defined macros or, alternatively, using the + SAM_PINMUX utility macros depending on the pinmux model used by the + SoC series. + drive-strength: + enum: + - 0 + - 1 + default: 0 + description: | + The drive strength controls the output driver strength of an I/O pin + configured as an output. + 0: Pin drive strength is set to normal drive strength. + 1: Pin drive strength is set to stronger drive strength. diff --git a/include/drivers/pinctrl/pinctrl_soc_sam_common.h b/include/drivers/pinctrl/pinctrl_soc_sam_common.h index bd3aad5188e..31cdc197132 100644 --- a/include/drivers/pinctrl/pinctrl_soc_sam_common.h +++ b/include/drivers/pinctrl/pinctrl_soc_sam_common.h @@ -38,12 +38,23 @@ typedef uint32_t pinctrl_soc_pin_t; * @param prop Property name. * @param idx Property entry index. */ +#if defined(CONFIG_SOC_FAMILY_SAM) #define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ ((DT_PROP_BY_IDX(node_id, prop, idx) << SAM_PINCTRL_PINMUX_POS) \ | (DT_PROP(node_id, bias_pull_up) << SAM_PINCTRL_PULLUP_POS) \ | (DT_PROP(node_id, bias_pull_down) << SAM_PINCTRL_PULLDOWN_POS) \ | (DT_PROP(node_id, drive_open_drain) << SAM_PINCTRL_OPENDRAIN_POS) \ ), +#else /* CONFIG_SOC_FAMILY_SAM0 */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + ((DT_PROP_BY_IDX(node_id, prop, idx) << SAM_PINCTRL_PINMUX_POS) \ + | (DT_PROP(node_id, bias_pull_up) << SAM_PINCTRL_PULLUP_POS) \ + | (DT_PROP(node_id, bias_pull_down) << SAM_PINCTRL_PULLDOWN_POS) \ + | (DT_PROP(node_id, input_enable) << SAM_PINCTRL_INPUTENABLE_POS) \ + | (DT_PROP(node_id, output_enable) << SAM_PINCTRL_OUTPUTENABLE_POS) \ + | (DT_ENUM_IDX(node_id, drive_strength) << SAM_PINCTRL_DRIVESTRENGTH_POS)\ + ), +#endif /** * @brief Utility macro to initialize state pins contained in a given property. @@ -68,7 +79,7 @@ typedef uint32_t pinctrl_soc_pin_t; #define SAM_PINCTRL_FLAGS_DEFAULT (0U) #define SAM_PINCTRL_FLAGS_POS (0U) -#define SAM_PINCTRL_FLAGS_MASK (0x7 << SAM_PINCTRL_FLAGS_POS) +#define SAM_PINCTRL_FLAGS_MASK (0x3F << SAM_PINCTRL_FLAGS_POS) #define SAM_PINCTRL_FLAG_MASK (1U) #define SAM_PINCTRL_PULLUP_POS (SAM_PINCTRL_FLAGS_POS) #define SAM_PINCTRL_PULLUP (1U << SAM_PINCTRL_PULLUP_POS) @@ -76,6 +87,12 @@ typedef uint32_t pinctrl_soc_pin_t; #define SAM_PINCTRL_PULLDOWN (1U << SAM_PINCTRL_PULLDOWN_POS) #define SAM_PINCTRL_OPENDRAIN_POS (SAM_PINCTRL_PULLDOWN_POS + 1U) #define SAM_PINCTRL_OPENDRAIN (1U << SAM_PINCTRL_OPENDRAIN_POS) +#define SAM_PINCTRL_INPUTENABLE_POS (SAM_PINCTRL_OPENDRAIN_POS + 1U) +#define SAM_PINCTRL_INPUTENABLE (1U << SAM_PINCTRL_INPUTENABLE_POS) +#define SAM_PINCTRL_OUTPUTENABLE_POS (SAM_PINCTRL_INPUTENABLE_POS + 1U) +#define SAM_PINCTRL_OUTPUTENABLE (1U << SAM_PINCTRL_OUTPUTENABLE_POS) +#define SAM_PINCTRL_DRIVESTRENGTH_POS (SAM_PINCTRL_OUTPUTENABLE_POS + 1U) +#define SAM_PINCTRL_DRIVESTRENGTH (1U << SAM_PINCTRL_DRIVESTRENGTH_POS) /** @} */ diff --git a/soc/arm/atmel_sam0/Kconfig.defconfig b/soc/arm/atmel_sam0/Kconfig.defconfig index 0569ef9281d..b4f25f92c75 100644 --- a/soc/arm/atmel_sam0/Kconfig.defconfig +++ b/soc/arm/atmel_sam0/Kconfig.defconfig @@ -4,3 +4,10 @@ # SPDX-License-Identifier: Apache-2.0 source "soc/arm/atmel_sam0/*/Kconfig.defconfig.series" + +if SOC_FAMILY_SAM0 + +config PINCTRL + default y + +endif # SOC_FAMILY_SAM0 diff --git a/soc/arm/atmel_sam0/common/pinctrl_soc.h b/soc/arm/atmel_sam0/common/pinctrl_soc.h new file mode 100644 index 00000000000..f8e6216878a --- /dev/null +++ b/soc/arm/atmel_sam0/common/pinctrl_soc.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022, Gerson Fernando Budke + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * Atmel SAM SoC specific helpers for pinctrl driver + */ + +#ifndef ZEPHYR_SOC_ARM_ATMEL_SAM_COMMON_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_ATMEL_SAM_COMMON_PINCTRL_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_ARM_ATMEL_SAM_COMMON_PINCTRL_SOC_H_ */ diff --git a/soc/arm/atmel_sam0/common/soc_port.h b/soc/arm/atmel_sam0/common/soc_port.h index 2c90fd9bd5d..f7beba6ea92 100644 --- a/soc/arm/atmel_sam0/common/soc_port.h +++ b/soc/arm/atmel_sam0/common/soc_port.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2016-2017 Piotr Mienkowski - * Copyright (c) 2020-2021 Gerson Fernando Budke + * Copyright (c) 2020-2022 Gerson Fernando Budke * SPDX-License-Identifier: Apache-2.0 */ @@ -19,26 +19,28 @@ #define SOC_PORT_DEFAULT (0) #define SOC_PORT_FLAGS_POS (0) -#define SOC_PORT_FLAGS_MASK (0x3F << SOC_PORT_FLAGS_POS) -#define SOC_PORT_PULLUP_POS (0) +#define SOC_PORT_FLAGS_MASK (0x7B << SOC_PORT_FLAGS_POS) +#define SOC_PORT_PULLUP_POS (SOC_PORT_FLAGS_POS) #define SOC_PORT_PULLUP (1 << SOC_PORT_PULLUP_POS) -#define SOC_PORT_PULLDOWN_POS (1) +#define SOC_PORT_PULLDOWN_POS (SOC_PORT_PULLUP_POS + 1U) #define SOC_PORT_PULLDOWN (1 << SOC_PORT_PULLDOWN_POS) +/* Open-Drain is a reserved entry at pinctrl driver */ +#define SOC_GPIO_OPENDRAIN_POS (SOC_PORT_PULLDOWN_POS + 1U) /* Input-Enable means Input-Buffer, see dts/pinctrl/pincfg-node.yaml */ -#define SOC_PORT_INPUT_ENABLE_POS (2) +#define SOC_PORT_INPUT_ENABLE_POS (SOC_GPIO_OPENDRAIN_POS + 1U) #define SOC_PORT_INPUT_ENABLE (1 << SOC_PORT_INPUT_ENABLE_POS) /* Output-Enable, see dts/pinctrl/pincfg-node.yaml */ -#define SOC_PORT_OUTPUT_ENABLE_POS (3) +#define SOC_PORT_OUTPUT_ENABLE_POS (SOC_PORT_INPUT_ENABLE_POS + 1U) #define SOC_PORT_OUTPUT_ENABLE (1 << SOC_PORT_OUTPUT_ENABLE_POS) /* Drive-Strength, 0mA means normal, any other value means stronger */ -#define SOC_PORT_STRENGTH_STRONGER_POS (4) +#define SOC_PORT_STRENGTH_STRONGER_POS (SOC_PORT_OUTPUT_ENABLE_POS + 1U) #define SOC_PORT_STRENGTH_STRONGER (1 << SOC_PORT_STRENGTH_STRONGER_POS) /* Peripheral Multiplexer Enable */ -#define SOC_PORT_PMUXEN_ENABLE_POS (5) +#define SOC_PORT_PMUXEN_ENABLE_POS (SOC_PORT_STRENGTH_STRONGER_POS + 1U) #define SOC_PORT_PMUXEN_ENABLE (1 << SOC_PORT_PMUXEN_ENABLE_POS) /* Bit field: SOC_PORT_FUNC */ -#define SOC_PORT_FUNC_POS (16) +#define SOC_PORT_FUNC_POS (16U) #define SOC_PORT_FUNC_MASK (0xF << SOC_PORT_FUNC_POS) /** Connect pin to peripheral A. */