diff --git a/drivers/gpio/gpio_cmsdk_ahb.c b/drivers/gpio/gpio_cmsdk_ahb.c index fae16ac3159..476f905fc80 100644 --- a/drivers/gpio/gpio_cmsdk_ahb.c +++ b/drivers/gpio/gpio_cmsdk_ahb.c @@ -96,8 +96,7 @@ static int gpio_cmsdk_ahb_port_toggle_bits(const struct device *dev, return 0; } -static int cmsdk_ahb_gpio_config(const struct device *dev, uint32_t mask, - gpio_flags_t flags) +int cmsdk_ahb_gpio_config(const struct device *dev, uint32_t mask, gpio_flags_t flags) { const struct gpio_cmsdk_ahb_cfg * const cfg = dev->config; diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index 54b88f0b82c..5aa194e3a45 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -1,10 +1,12 @@ # Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright 2025 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 zephyr_library() zephyr_library_sources(common.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_TELINK_B91 pinctrl_b91.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_AMBIQ pinctrl_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_ARM_MPS2 pinctrl_arm_mps2.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AF pinctrl_gd32_af.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_GD32_AFIO pinctrl_gd32_afio.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ITE_IT8XXX2 pinctrl_ite_it8xxx2.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b754e595a8b..46028fdeca9 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -1,4 +1,5 @@ # Copyright (c) 2021 Nordic Semiconductor ASA +# Copyright 2025 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 menuconfig PINCTRL @@ -35,6 +36,7 @@ config PINCTRL_DYNAMIC source "drivers/pinctrl/Kconfig.b91" source "drivers/pinctrl/Kconfig.ambiq" +source "drivers/pinctrl/Kconfig.arm_mps2" source "drivers/pinctrl/Kconfig.gd32" source "drivers/pinctrl/Kconfig.it8xxx2" source "drivers/pinctrl/Kconfig.npcx" diff --git a/drivers/pinctrl/Kconfig.arm_mps2 b/drivers/pinctrl/Kconfig.arm_mps2 new file mode 100644 index 00000000000..0820a671087 --- /dev/null +++ b/drivers/pinctrl/Kconfig.arm_mps2 @@ -0,0 +1,10 @@ +# Copyright 2025 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + + +config PINCTRL_ARM_MPS2 + bool "Arm MPS2 pin controller driver" + default y + depends on DT_HAS_ARM_MPS2_PINCTRL_ENABLED + help + Arm MPS2 pinctrl driver diff --git a/drivers/pinctrl/pinctrl_arm_mps2.c b/drivers/pinctrl/pinctrl_arm_mps2.c new file mode 100644 index 00000000000..c78a007fdf3 --- /dev/null +++ b/drivers/pinctrl/pinctrl_arm_mps2.c @@ -0,0 +1,55 @@ +/* + * Copyright 2025 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "zephyr/device.h" +#include "zephyr/drivers/gpio.h" +#include +#include +#include + +/** + * The ARM MPS2 Board has 4 GPIO controllers. These controllers + * are responsible for pin muxing, input/output, pull-up, etc. + * + * All GPIO controller pins are exposed via the following sequence of pin + * numbers: + * Pins 0 - 15 are for GPIO0 + * Pins 16 - 31 are for GPIO1 + * Pins 32 - 47 are for GPIO2 + * Pins 48 - 51 are for GPIO3 + * + * For the GPIO controllers configuration ARM MPS2 Board follows the + * Arduino compliant pin out. + */ + +static const struct device *const gpio_ports[] = { + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio0)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio1)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio2)), + DEVICE_DT_GET_OR_NULL(DT_NODELABEL(gpio3)), +}; + +static int pinctrl_configure_pin(const pinctrl_soc_pin_t *pin) +{ + uint32_t flags = pin->input_enable ? GPIO_INPUT : GPIO_OUTPUT; + + /* Each gpio has 16 pins, so divide by 16 to get specific gpio*/ + const struct device *gpio_dev = gpio_ports[pin->pin_num >> 4]; + + return cmsdk_ahb_gpio_config(gpio_dev, pin->pin_num % 16, flags); +} + +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++) { + if (pinctrl_configure_pin(pins++) == -ENOTSUP) { + return -ENOTSUP; + } + } + + return 0; +} diff --git a/dts/bindings/pinctrl/arm,mps2-pinctrl.yaml b/dts/bindings/pinctrl/arm,mps2-pinctrl.yaml new file mode 100644 index 00000000000..314da3b7e5b --- /dev/null +++ b/dts/bindings/pinctrl/arm,mps2-pinctrl.yaml @@ -0,0 +1,81 @@ +# Copyright 2025 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +description: | + The Arm Mps2 pin controller is a node responsible for controlling + pin function selection and pin properties, such as routing a UART3 TX + to pin 1. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as shown in this example: + + &pinctrl { + /* configuration for the usart0 "default" state */ + uart3_default: uart3_default { + /* group 1 */ + group1 { + /* configure P1 as UART3 TX */ + pinmux = ; + }; + /* group 2 */ + group2 { + /* configure P0 as UART3 RX */ + pinmux = ; + /* enable input on pin 1 */ + input-enable; + }; + }; + }; + + The 'uart3_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. Here is a list of supported standard pin properties: + - input-enable + + A group can also specify shared pin properties common to all the specified + pins, such as the 'input-enable' property in group 2. + + 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" + + &uart3 { + pinctrl-0 = <&uart3_default>; + pinctrl-1 = <&uart3_sleep>; + pinctrl-names = "default", "sleep"; + }; + +compatible: "arm,mps2-pinctrl" + +include: base.yaml + +child-binding: + description: | + Definitions for a pinctrl state. + child-binding: + + include: + - name: pincfg-node.yaml + property-allowlist: + - input-enable + + properties: + pinmux: + required: true + type: array + description: | + An array of pins sharing the same group properties. Each + element of the array is an integer constructed from the + pin number and the alternative function of the pin. diff --git a/include/zephyr/drivers/gpio/gpio_cmsdk_ahb.h b/include/zephyr/drivers/gpio/gpio_cmsdk_ahb.h index 46ba451c0e7..de65f7a4c6a 100644 --- a/include/zephyr/drivers/gpio/gpio_cmsdk_ahb.h +++ b/include/zephyr/drivers/gpio/gpio_cmsdk_ahb.h @@ -52,6 +52,8 @@ struct gpio_cmsdk_ahb { volatile uint32_t ub_masked[256]; }; +int cmsdk_ahb_gpio_config(const struct device *dev, uint32_t mask, gpio_flags_t flags); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/dt-bindings/pinctrl/arm-mps2-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/arm-mps2-pinctrl.h new file mode 100644 index 00000000000..dfb1dc9dfec --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/arm-mps2-pinctrl.h @@ -0,0 +1,124 @@ +/* + * Copyright 2025 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define MPS2_ALT_FUNC_POS 0 +#define MPS2_ALT_FUNC_MASK 0x3 + +#define MPS2_EXP_NUM_POS 2 +#define MPS2_EXP_NUM_MASK 0x3F + +#define MPS2_PINCTRL_FUNC_UART 0 +#define MPS2_PINCTRL_FUNC_GPIO 1 +#define MPS2_PINCTRL_FUNC_I2C 2 +#define MPS2_PINCTRL_FUNC_SPI 3 + + +#define MPS2_PINMUX(alt_func, exp_num) (exp_num << MPS2_EXP_NUM_POS | \ + alt_func << MPS2_ALT_FUNC_POS) + + + +/* + * This is the mapping from the ARM MPS2 Board pins to GPIO + * controllers. + * + * D0 : EXT_0 + * D1 : EXT_4 + * D2 : EXT_2 + * D3 : EXT_3 + * D4 : EXT_1 + * D5 : EXT_6 + * D6 : EXT_7 + * D7 : EXT_8 + * D8 : EXT_9 + * D9 : EXT_10 + * D10 : EXT_12 + * D11 : EXT_13 + * D12 : EXT_14 + * D13 : EXT_11 + * D14 : EXT_15 + * D15 : EXT_5 + * D16 : EXT_16 + * D17 : EXT_17 + * D18 : EXT_18 + * D19 : EXT_19 + * D20 : EXT_20 + * D21 : EXT_21 + * D22 : EXT_22 + * D23 : EXT_23 + * D24 : EXT_24 + * D25 : EXT_25 + * D26 : EXT_26 + * D27 : EXT_30 + * D28 : EXT_28 + * D29 : EXT_29 + * D30 : EXT_27 + * D31 : EXT_32 + * D32 : EXT_33 + * D33 : EXT_34 + * D34 : EXT_35 + * D35 : EXT_36 + * D36 : EXT_38 + * D37 : EXT_39 + * D38 : EXT_40 + * D39 : EXT_44 + * D40 : EXT_41 + * D41 : EXT_31 + * D42 : EXT_37 + * D43 : EXT_42 + * D44 : EXT_43 + * D45 : EXT_45 + * D46 : EXT_46 + * D47 : EXT_47 + * D48 : EXT_48 + * D49 : EXT_49 + * D50 : EXT_50 + * D51 : EXT_51 + * + * UART_3_RX : D0 + * UART_3_TX : D1 + * SPI_3_CS : D10 + * SPI_3_MOSI : D11 + * SPI_3_MISO : D12 + * SPI_3_SCLK : D13 + * I2C_3_SDA : D14 + * I2C_3_SCL : D15 + * UART_4_RX : D26 + * UART_4_TX : D30 + * SPI_4_CS : D36 + * SPI_4_MOSI : D37 + * SPI_4_MISO : D38 + * SPI_4_SCK : D39 + * I2C_4_SDA : D40 + * I2C_4_SCL : D41 + * + */ + +/* GPIO 0 */ +#define UART3_RXD_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_UART, 0) +#define UART3_TXD_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_UART, 4) +#define SBCON2_SCL_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_I2C, 5) +#define SBCON2_SDA_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_I2C, 15) +#define SPI3_SCK_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 11) +#define SPI3_SS_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 12) +#define SPI3_MOSI_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 13) +#define SPI3_MISO_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 14) + +/* GPIO 1 */ +#define SPI2_SS_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 16) +#define SPI2_MISO_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 17) +#define SPI2_MOSI_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 18) +#define SPI2_SCK_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 19) +#define UART4_RXD_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_UART, 26) +#define UART4_TXD_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_UART, 30) +#define SBCON3_SCL_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_I2C, 31) + +/* GPIO 2 */ +#define SBCON3_SDA_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_I2C, 41) +#define SPI4_SS_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 38) +#define SPI4_MOSI_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 39) +#define SPI4_MISO_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 40) +#define SPI4_SCK_EXP MPS2_PINMUX(MPS2_PINCTRL_FUNC_SPI, 44) diff --git a/soc/arm/mps2/pinctrl_soc.h b/soc/arm/mps2/pinctrl_soc.h new file mode 100644 index 00000000000..b3ab8b95a58 --- /dev/null +++ b/soc/arm/mps2/pinctrl_soc.h @@ -0,0 +1,51 @@ +/* + * Copyright 2025 Arm Limited and/or its affiliates + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/** + * @brief Type to hold a pin's pinctrl configuration. + */ +struct mps2_pinctrl_soc_pin { + /** Pin number 0..52 */ + uint32_t pin_num : 6; + /** Alternative function (UART, SPI, etc.) */ + uint32_t alt_func : 2; + /** Enable the pin as an input */ + uint32_t input_enable : 1; +}; + +typedef struct mps2_pinctrl_soc_pin pinctrl_soc_pin_t; + +/** + * @brief Utility macro to initialize each pin. + * + * @param node_id Node identifier. + * @param prop Property name. + * @param idx Property entry index. + */ +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + { \ + MPS2_GET_PIN_NUM(DT_PROP_BY_IDX(node_id, prop, idx)), \ + MPS2_GET_PIN_ALT_FUNC(DT_PROP_BY_IDX(node_id, prop, idx)), \ + DT_PROP(node_id, input_enable), \ + }, + +/** + * @brief Utility macro to initialize state pins contained in a given property. + * + * @param node_id Node identifier. + * @param prop Property name describing state pins. + */ +#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)} + +#define MPS2_GET_PIN_NUM(pinctrl) \ + (((pinctrl) >> MPS2_EXP_NUM_POS) & MPS2_EXP_NUM_MASK) +#define MPS2_GET_PIN_ALT_FUNC(pinctrl) \ + (((pinctrl) >> MPS2_ALT_FUNC_POS) & MPS2_ALT_FUNC_MASK)