From df43429dabda6c16a5405ea84c7b31498756bc9b Mon Sep 17 00:00:00 2001 From: Scott Worley Date: Mon, 20 May 2024 16:00:08 -0400 Subject: [PATCH] drivers: gpio: mec5: Microchip MEC5 HAL based GPIO driver Add a GPIO driver for the Microchip MEC5 HAL based chips. Current devices are: MEC174x, MEC175x, and HAL version of MEC172x named MECH172x. Signed-off-by: Scott Worley --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 1 + drivers/gpio/Kconfig.mec5 | 11 + drivers/gpio/gpio_mchp_mec5.c | 529 +++++++++++++++++++++ dts/arm/microchip/mec5.dtsi | 20 +- dts/bindings/gpio/microchip,mec5-gpio.yaml | 19 + 6 files changed, 569 insertions(+), 12 deletions(-) create mode 100644 drivers/gpio/Kconfig.mec5 create mode 100644 drivers/gpio/gpio_mchp_mec5.c create mode 100644 dts/bindings/gpio/microchip,mec5-gpio.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index cd441db164e5fe..2e6280ff047b3e 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_LITEX gpio_litex.c) zephyr_library_sources_ifdef(CONFIG_GPIO_LMP90XXX gpio_lmp90xxx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_LPC11U6X gpio_lpc11u6x.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MAX32 gpio_max32.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_MCHP_MEC5 gpio_mchp_mec5.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCHP_MSS gpio_mchp_mss.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCP230XX gpio_mcp230xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCP23SXX gpio_mcp23sxx.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 90cad25cebe96a..9920addfab89be 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -138,6 +138,7 @@ source "drivers/gpio/Kconfig.mcux" source "drivers/gpio/Kconfig.mcux_igpio" source "drivers/gpio/Kconfig.mcux_lpc" source "drivers/gpio/Kconfig.mcux_rgpio" +source "drivers/gpio/Kconfig.mec5" source "drivers/gpio/Kconfig.mmio32" source "drivers/gpio/Kconfig.nct38xx" source "drivers/gpio/Kconfig.neorv32" diff --git a/drivers/gpio/Kconfig.mec5 b/drivers/gpio/Kconfig.mec5 new file mode 100644 index 00000000000000..b1b426498b92e8 --- /dev/null +++ b/drivers/gpio/Kconfig.mec5 @@ -0,0 +1,11 @@ +# Microchip MEC5 GPIO configuration options + +# Copyright (c) 2024 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_MCHP_MEC5 + bool "Microchip MEC5 GPIO driver" + default y + depends on DT_HAS_MICROCHIP_MEC5_GPIO_ENABLED + help + Enable the Microchip MEC5 gpio driver. diff --git a/drivers/gpio/gpio_mchp_mec5.c b/drivers/gpio/gpio_mchp_mec5.c new file mode 100644 index 00000000000000..ef339eae1ee67c --- /dev/null +++ b/drivers/gpio/gpio_mchp_mec5.c @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2024 Microchip Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_mec5_gpio + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* 32 pins per bank. Each pin has a 4-byte control register */ +#define MEC5_GPIO_PIN_CTRL_RSHFT 7 +#define MEC5_GPIO_PIN_CTRL_ADDR_MSK 0xfu + +struct gpio_mec5_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + /* port ISR callback routine address */ + sys_slist_t callbacks; +}; + +struct gpio_mec5_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + uintptr_t pcr1_base; + uintptr_t parin_addr; + uintptr_t parout_addr; + uint32_t flags; +}; + +static inline uint32_t mec5_addr_to_port(uint32_t base_addr) +{ + return ((base_addr >> MEC5_GPIO_PIN_CTRL_RSHFT) & MEC5_GPIO_PIN_CTRL_ADDR_MSK); +} + +/* NOTE: gpio_flags_t b[0:15] are defined in the dt-binding gpio header. + * b[31:16] are defined in the driver gpio header. + */ +static int gpio_mec5_validate_flags(gpio_flags_t flags) +{ + if (flags & GPIO_LINE_OPEN_SOURCE) { + return -ENOTSUP; + } + + if ((flags & GPIO_OUTPUT_INIT_LOW) && (flags & GPIO_OUTPUT_INIT_HIGH)) { + return -EINVAL; + } + + return 0; +} + +static const struct mec_gpio_props cfg_props_init[] = { + {MEC_GPIO_PWRGT_PROP_ID, MEC_GPIO_PROP_PWRGT_VTR}, + {MEC_GPIO_OSEL_PROP_ID, MEC_GPIO_PROP_OSEL_CTRL}, + {MEC_GPIO_INPAD_DIS_PROP_ID, MEC_GPIO_PROP_INPAD_EN}, +}; + +/* Each GPIO pin has two 32-bit control registers. Control 1 configures pin + * features except for drive strength and slew rate in Control 2. + * A pin's input and output state can be read/written from either the Control 1 + * register or from corresponding bits in the GPIO parallel input/output registers. + * The parallel input and output registers group 32 pins into each register. + * The GPIO hardware restricts the pin output state to Control 1 or the parallel bit. + * Both output bits reflect each other on read and writes but only one is writable + * selected by the output control select bit in Control 1. In the configuration API + * we use Control 1 to configure all pin features and output state. Before exiting, + * we set the output select for parallel mode enabling writes to the parallel output bit. + */ +static int gpio_mec5_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t pin_num = 0u; + uint32_t port_num = 0u; + uint32_t temp = 0u; + int ret = 0; + size_t idx = 0; + struct mec_gpio_props props[8]; + + port_num = mec5_addr_to_port(config->pcr1_base); + ret = mec_hal_gpio_pin_num(port_num, pin, &pin_num); + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + ret = mec_hal_gpio_port_pin_valid(port_num, pin); + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + ret = gpio_mec5_validate_flags(flags); + if (ret) { + return ret; + } + + if (flags == GPIO_DISCONNECTED) { + ret = mec_hal_gpio_set_property(pin_num, MEC_GPIO_PWRGT_PROP_ID, + MEC_GPIO_PROP_PWRGT_OFF); + if (ret != MEC_RET_OK) { + ret = -EIO; + } + return ret; + } + + ret = mec_hal_gpio_set_props(pin_num, cfg_props_init, ARRAY_SIZE(cfg_props_init)); + if (ret != MEC_RET_OK) { + return -EIO; + } + + if (flags & GPIO_OUTPUT) { + props[idx].prop = MEC_GPIO_DIR_PROP_ID; + props[idx].val = MEC_GPIO_PROP_DIR_OUT; + idx++; + + props[idx].prop = MEC_GPIO_OBUFT_PROP_ID; + props[idx].val = MEC_GPIO_PROP_PUSH_PULL; + if (flags & GPIO_LINE_OPEN_DRAIN) { + props[idx].val = MEC_GPIO_PROP_OPEN_DRAIN; + } + idx++; + + props[idx].prop = MEC_GPIO_CTRL_OUT_VAL_ID; + props[idx].val = 0u; + if (flags & GPIO_OUTPUT_INIT_HIGH) { + props[idx].val = 1u; + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + props[idx].val = 0u; + } else { + mec_hal_gpio_pad_in(pin_num, &props[idx].val); + } + idx++; + } + + if (flags & GPIO_INPUT) { + props[idx].prop = MEC_GPIO_DIR_PROP_ID; + props[idx].val = MEC_GPIO_PROP_DIR_IN; + idx++; + } + + temp = flags & (GPIO_PULL_UP | GPIO_PULL_DOWN); + if (temp) { + props[idx].prop = MEC_GPIO_PUD_PROP_ID; + if (temp == (GPIO_PULL_UP | GPIO_PULL_DOWN)) { + props[idx].val = MEC_GPIO_PROP_REPEATER; + } else if (temp & GPIO_PULL_UP) { + props[idx].val = MEC_GPIO_PROP_PULL_UP; + } else { + props[idx].val = MEC_GPIO_PROP_PULL_DN; + } + idx++; + } + + ret = mec_hal_gpio_set_props(pin_num, props, idx); + if (ret != MEC_RET_OK) { + return -EIO; + } + + /* make output state in control read-only in control and read-write in parallel reg */ + ret = mec_hal_gpio_set_property(pin_num, MEC_GPIO_OSEL_PROP_ID, MEC_GPIO_PROP_OSEL_PAROUT); + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static uint8_t gen_gpio_ctrl_icfg(enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + uint8_t idet; + + if (mode == GPIO_INT_MODE_DISABLED) { + idet = MEC_GPIO_PROP_IDET_DIS; + } else { + if (mode == GPIO_INT_MODE_LEVEL) { + if (trig == GPIO_INT_TRIG_HIGH) { + idet = MEC_GPIO_PROP_IDET_HI_LVL; + } else { + idet = MEC_GPIO_PROP_IDET_LO_LVL; + } + } else { + switch (trig) { + case GPIO_INT_TRIG_LOW: + idet = MEC_GPIO_PROP_IDET_EDGE_DN; + break; + case GPIO_INT_TRIG_HIGH: + idet = MEC_GPIO_PROP_IDET_EDGE_UP; + break; + case GPIO_INT_TRIG_BOTH: + idet = MEC_GPIO_PROP_IDET_EDGE_BOTH; + break; + default: + idet = MEC_GPIO_PROP_IDET_DIS; + break; + } + } + } + + return idet; +} + +/* Enable interrupt to propagate via its GIRQ to the NVIC */ +static void gpio_mec5_intr_en(uint8_t port, gpio_pin_t pin, enum gpio_int_mode mode) +{ + uint8_t en = 0u; + + if (mode != GPIO_INT_MODE_DISABLED) { + en = 1u; + } + + mec_hal_gpio_port_pin_ia_enable(port, pin, en); +} + +static const struct mec_gpio_props icfg_props_init[] = { + {MEC_GPIO_PWRGT_PROP_ID, MEC_GPIO_PROP_PWRGT_VTR}, + {MEC_GPIO_INPAD_DIS_PROP_ID, MEC_GPIO_PROP_INPAD_EN}, +}; + +static int gpio_mec5_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t pin_num = (uint32_t)MEC_PIN_MAX; + uint32_t port_num = 0; + int ret = 0; + uint8_t idet = 0, idet_curr = 0; + + /* Validate pin number range in terms of current port */ + port_num = mec5_addr_to_port(config->pcr1_base); + ret = mec_hal_gpio_port_pin_valid(port_num, pin); + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + /* Check if GPIO port supports interrupts */ + if ((mode != GPIO_INT_MODE_DISABLED) && !(config->flags & GPIO_INT_ENABLE)) { + return -ENOTSUP; + } + + /* Disable interrupt in the EC aggregator */ + gpio_mec5_intr_en(port_num, pin, 0); + + mec_hal_gpio_pin_num(port_num, pin, &pin_num); + ret = mec_hal_gpio_set_props(pin_num, icfg_props_init, ARRAY_SIZE(icfg_props_init)); + if (ret) { + return -EIO; + } + + idet_curr = MEC_GPIO_PROP_IDET_DIS; + ret = mec_hal_gpio_get_property(pin_num, MEC_GPIO_IDET_PROP_ID, &idet_curr); + if (ret != MEC_RET_OK) { + return -EIO; + } + + idet = gen_gpio_ctrl_icfg(mode, trig); + if (idet_curr == idet) { + gpio_mec5_intr_en(port_num, pin, mode); + return 0; + } + + ret = mec_hal_gpio_set_property(pin_num, MEC_GPIO_IDET_PROP_ID, idet); + if (ret != MEC_RET_OK) { + return -EIO; + } + + ret = mec_hal_gpio_pin_ia_status_clr(pin_num); + if (ret != MEC_RET_OK) { + return -EIO; + } + + gpio_mec5_intr_en(port_num, pin, mode); + + return 0; +} + +static int gpio_mec5_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_parout_port_mask(port_num, value, (const uint32_t)mask); + + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_set_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_parout_port_set_bits(port_num, (const uint32_t)mask); + + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_clear_bits_raw(const struct device *dev, uint32_t mask) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_parout_port_mask(port_num, 0u, (const uint32_t)mask); + + if (ret != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_toggle_bits(const struct device *dev, uint32_t mask) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + + if (mec_hal_gpio_parout_port_xor(port_num, mask) != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_port_get_raw(const struct device *dev, uint32_t *value) +{ + const struct gpio_mec5_config *config = dev->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + + if (mec_hal_gpio_parin_port(port_num, value) != MEC_RET_OK) { + return -EIO; + } + + return 0; +} + +static int gpio_mec5_manage_callback(const struct device *dev, struct gpio_callback *callback, + bool set) +{ + struct gpio_mec5_data *data = dev->data; + + gpio_manage_callback(&data->callbacks, callback, set); + + return 0; +} + +#ifdef CONFIG_GPIO_GET_DIRECTION +static int gpio_mec5_get_direction(const struct device *port, gpio_port_pins_t map, + gpio_port_pins_t *inputs, gpio_port_pins_t *outputs) +{ + if (!port) { + return -EINVAL; + } + + const struct gpio_mec5_config *config = port->config; + uint32_t valid_msk = 0u; + uint32_t pin_num = 0u, port_num = 0u; + int ret = 0; + uint8_t pwr_gate = 0u, dir = 0u, in_pad_dis = 0u; + + port_num = mec5_addr_to_port(config->pcr1_base); + ret = mec_hal_gpio_port_valid_mask(port_num, &valid_msk); + if (ret != MEC_RET_OK) { + return -EIO; + } + + *inputs = 0u; + *outputs = 0u; + for (uint8_t pin_pos = 0; pin_pos < 32; pin++) { + if (!map) { + break; + } + if ((map & BIT(pin_pos)) && (valid_msk & BIT(pin_pos))) { + mec_hal_gpio_pin_num(port_num, pin, &pin_num); + mec_hal_gpio_get_property(pin_num, MEC_GPIO_PWRGT_PROP_ID, &pwr_gate); + mec_hal_gpio_get_property(pin_num, MEC_GPIO_DIR_PROP_ID, &dir); + mec_hal_gpio_get_property(pin_num, MEC_GPIO_INPAD_DIS_PROP_ID, &in_pad_dis); + + if (pwr_gate != MEC_GPIO_PROP_PWRGT_OFF) { + if (outputs && (dir == MEC_GPIO_PROP_DIR_OUT)) { + *outputs |= BIT(pin_pos); + } else if (inputs && (in_pad_dis == MEC_GPIO_PROP_INPAD_EN)) { + *inputs |= BIT(pin_pos); + } + } + + map &= ~BIT(pin_pos); + } + } + + return 0; +} +#endif + +#ifdef CONFIG_GPIO_GET_CONFIG +int gpio_mec5_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) +{ + if (!port || !flags) { + return -EINVAL; + } + + const struct gpio_mec5_config *config = port->config; + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); + int ret = mec_hal_gpio_port_pin_valid(port_num, pin); + + if (ret != MEC_RET_OK) { + return -EINVAL; + } + + uint32_t pin_ctrl = mec_hal_gpio_port_get_ctrl_nc(port_num, pin); + uint32_t pin_flags = 0u; + uint8_t prop = MEC_GPIO_PROP_DIR_IN; + + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_DIR_PROP_ID, &prop); + + if (prop == MEC_GPIO_PROP_DIR_OUT) { + pin_flags |= GPIO_OUTPUT; + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_CTRL_OUT_VAL_ID, &prop); + if (prop != 0) { + pin_flags |= GPIO_OUTPUT_INIT_HIGH; + } else { + pin_flags |= GPIO_OUTPUT_INIT_LOW; + } + + prop = MEC_GPIO_PROP_PUSH_PULL; + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_OBUFT_PROP_ID, &prop); + if (prop == MEC_GPIO_PROP_OPEN_DRAIN) { + pin_flags |= GPIO_OPEN_DRAIN; + } + } else { + prop = MEC_GPIO_PROP_INPAD_DIS; + mec_hal_gpio_get_ctrl_property(pin_ctrl, MEC_GPIO_INPAD_DIS_PROP_ID, &prop); + if (prop == MEC_GPIO_PROP_INPAD_EN) { + pin_flags |= GPIO_INPUT; + } + } + + if (pin_flags) { + *flags = pin_flags; + } else { + *flags = GPIO_DISCONNECTED; + } + + return 0; +} +#endif + +static void gpio_mec5_port_isr(const struct device *dev) +{ + const struct gpio_mec5_config *config = dev->config; + struct gpio_mec5_data *data = dev->data; + uint32_t girq_result = 0xffffffffu; + uint32_t port_num = 0u; + + /* Figure out which interrupts have been triggered from the EC + * aggregator result register + */ + port_num = mec5_addr_to_port(config->pcr1_base); + mec_hal_gpio_port_ia_result(port_num, &girq_result); + + /* Clear source register in aggregator before firing callbacks */ + mec_hal_gpio_port_ia_status_clr_mask(port_num, girq_result); + + gpio_fire_callbacks(&data->callbacks, dev, girq_result); +} + +/* GPIO driver official API table */ +static const struct gpio_driver_api gpio_mec5_driver_api = { + .pin_configure = gpio_mec5_configure, + .port_get_raw = gpio_mec5_port_get_raw, + .port_set_masked_raw = gpio_mec5_port_set_masked_raw, + .port_set_bits_raw = gpio_mec5_port_set_bits_raw, + .port_clear_bits_raw = gpio_mec5_port_clear_bits_raw, + .port_toggle_bits = gpio_mec5_port_toggle_bits, + .pin_interrupt_configure = gpio_mec5_pin_interrupt_configure, + .manage_callback = gpio_mec5_manage_callback, +#ifdef CONFIG_GPIO_GET_DIRECTION + .port_get_direction = gpio_mec5_get_direction, +#endif +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_mec5_get_config, +#endif +}; + +#define MEC5_GPIO_PORT_FLAGS(n) ((DT_INST_IRQ_HAS_CELL(n, irq)) ? GPIO_INT_ENABLE : 0) + +/* TODO remove port_num. Derive it from pin & pin_num? */ +#define MEC5_GPIO_PORT(n) \ + static int gpio_mec5_port_init_##n(const struct device *dev) \ + { \ + if (!(DT_INST_IRQ_HAS_CELL(n, irq))) { \ + return 0; \ + } \ + \ + const struct gpio_mec5_config *config = dev->config; \ + uint32_t port_num = mec5_addr_to_port(config->pcr1_base); \ + \ + mec_hal_gpio_port_ia_ctrl(port_num, 1u); \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), gpio_mec5_port_isr, \ + DEVICE_DT_INST_GET(n), 0u); \ + irq_enable(DT_INST_IRQN(n)); \ + return 0; \ + } \ + static struct gpio_mec5_data gpio_mec5_port_data_##n; \ + static const struct gpio_mec5_config gpio_mec5_config_##n = { \ + .common = \ + { \ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n), \ + }, \ + .pcr1_base = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 0), \ + .parin_addr = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 1), \ + .parout_addr = (uintptr_t)DT_INST_REG_ADDR_BY_IDX(n, 2), \ + .flags = MEC5_GPIO_PORT_FLAGS(n), \ + }; \ + DEVICE_DT_INST_DEFINE(n, gpio_mec5_port_init_##n, NULL, &gpio_mec5_port_data_##n, \ + &gpio_mec5_config_##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_mec5_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MEC5_GPIO_PORT) diff --git a/dts/arm/microchip/mec5.dtsi b/dts/arm/microchip/mec5.dtsi index 9e16bfd75cc33c..01fd5320974f6a 100644 --- a/dts/arm/microchip/mec5.dtsi +++ b/dts/arm/microchip/mec5.dtsi @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -141,57 +143,51 @@ reg = <0x40081000 0x1000>; gpio_000_036: gpio@40081000 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081000 0x80 0x40081300 0x04 0x40081380 0x04 0x400813fc 0x04>; interrupts = <3 2>; gpio-controller; - port-id = <0>; - girq-id = <11>; #gpio-cells=<2>; }; gpio_040_076: gpio@40081080 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081080 0x80 0x40081304 0x04 0x40081384 0x04 0x400813f8 0x4>; interrupts = <2 2>; gpio-controller; - port-id = <1>; - girq-id = <10>; #gpio-cells=<2>; }; gpio_100_136: gpio@40081100 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081100 0x80 0x40081308 0x04 0x40081388 0x04 0x400813f4 0x04>; gpio-controller; interrupts = <1 2>; - port-id = <2>; - girq-id = <9>; #gpio-cells=<2>; }; gpio_140_176: gpio@40081180 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081180 0x80 0x4008130c 0x04 0x4008138c 0x04 0x400813f0 0x04>; gpio-controller; interrupts = <0 2>; - port-id = <3>; - girq-id = <8>; #gpio-cells=<2>; }; gpio_200_236: gpio@40081200 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081200 0x80 0x40081310 0x04 0x40081390 0x04 0x400813ec 0x04>; gpio-controller; interrupts = <4 2>; - port-id = <4>; - girq-id = <12>; #gpio-cells=<2>; }; gpio_240_276: gpio@40081280 { + compatible = "microchip,mec5-gpio"; reg = < 0x40081280 0x80 0x40081314 0x04 0x40081394 0x04 0x400813e8 0x04>; gpio-controller; interrupts = <17 2>; - port-id = <5>; - girq-id = <26>; #gpio-cells=<2>; }; }; diff --git a/dts/bindings/gpio/microchip,mec5-gpio.yaml b/dts/bindings/gpio/microchip,mec5-gpio.yaml new file mode 100644 index 00000000000000..c29ecb3466a477 --- /dev/null +++ b/dts/bindings/gpio/microchip,mec5-gpio.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip MEC5 GPIO node + +compatible: "microchip,mec5-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags