From ebea288a377c4e2449d7361394da5f5f2cf6e0b3 Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 13 Jan 2022 17:12:59 -0600 Subject: [PATCH 01/10] west.yml: Update to pull in pinctrl header from NXP HAL NXP hal will define constants for pinmux options in RT pinctrl implementation. Update hal revision to pull in dtsi file. Signed-off-by: Daniel DeGrasse --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index d738d0374f89d..90038e777e252 100644 --- a/west.yml +++ b/west.yml @@ -98,7 +98,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 072bf81d2ffcb764a6c63041cec876cbfb614c6a + revision: da6c1410490e382e69ee654a648b86a25e682679 path: modules/hal/nxp groups: - hal From 4f404803ecd9b9180e08b4b9daa2d427142dcb98 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 14:53:09 +0800 Subject: [PATCH 02/10] dts: bindings: add pinctrl binding for nxp mcux rt1xxx Add dts binding for rt1xxx pinctrl driver settings. A binding file is present for the pinctrl node itself, and for the pinctrl child node that defines all pinmux options Signed-off-by: Hake Huang Signed-off-by: Daniel DeGrasse --- dts/bindings/pinctrl/nxp,imx-iomuxc.yaml | 35 ++++ dts/bindings/pinctrl/nxp,mcux-rt-pinctrl.yaml | 156 ++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 dts/bindings/pinctrl/nxp,imx-iomuxc.yaml create mode 100644 dts/bindings/pinctrl/nxp,mcux-rt-pinctrl.yaml diff --git a/dts/bindings/pinctrl/nxp,imx-iomuxc.yaml b/dts/bindings/pinctrl/nxp,imx-iomuxc.yaml new file mode 100644 index 0000000000000..078eee78f7b89 --- /dev/null +++ b/dts/bindings/pinctrl/nxp,imx-iomuxc.yaml @@ -0,0 +1,35 @@ +# Copyright (c) 2022 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + This compatible binding should be applied to the device's iomuxc DTS node. + the DTS node will be populated with all pinmux options for the specific SOC. + These options can then be used in a pinctrl node with the "nxp,mcux-rt-pinctrl" + compatible string to define pin groups. + + The user should not edit the bindings defined within this node to make pinmux + selections, but should instead edit the pinctrl groups for their board. + +compatible: "nxp,imx-iomuxc" + +include: + - name: base.yaml + +properties: + reg: + required: true + +child-binding: + description: MCUX RT pin mux option + properties: + pinmux: + required: true + type: array + description: | + An array of values defining the pin mux selection, in the following format: + + mux_register: register that will be written to to make mux selection + mux_val: value to write to mux_register + input_reg: peripheral register that will direct peripheral signal to pin + daisy_val: value to write to input_reg + cfg_reg: register that will configure pin pull, drive strength, and open drain diff --git a/dts/bindings/pinctrl/nxp,mcux-rt-pinctrl.yaml b/dts/bindings/pinctrl/nxp,mcux-rt-pinctrl.yaml new file mode 100644 index 0000000000000..0098c39cb6a55 --- /dev/null +++ b/dts/bindings/pinctrl/nxp,mcux-rt-pinctrl.yaml @@ -0,0 +1,156 @@ +# Copyright (c) 2022 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: | + The node has the 'pinctrl' node label set in MCUX RT SoC's devicetree. These + nodes can be autogenerated using the MCUXpresso config tools combined with + the rt_dts_gen.py script in NXP's HAL. The mux, mode, input, daisy, and cfg + fields in a group select the pins to be configured, and the remaining + devicetree properties set configuration values for those pins + for example, here is an group configuring LPUART1 pins: + + group0 { + pinmux = <&iomuxc_gpio_ad_b0_12_lpuart1_tx, + &iomuxc_gpio_ad_b0_13_lpuart1_rx>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + + Note that the mux, mode, input, daisy, and cfg values must be aligned for + correct configuration + This will select GPIO_AD_B0_12 as LPUART1 TX, and GPIO_AD_B0_13 as LPUART1 RX. + Both pins will be configured with a weak latch, drive strength of "r0-6", + slow slew rate, and 100 MHZ speed. + Note that the soc level iomuxc dts file can be examined to find the possible + pinmux options. Here are the affects of each property on the + IOMUXC SW_PAD_CTL register: + input-schmitt-enable: HYS=1 + drive-open-drain: ODE=1 + input-enable: SION=1 (in SW_MUX_CTL_PAD register) + bias-pull-down: PUE=1, PUS= + bias-pull-up: PUE=1, PUS= + bias-disable: PKE=0 + slew-rate: SRE= + drive-strength: DSE= + nxp,speed: SPEED= + + If only required properties are supplied, the pin will have the following + configuration: + HYS=0, + ODE=0, + SION=0, + PUE=0, + PUS=0, + PKE=1, + SRE=, + DSE=, + SPEED= + + +compatible: "nxp,mcux-rt-pinctrl" + +include: + - name: base.yaml + - name: pincfg-node-group.yaml + child-binding: + child-binding: + property-allowlist: + - input-schmitt-enable + - drive-open-drain + - input-enable + - bias-disable + - bias-pull-down + - bias-pull-up + +child-binding: + description: MCUX RT pin controller pin group + child-binding: + description: | + MCUX RT pin controller pin configuration node. + properties: + pinmux: + required: true + type: phandles + description: | + Pin mux selections for this group. See the soc level iomuxc DTSI file + for a defined list of these options. + drive-strength: + required: true + type: string + enum: + - "disabled" + - "r0" + - "r0-2" + - "r0-3" + - "r0-4" + - "r0-5" + - "r0-6" + - "r0-7" + description: | + Pin output drive strength. Sets the DSE field in the IOMUXC peripheral. + the drive strength is expressed as a output impedance at a given voltage, + but maximum current values can be calculated from these impedances + for a specific load impedance. + 000 DSE_0_output_driver_disabled_ — output driver disabled + 001 DSE_1_R0_1 — 157 Ohm impedance @3.3V, 260 Ohm impedance @1.8V + 010 DSE_2_R0_2 — 78 Ohm @3.3V, 130 Ohm @1.8V + 011 DSE_3_R0_3 — 53 Ohm @3.3V, 88 Ohm @1.8V + 100 DSE_4_R0_4 — 39 Ohm @3.3V, 65 Ohm @1.8V + 101 DSE_5_R0_5 — 32 Ohm @3.3V, 52 Ohm @1.8V + 110 DSE_6_R0_6 — 32 Ohm @3.3V, 43 Ohm @1.8V + 111 DSE_7_R0_7 — 26 Ohm @3.3V, 37 Ohm @1.8V + bias-pull-up-value: + required: false + type: string + default: "47k" + enum: + - "unused" + - "47k" + - "100k" + - "22k" + description: | + Select the value of the pull up resistor present on this pin + Corresponds to the PUS field in the IOMUXC peripheral. + 47k resistor selected as default due to this being the default pullup + value on most SOC pins + 00 Unused- no change will be applied to pin + 01 PUS_1_47K_Ohm_Pull_Up — 47K Ohm Pull Up + 10 PUS_2_100K_Ohm_Pull_Up — 100K Ohm Pull Up + 11 PUS_2_22K_Ohm_Pull_Up — 22K Ohm Pull Up + + bias-pull-down-value: + required: false + type: string + default: "100k" + enum: + - "100k" + description: | + Select the value of the pull up resistor present on this pin + Corresponds to the PUS field in the IOMUXC peripheral. 100k is + currently the only supported pull down resistance. + 00 PUS_0_100K_Ohm_Pull_Down - 100K Ohm Pull Down + slew-rate: + required: true + type: string + enum: + - "slow" + - "fast" + description: | + Select slew rate for pin. Corresponds to SRE field in IOMUXC peripheral + 0 SRE_0_Slow_Slew_Rate — Slow Slew Rate + 1 SRE_1_Fast_Slew_Rate — Fast Slew Rate + nxp,speed: + required: false + type: string + enum: + - "50-mhz" + - "100-mhz" + - "150-mhz" + - "200-mhz" + description: | + Sets pin speed. Corresponds to SPEED field in IOMUXC peripheral + 00 SPEED_0_low_50MHz_ — low(50MHz) + 01 SPEED_1_medium_100MHz_ — medium(100MHz) + 10 SPEED_2_medium_150MHz_ — medium(150MHz) + 11 SPEED_3_max_200MHz_ — max(200MHz) From e8cee71654dbc8e791bfc99f188941159148c531 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 14:53:57 +0800 Subject: [PATCH 03/10] dts: bindings: add pinctrl node to sai and lpuart enable pinctrl in i2s and lpuart driver bindings Signed-off-by: Hake Huang Signed-off-by: Daniel DeGrasse --- dts/bindings/i2s/nxp,mcux-i2s.yaml | 2 +- dts/bindings/serial/nxp,kinetis-lpuart.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dts/bindings/i2s/nxp,mcux-i2s.yaml b/dts/bindings/i2s/nxp,mcux-i2s.yaml index c68cd9f41b078..d5b06daf2a719 100644 --- a/dts/bindings/i2s/nxp,mcux-i2s.yaml +++ b/dts/bindings/i2s/nxp,mcux-i2s.yaml @@ -5,7 +5,7 @@ description: NXP mcux SAI-I2S controller compatible: "nxp,mcux-i2s" -include: [i2s-controller.yaml] +include: [i2s-controller.yaml, pinctrl-device.yaml] properties: reg: diff --git a/dts/bindings/serial/nxp,kinetis-lpuart.yaml b/dts/bindings/serial/nxp,kinetis-lpuart.yaml index afcde99e06441..11b859871dd98 100644 --- a/dts/bindings/serial/nxp,kinetis-lpuart.yaml +++ b/dts/bindings/serial/nxp,kinetis-lpuart.yaml @@ -2,7 +2,7 @@ description: Kinetis LPUART compatible: "nxp,kinetis-lpuart" -include: uart-controller.yaml +include: [uart-controller.yaml, pinctrl-device.yaml] properties: reg: From 4697620966f9d5434c5abae1e3df9ac999804e8c Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 14:56:38 +0800 Subject: [PATCH 04/10] soc: add pinctrl header file definition for RT series Pinctrl requires header file with Z_PINCTRL_STATE_PINS_INIT macro defined. Add header file for mcux RT pinctrl implementation. Signed-off-by: Hake Huang Signed-off-by: Daniel DeGrasse --- soc/arm/nxp_imx/rt/pinctrl_soc.h | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 soc/arm/nxp_imx/rt/pinctrl_soc.h diff --git a/soc/arm/nxp_imx/rt/pinctrl_soc.h b/soc/arm/nxp_imx/rt/pinctrl_soc.h new file mode 100644 index 0000000000000..213ca0ab9f550 --- /dev/null +++ b/soc/arm/nxp_imx/rt/pinctrl_soc.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_ARM_NXP_IMX_RT_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_ARM_NXP_IMX_RT_PINCTRL_SOC_H_ + +#include +#include +#include "fsl_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct pinctrl_soc_pinmux { + uint32_t mux_register; + uint32_t mux_mode; + uint32_t input_register; + uint32_t input_daisy; + uint32_t config_register; +}; + +struct pinctrl_soc_pin { + struct pinctrl_soc_pinmux pinmux; + uint32_t pin_ctrl_flags; +}; + +typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; + +#define MCUX_RT_INPUT_SCHMITT_ENABLE_SHIFT IOMUXC_SW_PAD_CTL_PAD_HYS_SHIFT +#define MCUX_RT_BIAS_PULL_DOWN_SHIFT IOMUXC_SW_PAD_CTL_PAD_PUS_SHIFT +#define MCUX_RT_BIAS_PULL_UP_SHIFT IOMUXC_SW_PAD_CTL_PAD_PUS_SHIFT +#define MCUX_RT_BIAS_BUS_HOLD_SHIFT IOMUXC_SW_PAD_CTL_PAD_PUE_SHIFT +#define MCUX_RT_PULL_ENABLE_SHIFT IOMUXC_SW_PAD_CTL_PAD_PKE_SHIFT +#define MCUX_RT_DRIVE_OPEN_DRAIN_SHIFT IOMUXC_SW_PAD_CTL_PAD_ODE_SHIFT +#define MCUX_RT_SPEED_SHIFT IOMUXC_SW_PAD_CTL_PAD_SPEED_SHIFT +#define MCUX_RT_DRIVE_STRENGTH_SHIFT IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT +#define MCUX_RT_SLEW_RATE_SHIFT IOMUXC_SW_PAD_CTL_PAD_SRE_SHIFT +#define MCUX_RT_INPUT_ENABLE_SHIFT 31 /* Shift to a bit not used by IOMUXC_SW_PAD_CTL */ +#define MCUX_RT_INPUT_ENABLE(x) ((x >> MCUX_RT_INPUT_ENABLE_SHIFT) & 0x1) + +#define Z_PINCTRL_MCUX_RT_PINCFG_INIT(node_id) \ + ((DT_PROP(node_id, input_schmitt_enable) << MCUX_RT_INPUT_SCHMITT_ENABLE_SHIFT) | \ + IF_ENABLED(DT_PROP(node_id, bias_pull_up), (DT_ENUM_IDX(node_id, bias_pull_up_value) \ + << MCUX_RT_BIAS_PULL_UP_SHIFT) |) \ + IF_ENABLED(DT_PROP(node_id, bias_pull_down), (DT_ENUM_IDX(node_id, bias_pull_down_value)\ + << MCUX_RT_BIAS_PULL_DOWN_SHIFT) |) \ + ((DT_PROP(node_id, bias_pull_down) | DT_PROP(node_id, bias_pull_up)) \ + << MCUX_RT_BIAS_BUS_HOLD_SHIFT) | \ + ((!DT_PROP(node_id, bias_disable)) << MCUX_RT_PULL_ENABLE_SHIFT) | \ + (DT_PROP(node_id, drive_open_drain) << MCUX_RT_DRIVE_OPEN_DRAIN_SHIFT) | \ + (DT_ENUM_IDX(node_id, nxp_speed) << MCUX_RT_SPEED_SHIFT) | \ + (DT_ENUM_IDX(node_id, drive_strength) << MCUX_RT_DRIVE_STRENGTH_SHIFT) | \ + (DT_ENUM_IDX(node_id, slew_rate) << MCUX_RT_SLEW_RATE_SHIFT) | \ + (DT_PROP(node_id, input_enable) << MCUX_RT_INPUT_ENABLE_SHIFT)) + + +#define Z_PINCTRL_PINMUX(group_id, pin_prop, idx, pinmux_idx) \ + DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx), pinmux, pinmux_idx) + +#define Z_PINCTRL_STATE_PIN_INIT(group_id, pin_prop, idx) \ + { \ + .pinmux.mux_register = Z_PINCTRL_PINMUX(group_id, pin_prop, idx, 0), \ + .pinmux.mux_mode = Z_PINCTRL_PINMUX(group_id, pin_prop, idx, 1), \ + .pinmux.input_register = Z_PINCTRL_PINMUX(group_id, pin_prop, idx, 2), \ + .pinmux.input_daisy = Z_PINCTRL_PINMUX(group_id, pin_prop, idx, 3), \ + .pinmux.config_register = Z_PINCTRL_PINMUX(group_id, pin_prop, idx, 4), \ + .pin_ctrl_flags = Z_PINCTRL_MCUX_RT_PINCFG_INIT(group_id), \ + }, + + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ + DT_FOREACH_PROP_ELEM, pinmux, Z_PINCTRL_STATE_PIN_INIT)}; \ + + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_SOC_ARM_NXP_IMX_RT_PINCTRL_SOC_H_ */ From aaadefcaae8b7df18709241ca6fda6e0e41f870d Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 14:57:44 +0800 Subject: [PATCH 05/10] dts: imx_rt: add pinctrl and gpr for rt1xxx add dtsi settings for rt series dtsi use gpr to replace pinmux nxp iomuxc has gpr which has more settings than mux and io settings current solution is to export gpr separately and access then directly Signed-off-by: Hake Huang Signed-off-by: Daniel DeGrasse --- dts/arm/nxp/nxp_rt.dtsi | 9 +++++++-- dts/arm/nxp/nxp_rt11xx.dtsi | 24 +++++++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/dts/arm/nxp/nxp_rt.dtsi b/dts/arm/nxp/nxp_rt.dtsi index 18f7bd2ae8813..87983315fb1cc 100644 --- a/dts/arm/nxp/nxp_rt.dtsi +++ b/dts/arm/nxp/nxp_rt.dtsi @@ -232,8 +232,13 @@ }; iomuxc: iomuxc@401f8000 { + compatible = "nxp,imx-iomuxc"; reg = <0x401f8000 0x4000>; - label = "PINMUX_0"; + status = "okay"; + pinctrl: pinctrl { + status = "okay"; + compatible = "nxp,mcux-rt-pinctrl"; + }; }; lcdif: display-controller@402b8000 { @@ -729,7 +734,7 @@ }; iomuxcgpr: iomuxcgpr@400ac000 { - compatible = "nxp,imx-pinmux"; + compatible = "nxp,imx-gpr"; reg = <0x400AC000 0x4000>; label = "IOMUX_GPR"; #pinmux-cells = <2>; diff --git a/dts/arm/nxp/nxp_rt11xx.dtsi b/dts/arm/nxp/nxp_rt11xx.dtsi index 88bec6c9bf50e..e8d14e1e35886 100644 --- a/dts/arm/nxp/nxp_rt11xx.dtsi +++ b/dts/arm/nxp/nxp_rt11xx.dtsi @@ -313,8 +313,26 @@ }; iomuxc: iomuxc@400e8000 { + compatible = "nxp,imx-iomuxc"; reg = <0x400e8000 0x4000>; - label = "PINMUX_0"; + status = "okay"; + pinctrl: pinctrl { + status = "okay"; + compatible = "nxp,mcux-rt-pinctrl"; + }; + }; + + iomuxc_lpsr: iomuxc_lpsr@40c08000 { + compatible = "nxp,mcux-rt-pinctrl"; + reg = <0x40c08000 0x4000>; + status = "disabled"; + }; + + iomuxc_lpsr_gpr: iomuxc_lpsr_gpr@40c08000 { + compatible = "nxp,imx-gpr"; + reg = <0x40c08000 0x4000>; + label = "IOMUX_GPR"; + #pinmux-cells = <2>; }; lcdif: display-controller@40804000 { @@ -888,8 +906,8 @@ }; iomuxcgpr: iomuxcgpr@400e4000 { - compatible = "nxp,imx-pinmux"; - reg = <0x400E4000 0x4000>; + compatible = "nxp,imx-gpr"; + reg = <0x400e4000 0x4000>; label = "IOMUX_GPR"; #pinmux-cells = <2>; }; From dbd4f2d649dd44f25f987bc92fdeeef849574e03 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 15:01:27 +0800 Subject: [PATCH 06/10] drivers: pinctrl: add mcux_rt pinctrl driver Add pinctrl driver for rt1xxx Signed-off-by: Hake Huang Signed-off-by: Daniel DeGrasse --- drivers/pinctrl/CMakeLists.txt | 1 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Kconfig.mcux | 11 +++++++ drivers/pinctrl/pinctrl_mcux_rt.c | 48 +++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 drivers/pinctrl/Kconfig.mcux create mode 100644 drivers/pinctrl/pinctrl_mcux_rt.c diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index df5cbb1bb7e7e..c91ed202f5759 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -12,3 +12,4 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_RPI_PICO pinctrl_rpi_pico.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) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_MCUX_RT pinctrl_mcux_rt.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 9c1232a7d88ba..b0572429c4594 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -37,5 +37,6 @@ source "drivers/pinctrl/Kconfig.rpi_pico" source "drivers/pinctrl/Kconfig.stm32" source "drivers/pinctrl/Kconfig.kinetis" source "drivers/pinctrl/Kconfig.xec" +source "drivers/pinctrl/Kconfig.mcux" endif # PINCTRL diff --git a/drivers/pinctrl/Kconfig.mcux b/drivers/pinctrl/Kconfig.mcux new file mode 100644 index 0000000000000..c5a582af57266 --- /dev/null +++ b/drivers/pinctrl/Kconfig.mcux @@ -0,0 +1,11 @@ +# Copyright (c) 2022 NXP +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_MCUX_RT_PINCTRL := nxp,mcux-rt-pinctrl + +config PINCTRL_MCUX_RT + bool "Pin controller driver for MCUX RT1xxx MCUs" + depends on SOC_SERIES_IMX_RT + default $(dt_compat_enabled,$(DT_COMPAT_MCUX_RT_PINCTRL)) + help + Enable pin controller driver for NXP RT series MCUs diff --git a/drivers/pinctrl/pinctrl_mcux_rt.c b/drivers/pinctrl/pinctrl_mcux_rt.c new file mode 100644 index 0000000000000..a671d08ded645 --- /dev/null +++ b/drivers/pinctrl/pinctrl_mcux_rt.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_mcux_rt_pinctrl + +#include +#include +#include +#include + + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, + uintptr_t reg) +{ + /* configure all pins */ + for (uint8_t i = 0U; i < pin_cnt; i++) { + uint32_t mux_register = pins[i].pinmux.mux_register; + uint32_t mux_mode = pins[i].pinmux.mux_mode; + uint32_t input_register = pins[i].pinmux.input_register; + uint32_t input_daisy = pins[i].pinmux.input_daisy; + uint32_t config_register = pins[i].pinmux.config_register; + uint32_t pin_ctrl_flags = pins[i].pin_ctrl_flags; + + IOMUXC_SetPinMux(mux_register, mux_mode, input_register, + input_daisy, config_register, + MCUX_RT_INPUT_ENABLE(pin_ctrl_flags)); + + IOMUXC_SetPinConfig(mux_register, mux_mode, input_register, + input_daisy, config_register, + pin_ctrl_flags & (~(0x1 << MCUX_RT_INPUT_ENABLE_SHIFT))); + } + return 0; +} + +static int mcux_pinctrl_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + CLOCK_EnableClock(kCLOCK_Iomuxc); + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + return 0; +} + +SYS_INIT(mcux_pinctrl_init, PRE_KERNEL_1, 0); From 3cc8f3a088dae59bb92662190c52c16129447798 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 15:01:58 +0800 Subject: [PATCH 07/10] drivers: uart: add pinctrl support in mcux lpuart enable pinctrl in lpuart driver, and clean up driver instance definition macros Signed-off-by: Hake Huang --- drivers/serial/uart_mcux_lpuart.c | 79 +++++++++++++++++++------------ 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/drivers/serial/uart_mcux_lpuart.c b/drivers/serial/uart_mcux_lpuart.c index 0cc0aef0681e1..0752e71c8ebf9 100644 --- a/drivers/serial/uart_mcux_lpuart.c +++ b/drivers/serial/uart_mcux_lpuart.c @@ -14,10 +14,16 @@ #include #include #include +#ifdef CONFIG_PINCTRL +#include +#endif struct mcux_lpuart_config { LPUART_Type *base; const struct device *clock_dev; +#ifdef CONFIG_PINCTRL + const struct pinctrl_dev_config *pincfg; +#endif clock_control_subsys_t clock_subsys; uint32_t baud_rate; uint8_t flow_ctrl; @@ -454,6 +460,9 @@ static int mcux_lpuart_init(const struct device *dev) const struct mcux_lpuart_config *config = dev->config; struct mcux_lpuart_data *data = dev->data; struct uart_config *uart_api_config = &data->uart_config; +#ifdef CONFIG_PINCTRL + int err; +#endif uart_api_config->baudrate = config->baud_rate; uart_api_config->parity = UART_CFG_PARITY_NONE; @@ -463,6 +472,12 @@ static int mcux_lpuart_init(const struct device *dev) /* set initial configuration */ mcux_lpuart_configure_init(dev, uart_api_config); +#ifdef CONFIG_PINCTRL + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } +#endif #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_PM) config->irq_config_func(dev); @@ -505,7 +520,7 @@ static const struct uart_driver_api mcux_lpuart_driver_api = { #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_PM) -#define MCUX_LPUART_IRQ_INIT(n, i) \ +#define MCUX_LPUART_IRQ_INSTALL(n, i) \ do { \ IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, i, irq), \ DT_INST_IRQ_BY_IDX(n, i, priority), \ @@ -513,41 +528,49 @@ static const struct uart_driver_api mcux_lpuart_driver_api = { \ irq_enable(DT_INST_IRQ_BY_IDX(n, i, irq)); \ } while (0) -#define LPUART_MCUX_CONFIG_FUNC(n) \ - static void mcux_lpuart_config_func_##n(const struct device *dev) \ - { \ - MCUX_LPUART_IRQ_INIT(n, 0); \ +#define MCUX_LPUART_IRQ_INIT(n) .irq_config_func = mcux_lpuart_config_func_##n, +#define MCUX_LPUART_IRQ_DEFINE(n) \ + static void mcux_lpuart_config_func_##n(const struct device *dev) \ + { \ + MCUX_LPUART_IRQ_INSTALL(n, 0); \ \ IF_ENABLED(DT_INST_IRQ_HAS_IDX(n, 1), \ - (MCUX_LPUART_IRQ_INIT(n, 1);)) \ + (MCUX_LPUART_IRQ_INSTALL(n, 1);)) \ } -#define LPUART_MCUX_IRQ_CFG_FUNC_INIT(n) \ - .irq_config_func = mcux_lpuart_config_func_##n -#define LPUART_MCUX_INIT_CFG(n) \ - LPUART_MCUX_DECLARE_CFG(n, LPUART_MCUX_IRQ_CFG_FUNC_INIT(n)) #else -#define LPUART_MCUX_CONFIG_FUNC(n) -#define LPUART_MCUX_IRQ_CFG_FUNC_INIT -#define LPUART_MCUX_INIT_CFG(n) \ - LPUART_MCUX_DECLARE_CFG(n, LPUART_MCUX_IRQ_CFG_FUNC_INIT) -#endif +#define MCUX_LPUART_IRQ_INIT(n) +#define MCUX_LPUART_IRQ_DEFINE(n) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ -#define LPUART_MCUX_DECLARE_CFG(n, IRQ_FUNC_INIT) \ -static const struct mcux_lpuart_config mcux_lpuart_##n##_config = { \ - .base = (LPUART_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),\ - .baud_rate = DT_INST_PROP(n, current_speed), \ - .flow_ctrl = DT_INST_PROP(n, hw_flow_control) ? \ - UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE,\ - IRQ_FUNC_INIT \ -} + +#if CONFIG_PINCTRL +#define PINCTRL_DEFINE(n) PINCTRL_DT_INST_DEFINE(n); +#define PINCTRL_INIT(n) .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), +#else +#define PINCTRL_DEFINE(n) +#define PINCTRL_INIT(n) +#endif /* CONFIG_PINCTRL */ + +#define LPUART_MCUX_DECLARE_CFG(n) \ +static const struct mcux_lpuart_config mcux_lpuart_##n##_config = { \ + .base = (LPUART_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), \ + .baud_rate = DT_INST_PROP(n, current_speed), \ + .flow_ctrl = DT_INST_PROP(n, hw_flow_control) ? \ + UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE, \ + PINCTRL_INIT(n) \ + MCUX_LPUART_IRQ_INIT(n) \ +}; #define LPUART_MCUX_INIT(n) \ \ static struct mcux_lpuart_data mcux_lpuart_##n##_data; \ \ - static const struct mcux_lpuart_config mcux_lpuart_##n##_config;\ + PINCTRL_DEFINE(n) \ + MCUX_LPUART_IRQ_DEFINE(n) \ + \ + LPUART_MCUX_DECLARE_CFG(n) \ \ DEVICE_DT_INST_DEFINE(n, \ &mcux_lpuart_init, \ @@ -557,9 +580,5 @@ static const struct mcux_lpuart_config mcux_lpuart_##n##_config = { \ PRE_KERNEL_1, \ CONFIG_SERIAL_INIT_PRIORITY, \ &mcux_lpuart_driver_api); \ - \ - LPUART_MCUX_CONFIG_FUNC(n) \ - \ - LPUART_MCUX_INIT_CFG(n); DT_INST_FOREACH_STATUS_OKAY(LPUART_MCUX_INIT) From f7e7c8640c0e55810f6cba5910064d1574aac379 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 15:02:25 +0800 Subject: [PATCH 08/10] drivers: sai: add pinctrl support in mcux sai enable i2s pinctrl Signed-off-by: Hake Huang --- drivers/i2s/i2s_mcux_sai.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/i2s/i2s_mcux_sai.c b/drivers/i2s/i2s_mcux_sai.c index 5692b03595516..82098c456b5d5 100644 --- a/drivers/i2s/i2s_mcux_sai.c +++ b/drivers/i2s/i2s_mcux_sai.c @@ -16,8 +16,10 @@ #include #include #include - #include +#ifdef CONFIG_PINCTRL +#include +#endif #include #include #include @@ -78,6 +80,9 @@ struct i2s_mcux_config { uint32_t tx_channel; clock_control_subsys_t clk_sub_sys; const struct device *ccm_dev; +#ifdef CONFIG_PINCTRL + const struct pinctrl_dev_config *pinctrl; +#endif void (*irq_connect)(const struct device *dev); bool rx_sync_mode; bool tx_sync_mode; @@ -335,7 +340,6 @@ static void enable_mclk_direction(const struct device *dev, bool dir) } else { *gpr &= ~mask; } - } static void get_mclk_rate(const struct device *dev, uint32_t *mclk) @@ -969,6 +973,9 @@ static int i2s_mcux_initialize(const struct device *dev) I2S_Type *base = (I2S_Type *)dev_cfg->base; struct i2s_dev_data *dev_data = dev->data; uint32_t mclk; +#ifdef CONFIG_PINCTRL + int err; +#endif if (!dev_data->dev_dma) { LOG_ERR("DMA device not found"); @@ -987,6 +994,14 @@ static int i2s_mcux_initialize(const struct device *dev) /* register ISR */ dev_cfg->irq_connect(dev); + /* pinctrl */ +#ifdef CONFIG_PINCTRL + err = pinctrl_apply_state(dev_cfg->pinctrl, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("mclk pinctrl setup failed (%d)", err); + return err; + } +#endif /*clock configuration*/ audio_clock_settings(dev); @@ -1036,9 +1051,19 @@ static const struct i2s_driver_api i2s_mcux_driver_api = { .trigger = i2s_mcux_trigger, }; +#ifdef CONFIG_PINCTRL +#define PINCTRL_DEFINE(i2s_id) PINCTRL_DT_INST_DEFINE(i2s_id); +#define PINCTRL_INIT(i2s_id) .pinctrl = PINCTRL_DT_INST_DEV_CONFIG_GET(i2s_id), +#else +#define PINCTRL_DEFINE(i2s_id) +#define PINCTRL_INIT(i2s_id) +#endif + #define I2S_MCUX_INIT(i2s_id) \ static void i2s_irq_connect_##i2s_id(const struct device *dev); \ \ + PINCTRL_DEFINE(i2s_id) \ + \ static const struct i2s_mcux_config i2s_##i2s_id##_config = { \ .base = (I2S_Type *)DT_INST_REG_ADDR(i2s_id), \ .clk_src = \ @@ -1071,6 +1096,7 @@ static const struct i2s_driver_api i2s_mcux_driver_api = { DT_INST_CLOCKS_CELL_BY_IDX(i2s_id, 0, name), \ .ccm_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(i2s_id)), \ .irq_connect = i2s_irq_connect_##i2s_id, \ + PINCTRL_INIT(i2s_id) \ .tx_sync_mode = \ DT_INST_PROP(i2s_id, nxp_tx_sync_mode), \ .rx_sync_mode = \ From 3a6b74d59e0427dd9570c2b5cd2b659f5abe344f Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 15:00:28 +0800 Subject: [PATCH 09/10] board: pinctrl: board config for RT1060 enable pin control for RT1060 EVK. Signed-off-by: Hake Huang Signed-off-by: Daniel DeGrasse --- .../mimxrt1060_evk-pinctrl.dtsi | 53 +++++++++++++++++++ boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts | 10 ++++ .../mimxrt1060_evk/mimxrt1060_evk_defconfig | 1 + boards/arm/mimxrt1060_evk/pinmux.c | 30 ----------- 4 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi b/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi new file mode 100644 index 0000000000000..9f54a7aeed25f --- /dev/null +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk-pinctrl.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, NXP + * SPDX-License-Identifier: Apache-2.0 + * + * Generated by rt_cfg_utils.py on 2022-03-02 + */ + +#include + +&pinctrl { + lpuart1_default: lpuart1_default { + group0 { + pinmux = <&iomuxc_gpio_ad_b0_12_lpuart1_tx + &iomuxc_gpio_ad_b0_13_lpuart1_rx>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; + + lpuart1_sleep: pinmux_lpuart1_sleep { + group0 { + pinmux = <&iomuxc_gpio_ad_b0_13_gpio1_io13>; + bias-disable; + drive-strength = "r0"; + bias-pull-up; + bias-pull-up-value = "100k"; + slew-rate = "slow"; + nxp,speed = "50-mhz"; + }; + group1 { + pinmux = <&iomuxc_gpio_ad_b0_12_lpuart1_tx>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + }; + }; + + sai1_default: sai1_default { + group0 { + pinmux = <&iomuxc_gpio_ad_b1_09_sai1_mclk + &iomuxc_gpio_ad_b1_13_sai1_tx_data00 + &iomuxc_gpio_ad_b1_12_sai1_rx_data00 + &iomuxc_gpio_ad_b1_14_sai1_tx_bclk + &iomuxc_gpio_ad_b1_15_sai1_tx_sync>; + drive-strength = "r0-6"; + slew-rate = "slow"; + nxp,speed = "100-mhz"; + input-enable; + }; + }; + +}; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts index 3a08556706c6c..2f1c80da11dc1 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts @@ -7,6 +7,7 @@ /dts-v1/; #include +#include "mimxrt1060_evk-pinctrl.dtsi" / { model = "NXP MIMXRT1060-EVK board"; @@ -175,6 +176,9 @@ arduino_serial: &lpuart3 {}; &lpuart1 { status = "okay"; current-speed = <115200>; + pinctrl-0 = <&lpuart1_default>; + pinctrl-1 = <&lpuart1_sleep>; + pinctrl-names = "default", "sleep"; }; &enet { @@ -229,6 +233,8 @@ zephyr_udc0: &usb1 { &sai1 { status = "okay"; + pinctrl-0 = <&sai1_default>; + pinctrl-names = "default"; }; /* Enable GPT for use as a hardware timer. This disables Cortex Systick. @@ -237,3 +243,7 @@ zephyr_udc0: &usb1 { &gpt_hw_timer { status = "okay"; }; + +&iomuxcgpr { + status = "okay"; +}; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig index 535467c4575bc..40d615261b37a 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk_defconfig @@ -13,3 +13,4 @@ CONFIG_SERIAL=y CONFIG_GPIO=y CONFIG_ARM_MPU=y CONFIG_HW_STACK_PROTECTION=y +CONFIG_PINCTRL=y diff --git a/boards/arm/mimxrt1060_evk/pinmux.c b/boards/arm/mimxrt1060_evk/pinmux.c index 3a597c22b2b7b..5a90ad608ad56 100644 --- a/boards/arm/mimxrt1060_evk/pinmux.c +++ b/boards/arm/mimxrt1060_evk/pinmux.c @@ -114,22 +114,6 @@ static int mimxrt1060_evk_init(const struct device *dev) IOMUXC_SetPinMux(IOMUXC_SNVS_WAKEUP_GPIO5_IO00, 0); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart1), okay) && CONFIG_SERIAL - /* LPUART1 TX/RX */ - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, 0); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_12_LPUART1_TX, - IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | - IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | - IOMUXC_SW_PAD_CTL_PAD_DSE(6)); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, - IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | - IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | - IOMUXC_SW_PAD_CTL_PAD_DSE(6)); -#endif - #if DT_NODE_HAS_STATUS(DT_NODELABEL(lpuart3), okay) && CONFIG_SERIAL /* LPUART3 TX/RX */ IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_LPUART3_TX, 0); @@ -400,20 +384,6 @@ static int mimxrt1060_evk_init(const struct device *dev) IOMUXC_SW_PAD_CTL_PAD_DSE(6)); #endif -#if DT_NODE_HAS_STATUS(DT_NODELABEL(sai1), okay) && CONFIG_I2S - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_09_SAI1_MCLK, 1U); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00, 1U); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00, 1U); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK, 1U); - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC, 1U); - - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_09_SAI1_MCLK, 0x10B0u); - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00, 0x10B0u); - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00, 0x10B0u); - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK, 0x10B0u); - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC, 0x10B0u); -#endif - return 0; } From 1a1babf6a711f575594c72887ed6796a4d669a4d Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Fri, 24 Dec 2021 15:15:10 +0800 Subject: [PATCH 10/10] dts: binding: rename pinmux to gpr rename pinmux to gpr different from pinmux and io settings gpr will do more IO settings. Signed-off-by: Hake Huang --- dts/bindings/pinctrl/{nxp,imx-pinmux.yaml => nxp,imx-gpr.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename dts/bindings/pinctrl/{nxp,imx-pinmux.yaml => nxp,imx-gpr.yaml} (88%) diff --git a/dts/bindings/pinctrl/nxp,imx-pinmux.yaml b/dts/bindings/pinctrl/nxp,imx-gpr.yaml similarity index 88% rename from dts/bindings/pinctrl/nxp,imx-pinmux.yaml rename to dts/bindings/pinctrl/nxp,imx-gpr.yaml index 66c1ed3a0dfeb..cac8908f65562 100644 --- a/dts/bindings/pinctrl/nxp,imx-pinmux.yaml +++ b/dts/bindings/pinctrl/nxp,imx-gpr.yaml @@ -3,7 +3,7 @@ description: i.MX IOMUXC node -compatible: "nxp,imx-pinmux" +compatible: "nxp,imx-gpr" include: base.yaml