From 491e3e6477b4389e7e6dfe06ccd2b5594b384cde Mon Sep 17 00:00:00 2001 From: Tim Lin Date: Thu, 19 Jan 2023 16:48:24 +0800 Subject: [PATCH] ITE: drivers/gpio: Add gpio_ite_it8xxx2_v2 driver This driver is made for it82xx2 series. Signed-off-by: Tim Lin --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig.it8xxx2 | 7 + drivers/gpio/gpio_ite_it8xxx2_v2.c | 456 +++++++++++++++++ dts/bindings/gpio/ite,it8xxx2-gpio-v2.yaml | 32 ++ dts/riscv/ite/it82xx2.dtsi | 561 +++++++++++++++++++++ soc/riscv/riscv-ite/common/soc_dt.h | 23 + 6 files changed, 1080 insertions(+) create mode 100644 drivers/gpio/gpio_ite_it8xxx2_v2.c create mode 100644 dts/bindings/gpio/ite,it8xxx2-gpio-v2.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index d5cbf9e5067..810236106d3 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -13,6 +13,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SIFIVE gpio_sifive.c) zephyr_library_sources_ifdef(CONFIG_GPIO_GECKO gpio_gecko.c) zephyr_library_sources_ifdef(CONFIG_GPIO_IMX gpio_imx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ITE_IT8XXX2 gpio_ite_it8xxx2.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_ITE_IT8XXX2_V2 gpio_ite_it8xxx2_v2.c) zephyr_library_sources_ifdef(CONFIG_GPIO_KSCAN_ITE_IT8XXX2 gpio_kscan_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCP23S17 gpio_mcp23s17.c) zephyr_library_sources_ifdef(CONFIG_GPIO_MCP23XXX gpio_mcp23xxx.c) diff --git a/drivers/gpio/Kconfig.it8xxx2 b/drivers/gpio/Kconfig.it8xxx2 index 4bf21961ce1..713e6916f52 100644 --- a/drivers/gpio/Kconfig.it8xxx2 +++ b/drivers/gpio/Kconfig.it8xxx2 @@ -8,6 +8,13 @@ config GPIO_ITE_IT8XXX2 help Enable driver for the ite GPIO controller. +config GPIO_ITE_IT8XXX2_V2 + bool "ITE IT8XXX2 GPIO driver V2" + default y + depends on DT_HAS_ITE_IT8XXX2_GPIO_V2_ENABLED + help + Enable driver for the ite GPIO V2 controller. + config GPIO_KSCAN_ITE_IT8XXX2 bool "ITE IT8XXX2 GPIO KSCAN driver" default y diff --git a/drivers/gpio/gpio_ite_it8xxx2_v2.c b/drivers/gpio/gpio_ite_it8xxx2_v2.c new file mode 100644 index 00000000000..b06dca0fef1 --- /dev/null +++ b/drivers/gpio/gpio_ite_it8xxx2_v2.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2023 ITE Corporation. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#define DT_DRV_COMPAT ite_it8xxx2_gpio_v2 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +LOG_MODULE_REGISTER(gpio_it8xxx2, LOG_LEVEL_ERR); + +/* + * Structure gpio_ite_cfg is about the setting of GPIO + * this config will be used at initial time + */ +struct gpio_ite_cfg { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; + /* GPIO port data register (bit mapping to pin) */ + uintptr_t reg_gpdr; + /* GPIO port data mirror register (bit mapping to pin) */ + uintptr_t reg_gpdmr; + /* GPIO port output type register (bit mapping to pin) */ + uintptr_t reg_gpotr; + /* GPIO port 1.8V select register (bit mapping to pin) */ + uintptr_t reg_p18scr; + /* GPIO port control register (byte mapping to pin) */ + uintptr_t reg_gpcr; + /* Wake up control base register */ + uintptr_t wuc_base[8]; + /* Wake up control mask */ + uint8_t wuc_mask[8]; + /* GPIO's irq */ + uint8_t gpio_irq[8]; + /* Support input voltage selection */ + uint8_t has_volt_sel[8]; + /* Number of pins per group of GPIO */ + uint8_t num_pins; +}; + +/* Structure gpio_ite_data is about callback function */ +struct gpio_ite_data { + struct gpio_driver_data common; + sys_slist_t callbacks; + uint8_t volt_default_set; +}; + +/** + * Driver functions + */ +static int gpio_ite_configure(const struct device *dev, + gpio_pin_t pin, + gpio_flags_t flags) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr; + volatile uint8_t *reg_gpotr = (uint8_t *)gpio_config->reg_gpotr; + volatile uint8_t *reg_p18scr = (uint8_t *)gpio_config->reg_p18scr; + volatile uint8_t *reg_gpcr = (uint8_t *)gpio_config->reg_gpcr + pin; + struct gpio_ite_data *data = dev->data; + uint8_t mask = BIT(pin); + + /* Don't support "open source" mode */ + if (((flags & GPIO_SINGLE_ENDED) != 0) && + ((flags & GPIO_LINE_OPEN_DRAIN) == 0)) { + return -ENOTSUP; + } + + if (flags == GPIO_DISCONNECTED) { + *reg_gpcr = GPCR_PORT_PIN_MODE_TRISTATE; + /* + * Since not all GPIOs can be to configured as tri-state, + * prompt error if pin doesn't support the flag. + */ + if (*reg_gpcr != GPCR_PORT_PIN_MODE_TRISTATE) { + /* Go back to default setting (input) */ + *reg_gpcr = GPCR_PORT_PIN_MODE_INPUT; + LOG_ERR("Cannot config the node-gpio@%x, pin=%d as tri-state", + (uint32_t)reg_gpdr, pin); + return -ENOTSUP; + } + /* + * The following configuration isn't necessary because the pin + * was configured as disconnected. + */ + return 0; + } + + /* + * Select open drain first, so that we don't glitch the signal + * when changing the line to an output. + */ + if (flags & GPIO_OPEN_DRAIN) { + *reg_gpotr |= mask; + } else { + *reg_gpotr &= ~mask; + } + + /* 1.8V or 3.3V */ + if (gpio_config->has_volt_sel[pin]) { + gpio_flags_t volt = flags & IT8XXX2_GPIO_VOLTAGE_MASK; + + if (volt == IT8XXX2_GPIO_VOLTAGE_1P8) { + __ASSERT(!(flags & GPIO_PULL_UP), + "Don't enable internal pullup if 1.8V voltage is used"); + *reg_p18scr |= mask; + data->volt_default_set &= ~mask; + } else if (volt == IT8XXX2_GPIO_VOLTAGE_3P3) { + *reg_p18scr &= ~mask; + /* + * A variable is needed to store the difference between + * 3.3V and default so that the flag can be distinguished + * between the two in gpio_ite_get_config. + */ + data->volt_default_set &= ~mask; + } else if (volt == IT8XXX2_GPIO_VOLTAGE_DEFAULT) { + *reg_p18scr &= ~mask; + data->volt_default_set |= mask; + } else { + return -EINVAL; + } + } + + /* If output, set level before changing type to an output. */ + if (flags & GPIO_OUTPUT) { + if (flags & GPIO_OUTPUT_INIT_HIGH) { + *reg_gpdr |= mask; + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + *reg_gpdr &= ~mask; + } + } + + /* Set input or output. */ + if (flags & GPIO_OUTPUT) { + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_OUTPUT) & + ~GPCR_PORT_PIN_MODE_INPUT; + } else { + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) & + ~GPCR_PORT_PIN_MODE_OUTPUT; + } + + /* Handle pullup / pulldown */ + if (flags & GPIO_PULL_UP) { + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLUP) & + ~GPCR_PORT_PIN_MODE_PULLDOWN; + } else if (flags & GPIO_PULL_DOWN) { + *reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_PULLDOWN) & + ~GPCR_PORT_PIN_MODE_PULLUP; + } else { + /* No pull up/down */ + *reg_gpcr &= ~(GPCR_PORT_PIN_MODE_PULLUP | + GPCR_PORT_PIN_MODE_PULLDOWN); + } + + return 0; +} + +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_ite_get_config(const struct device *dev, + gpio_pin_t pin, + gpio_flags_t *out_flags) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr; + volatile uint8_t *reg_gpotr = (uint8_t *)gpio_config->reg_gpotr; + volatile uint8_t *reg_p18scr = (uint8_t *)gpio_config->reg_p18scr; + volatile uint8_t *reg_gpcr = (uint8_t *)gpio_config->reg_gpcr + pin; + struct gpio_ite_data *data = dev->data; + uint8_t mask = BIT(pin); + gpio_flags_t flags = 0; + + /* push-pull or open-drain */ + if (*reg_gpotr & mask) { + flags |= GPIO_OPEN_DRAIN; + } + + /* 1.8V or 3.3V */ + if (gpio_config->has_volt_sel[pin]) { + if (data->volt_default_set & mask) { + flags |= IT8XXX2_GPIO_VOLTAGE_DEFAULT; + } else { + if (*reg_p18scr & mask) { + flags |= IT8XXX2_GPIO_VOLTAGE_1P8; + } else { + flags |= IT8XXX2_GPIO_VOLTAGE_3P3; + } + } + } + + /* set input or output. */ + if (*reg_gpcr & GPCR_PORT_PIN_MODE_OUTPUT) { + flags |= GPIO_OUTPUT; + + /* set level */ + if (*reg_gpdr & mask) { + flags |= GPIO_OUTPUT_HIGH; + } else { + flags |= GPIO_OUTPUT_LOW; + } + } + + if (*reg_gpcr & GPCR_PORT_PIN_MODE_INPUT) { + flags |= GPIO_INPUT; + + /* pullup / pulldown */ + if (*reg_gpcr & GPCR_PORT_PIN_MODE_PULLUP) { + flags |= GPIO_PULL_UP; + } + + if (*reg_gpcr & GPCR_PORT_PIN_MODE_PULLDOWN) { + flags |= GPIO_PULL_DOWN; + } + } + + *out_flags = flags; + + return 0; +} +#endif + +static int gpio_ite_port_get_raw(const struct device *dev, + gpio_port_value_t *value) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdmr = (uint8_t *)gpio_config->reg_gpdmr; + + /* Get raw bits of GPIO mirror register */ + *value = *reg_gpdmr; + + return 0; +} + +static int gpio_ite_port_set_masked_raw(const struct device *dev, + gpio_port_pins_t mask, + gpio_port_value_t value) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr; + uint8_t out = *reg_gpdr; + + *reg_gpdr = ((out & ~mask) | (value & mask)); + + return 0; +} + +static int gpio_ite_port_set_bits_raw(const struct device *dev, + gpio_port_pins_t pins) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr; + + /* Set raw bits of GPIO data register */ + *reg_gpdr |= pins; + + return 0; +} + +static int gpio_ite_port_clear_bits_raw(const struct device *dev, + gpio_port_pins_t pins) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr; + + /* Clear raw bits of GPIO data register */ + *reg_gpdr &= ~pins; + + return 0; +} + +static int gpio_ite_port_toggle_bits(const struct device *dev, + gpio_port_pins_t pins) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr; + + /* Toggle raw bits of GPIO data register */ + *reg_gpdr ^= pins; + + return 0; +} + +static int gpio_ite_manage_callback(const struct device *dev, + struct gpio_callback *callback, + bool set) +{ + struct gpio_ite_data *data = dev->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static void gpio_ite_isr(const void *arg) +{ + const struct device *dev = arg; + const struct gpio_ite_cfg *gpio_config = dev->config; + struct gpio_ite_data *data = dev->data; + uint8_t irq = ite_intc_get_irq_num(); + uint8_t num_pins = gpio_config->num_pins; + uint8_t pin; + + for (pin = 0; pin <= num_pins; pin++) { + if (irq == gpio_config->gpio_irq[pin]) { + volatile uint8_t *reg_base = + (uint8_t *)gpio_config->wuc_base[pin]; + volatile uint8_t *reg_wuesr = reg_base + 1; + uint8_t wuc_mask = gpio_config->wuc_mask[pin]; + + /* Clear the WUC status register. */ + *reg_wuesr = wuc_mask; + gpio_fire_callbacks(&data->callbacks, dev, BIT(pin)); + + break; + } + } +} + +static int gpio_ite_pin_interrupt_configure(const struct device *dev, + gpio_pin_t pin, + enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct gpio_ite_cfg *gpio_config = dev->config; + uint8_t gpio_irq = gpio_config->gpio_irq[pin]; + +#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT + if (mode == GPIO_INT_MODE_DISABLED || mode == GPIO_INT_MODE_DISABLE_ONLY) { +#else + if (mode == GPIO_INT_MODE_DISABLED) { +#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */ + /* Disable GPIO interrupt */ + irq_disable(gpio_irq); + return 0; +#ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT + } else if (mode == GPIO_INT_MODE_ENABLE_ONLY) { + /* Only enable GPIO interrupt */ + irq_enable(gpio_irq); + return 0; +#endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */ + } + + if (mode == GPIO_INT_MODE_LEVEL) { + LOG_ERR("Level trigger mode not supported"); + return -ENOTSUP; + } + + /* Disable irq before configuring it */ + irq_disable(gpio_irq); + + if (trig & GPIO_INT_TRIG_BOTH) { + volatile uint8_t *reg_base = (uint8_t *)gpio_config->wuc_base[pin]; + volatile uint8_t *reg_wuemr = reg_base; + volatile uint8_t *reg_wuesr = reg_base + 1; + volatile uint8_t *reg_wubemr = reg_base + 3; + uint8_t wuc_mask = gpio_config->wuc_mask[pin]; + + /* Set both edges interrupt. */ + if ((trig & GPIO_INT_TRIG_BOTH) == GPIO_INT_TRIG_BOTH) { + *reg_wubemr |= wuc_mask; + } else { + *reg_wubemr &= ~wuc_mask; + } + + if (trig & GPIO_INT_TRIG_LOW) { + *reg_wuemr |= wuc_mask; + } else { + *reg_wuemr &= ~wuc_mask; + } + /* + * Always write 1 to clear the WUC status register after + * modifying edge mode selection register (WUBEMR and WUEMR). + */ + *reg_wuesr = wuc_mask; + } + + /* Enable GPIO interrupt */ + irq_connect_dynamic(gpio_irq, 0, gpio_ite_isr, dev, 0); + irq_enable(gpio_irq); + + return 0; +} + +static const struct gpio_driver_api gpio_ite_driver_api = { + .pin_configure = gpio_ite_configure, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_ite_get_config, +#endif + .port_get_raw = gpio_ite_port_get_raw, + .port_set_masked_raw = gpio_ite_port_set_masked_raw, + .port_set_bits_raw = gpio_ite_port_set_bits_raw, + .port_clear_bits_raw = gpio_ite_port_clear_bits_raw, + .port_toggle_bits = gpio_ite_port_toggle_bits, + .pin_interrupt_configure = gpio_ite_pin_interrupt_configure, + .manage_callback = gpio_ite_manage_callback, +}; + +static int gpio_ite_init(const struct device *dev) +{ + return 0; +} + +#define GPIO_ITE_DEV_CFG_DATA(inst) \ +static struct gpio_ite_data gpio_ite_data_##inst; \ +static const struct gpio_ite_cfg gpio_ite_cfg_##inst = { \ + .common = { \ + .port_pin_mask = \ + GPIO_PORT_PIN_MASK_FROM_DT_INST(inst) \ + }, \ + .reg_gpdr = DT_INST_REG_ADDR_BY_IDX(inst, 0), \ + .reg_gpdmr = DT_INST_REG_ADDR_BY_IDX(inst, 1), \ + .reg_gpotr = DT_INST_REG_ADDR_BY_IDX(inst, 2), \ + .reg_p18scr = DT_INST_REG_ADDR_BY_IDX(inst, 3), \ + .reg_gpcr = DT_INST_REG_ADDR_BY_IDX(inst, 4), \ + .wuc_base = DT_INST_PROP_OR(inst, wuc_base, {0}), \ + .wuc_mask = DT_INST_PROP_OR(inst, wuc_mask, {0}), \ + .gpio_irq = IT8XXX2_DT_GPIO_IRQ_LIST(inst), \ + .has_volt_sel = DT_INST_PROP_OR(inst, has_volt_sel, {0}), \ + .num_pins = DT_INST_PROP(inst, ngpios), \ + }; \ +DEVICE_DT_INST_DEFINE(inst, \ + gpio_ite_init, \ + NULL, \ + &gpio_ite_data_##inst, \ + &gpio_ite_cfg_##inst, \ + PRE_KERNEL_1, \ + CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_ite_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_ITE_DEV_CFG_DATA) + +static int gpio_it8xxx2_init_set(void) +{ + if (IS_ENABLED(CONFIG_SOC_IT8XXX2_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN)) { + const struct device *const gpiok = DEVICE_DT_GET(DT_NODELABEL(gpiok)); + const struct device *const gpiol = DEVICE_DT_GET(DT_NODELABEL(gpiol)); + + for (int i = 0; i < 8; i++) { + gpio_pin_configure(gpiok, i, GPIO_INPUT | GPIO_PULL_DOWN); + gpio_pin_configure(gpiol, i, GPIO_INPUT | GPIO_PULL_DOWN); + } + } + + return 0; +} +SYS_INIT(gpio_it8xxx2_init_set, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY); diff --git a/dts/bindings/gpio/ite,it8xxx2-gpio-v2.yaml b/dts/bindings/gpio/ite,it8xxx2-gpio-v2.yaml new file mode 100644 index 00000000000..7c77e610a23 --- /dev/null +++ b/dts/bindings/gpio/ite,it8xxx2-gpio-v2.yaml @@ -0,0 +1,32 @@ +# Copyright (c) 2023 ITE Corporation. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +description: This binding gives a base representation of the ITE gpio + +compatible: "ite,it8xxx2-gpio-v2" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + has-volt-sel: + type: array + description: | + Selection of support input voltage 3.3V or 1.8V. + + wuc-base: + type: array + description: | + WUCs are mapped to the pins of GPIO. + The WUC groups internal and external inputs, and asserts + a wake-up signal to the INTC, allowing the CPU to exit + Doze/Deep Doze/Sleep modes. + + wuc-mask: + type: array + +gpio-cells: + - pin + - flags diff --git a/dts/riscv/ite/it82xx2.dtsi b/dts/riscv/ite/it82xx2.dtsi index 5eed3bb2777..189f0713787 100644 --- a/dts/riscv/ite/it82xx2.dtsi +++ b/dts/riscv/ite/it82xx2.dtsi @@ -29,6 +29,407 @@ reg = <0x00f03e00 0x2f>; }; + gpioa: gpio@f01601 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01601 1 /* GPDR (set) */ + 0x00f01618 1 /* GPDMR (get) */ + 0x00f01630 1 /* GPOTR */ + 0x00f01648 1 /* P18SCR */ + 0x00f01660 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b20 0xf01b20 0xf01b20 0xf01b1c + 0xf01b1c 0xf01b1c 0xf01b1c 0xf01b24>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpiob: gpio@f01602 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01602 1 /* GPDR (set) */ + 0x00f01619 1 /* GPDMR (get) */ + 0x00f01631 1 /* GPOTR */ + 0x00f01649 1 /* P18SCR */ + 0x00f01668 8>; /* GPCR */ + ngpios = <7>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b24 0xf01b24 0xf01b1c 0xf01b24 + 0xf01b20 0xf01b28 0xf01b28 NO_FUNC >; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 0>; + #gpio-cells = <2>; + }; + + gpioc: gpio@f01603 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01603 1 /* GPDR (set) */ + 0x00f0161a 1 /* GPDMR (get) */ + 0x00f01632 1 /* GPOTR */ + 0x00f0164a 1 /* P18SCR */ + 0x00f01670 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b1c 0xf01b28 0xf01b20 0xf01b28 + 0xf01b04 0xf01b28 0xf01b04 0xf01b1c>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpiod: gpio@f01604 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01604 1 /* GPDR (set) */ + 0x00f0161b 1 /* GPDMR (get) */ + 0x00f01633 1 /* GPOTR */ + 0x00f0164b 1 /* P18SCR */ + 0x00f01678 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b04 0xf01b04 0xf01b04 0xf01b28 + 0xf01b28 0xf01b2c 0xf01b2c 0xf01b1c>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpioe: gpio@f01605 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01605 1 /* GPDR (set) */ + 0x00f0161c 1 /* GPDMR (get) */ + 0x00f01634 1 /* GPOTR */ + 0x00f0164c 1 /* P18SCR */ + 0x00f01680 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b18 0xf01b18 0xf01b18 0xf01b18 + 0xf01b2c 0xf01b0c 0xf01b0c 0xf01b0c>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpiof: gpio@f01606 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01606 1 /* GPDR (set) */ + 0x00f0161d 1 /* GPDMR (get) */ + 0x00f01635 1 /* GPOTR */ + 0x00f0164d 1 /* P18SCR */ + 0x00f01688 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b24 0xf01b24 0xf01b24 0xf01b24 + 0xf01b14 0xf01b14 0xf01b14 0xf01b14>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpiog: gpio@f01607 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01607 1 /* GPDR (set) */ + 0x00f0161e 1 /* GPDMR (get) */ + 0x00f01636 1 /* GPOTR */ + 0x00f0164e 1 /* P18SCR */ + 0x00f01690 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b2c 0xf01b2c 0xf01b2c 0xf01b30 + 0xf01b30 0xf01b30 0xf01b2c 0xf01b30>; + wuc-mask = ; + has-volt-sel = <1 1 1 0 0 0 1 0>; + #gpio-cells = <2>; + }; + + gpioh: gpio@f01608 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01608 1 /* GPDR (set) */ + 0x00f0161f 1 /* GPDMR (get) */ + 0x00f01637 1 /* GPOTR */ + 0x00f0164f 1 /* P18SCR */ + 0x00f01698 8>; /* GPCR */ + ngpios = <7>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b14 0xf01b14 0xf01b14 0xf01b14 + 0xf01b20 0xf01b20 0xf01b20 NO_FUNC >; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 0>; + #gpio-cells = <2>; + }; + + gpioi: gpio@f01609 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01609 1 /* GPDR (set) */ + 0x00f01620 1 /* GPDMR (get) */ + 0x00f01638 1 /* GPOTR */ + 0x00f01650 1 /* P18SCR */ + 0x00f016a0 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b2c 0xf01b30 0xf01b30 0xf01b30 + 0xf01b18 0xf01b18 0xf01b18 0xf01b18>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpioj: gpio@f0160a { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f0160a 1 /* GPDR (set) */ + 0x00f01621 1 /* GPDMR (get) */ + 0x00f01639 1 /* GPOTR */ + 0x00f01651 1 /* P18SCR */ + 0x00f016a8 8>; /* GPCR */ + ngpios = <6>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b34 0xf01b34 0xf01b34 0xf01b34 + 0xf01b34 0xf01b34 NO_FUNC NO_FUNC >; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 0 0>; + #gpio-cells = <2>; + }; + + gpiok: gpio@f0160b { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f0160b 1 /* GPDR (set) */ + 0x00f01622 1 /* GPDMR (get) */ + 0x00f0163a 1 /* GPOTR */ + 0x00f01652 1 /* P18SCR */ + 0x00f016b0 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b10 0xf01b10 0xf01b10 0xf01b10 + 0xf01b10 0xf01b10 0xf01b10 0xf01b10>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpiol: gpio@f0160c { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f0160c 1 /* GPDR (set) */ + 0x00f01623 1 /* GPDMR (get) */ + 0x00f0163b 1 /* GPOTR */ + 0x00f01653 1 /* P18SCR */ + 0x00f016b8 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b38 0xf01b38 0xf01b38 0xf01b38 + 0xf01b38 0xf01b38 0xf01b38 0xf01b38>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; + + gpiom: gpio@f0160d { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f0160d 1 /* GPDR (set) */ + 0x00f01624 1 /* GPDMR (get) */ + 0x00f0163c 1 /* GPOTR */ + 0x00f01654 1 /* P18SCR */ + 0x00f016c0 8>; /* GPCR */ + ngpios = <7>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + wuc-base = <0xf01b3c 0xf01b3c 0xf01b3c 0xf01b3c + 0xf01b3c 0xf01b3c 0xf01b3c NO_FUNC >; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 0>; + #gpio-cells = <2>; + }; + + gpioksi: gpio@f01d08 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01d08 1 /* GPDR (set) */ + 0x00f01d09 1 /* GPDMR (get) */ + 0x00f01d2c 1 /* GPOTR */ + NO_FUNC 1 /* P18SCR */ + 0x00f01d40 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + #gpio-cells = <2>; + }; + + gpioksoh: gpio@f01d01 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01d01 1 /* GPDR (set) */ + 0x00f01d0c 1 /* GPDMR (get) */ + 0x00f01d2d 1 /* GPOTR */ + NO_FUNC 1 /* P18SCR */ + 0x00f01d50 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + #gpio-cells = <2>; + }; + + gpioksol: gpio@f01d00 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01d00 1 /* GPDR (set) */ + 0x00f01d0f 1 /* GPDMR (get) */ + 0x00f01d2e 1 /* GPOTR */ + NO_FUNC 1 /* P18SCR */ + 0x00f01d48 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = ; + interrupt-parent = <&intc>; + #gpio-cells = <2>; + }; + pinctrl: pin-controller { compatible = "ite,it8xxx2-pinctrl"; #address-cells = <1>; @@ -310,6 +711,166 @@ }; }; + wuc1: wakeup-controller@f01b00 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b00 1 /* WUEMR1 */ + 0x00f01b01 1 /* WUESR1 */ + 0x00f01b02 1 /* WUENR1 */ + 0x00f01b03 1>; /* WUBEMR1 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc2: wakeup-controller@f01b04 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b04 1 /* WUEMR2 */ + 0x00f01b05 1 /* WUESR2 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR2 */ + 0x00f01b07 1>; /* WUBEMR2 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc3: wakeup-controller@f01b08 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b08 1 /* WUEMR3 */ + 0x00f01b09 1 /* WUESR3 */ + 0x00f01b0a 1 /* WUENR3 */ + 0x00f01b0b 1>; /* WUBEMR3 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc4: wakeup-controller@f01b0c { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b0c 1 /* WUEMR4 */ + 0x00f01b0d 1 /* WUESR4 */ + 0x00f01b0e 1 /* WUENR4 */ + 0x00f01b0f 1>; /* WUBEMR4 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc5: wakeup-controller@f01b10 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b10 1 /* WUEMR5 */ + 0x00f01b11 1 /* WUESR5 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR5 */ + 0x00f01b13 1>; /* WUBEMR5 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc6: wakeup-controller@f01b14 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b14 1 /* WUEMR6 */ + 0x00f01b15 1 /* WUESR6 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR6 */ + 0x00f01b17 1>; /* WUBEMR6 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc7: wakeup-controller@f01b18 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b18 1 /* WUEMR7 */ + 0x00f01b19 1 /* WUESR7 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR7 */ + 0x00f01b1b 1>; /* WUBEMR7 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc8: wakeup-controller@f01b1c { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b1c 1 /* WUEMR8 */ + 0x00f01b1d 1 /* WUESR8 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR8 */ + 0x00f01b1f 1>; /* WUBEMR8 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc9: wakeup-controller@f01b20 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b20 1 /* WUEMR9 */ + 0x00f01b21 1 /* WUESR9 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR9 */ + 0x00f01b23 1>; /* WUBEMR9 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc10: wakeup-controller@f01b24 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b24 1 /* WUEMR10 */ + 0x00f01b25 1 /* WUESR10 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR10 */ + 0x00f01b27 1>; /* WUBEMR10 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc11: wakeup-controller@f01b28 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b28 1 /* WUEMR11 */ + 0x00f01b29 1 /* WUESR11 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR11 */ + 0x00f01b2b 1>; /* WUBEMR11 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc12: wakeup-controller@f01b2c { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b2c 1 /* WUEMR12 */ + 0x00f01b2d 1 /* WUESR12 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR12 */ + 0x00f01b2f 1>; /* WUBEMR12 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc13: wakeup-controller@f01b30 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b30 1 /* WUEMR13 */ + 0x00f01b31 1 /* WUESR13 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR13 */ + 0x00f01b33 1>; /* WUBEMR13 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc14: wakeup-controller@f01b34 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b34 1 /* WUEMR14 */ + 0x00f01b35 1 /* WUESR14 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR14 */ + 0x00f01b37 1>; /* WUBEMR14 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc15: wakeup-controller@f01b38 { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b38 1 /* WUEMR15 */ + 0x00f01b39 1 /* WUESR15 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR15 */ + 0x00f01b3b 1>; /* WUBEMR15 */ + wakeup-controller; + #wuc-cells = <1>; + }; + + wuc16: wakeup-controller@f01b3c { + compatible = "ite,it8xxx2-wuc"; + reg = <0x00f01b3c 1 /* WUEMR16 */ + 0x00f01b3d 1 /* WUESR16 */ + IT8XXX2_WUC_UNUSED_REG 1 /* WUENR16 */ + 0x00f01b3f 1>; /* WUBEMR16 */ + wakeup-controller; + #wuc-cells = <1>; + }; + i2c0: i2c@f04300 { compatible = "ite,enhance-i2c"; #address-cells = <1>; diff --git a/soc/riscv/riscv-ite/common/soc_dt.h b/soc/riscv/riscv-ite/common/soc_dt.h index d831c07588c..3be4ece0f38 100644 --- a/soc/riscv/riscv-ite/common/soc_dt.h +++ b/soc/riscv/riscv-ite/common/soc_dt.h @@ -63,4 +63,27 @@ inst) \ } +/** + * @brief Macro function to construct it8xxx2 GPIO IRQ in LISTIFY extension. + * + * @param idx index in LISTIFY extension. + * @param inst instance number for compatible defined in DT_DRV_COMPAT. + * @return an IRQ number of GPIO. + */ +#define IT8XXX2_DT_GPIO_IRQ_FUNC(idx, inst) \ + DT_INST_IRQ_BY_IDX(inst, idx, irq) + +/** + * @brief Macro function to construct a list of it8xxx2 GPIO IRQ number + * with compatible defined in DT_DRV_COMPAT by LISTIFY func. + * + * @param inst instance number for compatible defined in DT_DRV_COMPAT. + * @return an array of GPIO IRQ number. + */ +#define IT8XXX2_DT_GPIO_IRQ_LIST(inst) { \ + LISTIFY(DT_INST_PROP(inst, ngpios), \ + IT8XXX2_DT_GPIO_IRQ_FUNC, (,), \ + inst) \ + } + #endif /* _ITE_IT8XXX2_SOC_DT_H_ */