From 31baddaa51d5b40e6e6394b8be6cb32e1e962f08 Mon Sep 17 00:00:00 2001 From: Junho Lee Date: Thu, 21 Mar 2024 13:18:44 +0900 Subject: [PATCH] drivers: gpio: add brcmstb gpio driver Add GPIO driver for brcmstb, required by Raspberry Pi 5. Signed-off-by: Junho Lee --- drivers/gpio/CMakeLists.txt | 1 + drivers/gpio/Kconfig | 2 + drivers/gpio/Kconfig.brcmstb | 9 ++ drivers/gpio/gpio_brcmstb.c | 141 +++++++++++++++++++++++ dts/bindings/gpio/brcm,brcmstb-gpio.yaml | 19 +++ 5 files changed, 172 insertions(+) create mode 100644 drivers/gpio/Kconfig.brcmstb create mode 100644 drivers/gpio/gpio_brcmstb.c create mode 100644 dts/bindings/gpio/brcm,brcmstb-gpio.yaml diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 2143d019cb..13620ab984 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -92,6 +92,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_RENESAS_RA gpio_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_GPIO_ENE_KB1200 gpio_ene_kb1200.c) zephyr_library_sources_ifdef(CONFIG_GPIO_RZT2M gpio_rzt2m.c) zephyr_library_sources_ifdef(CONFIG_GPIO_AMBIQ gpio_ambiq.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_BRCMSTB gpio_brcmstb.c) if (CONFIG_GPIO_EMUL_SDL) zephyr_library_sources(gpio_emul_sdl.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 2ca6da678c..c6e19c5b78 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -242,4 +242,6 @@ source "drivers/gpio/Kconfig.rzt2m" source "drivers/gpio/Kconfig.ambiq" +source "drivers/gpio/Kconfig.brcmstb" + endif # GPIO diff --git a/drivers/gpio/Kconfig.brcmstb b/drivers/gpio/Kconfig.brcmstb new file mode 100644 index 0000000000..0974f05239 --- /dev/null +++ b/drivers/gpio/Kconfig.brcmstb @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Junho Lee +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_BRCMSTB + bool "Broadcom Set-top box SoC GPIO Driver" + default y + depends on DT_HAS_BRCM_BRCMSTB_GPIO_ENABLED + help + Enable Driver for Broadcom Set-top box SoC GPIO Banks. diff --git a/drivers/gpio/gpio_brcmstb.c b/drivers/gpio/gpio_brcmstb.c new file mode 100644 index 0000000000..cfec6868f2 --- /dev/null +++ b/drivers/gpio/gpio_brcmstb.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2024 Junho Lee + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT brcm_brcmstb_gpio + +#include +#include +#include +#include +#include + +#define GIO_DATA 0x04 +#define GIO_IODIR 0x08 + +#define DEV_CFG(dev) ((const struct gpio_brcmstb_config *)(dev)->config) +#define DEV_DATA(dev) ((struct gpio_brcmstb_data *)(dev)->data) + +struct gpio_brcmstb_config { + struct gpio_driver_config common; + + DEVICE_MMIO_NAMED_ROM(reg_base); + mem_addr_t offset; +}; + +struct gpio_brcmstb_data { + struct gpio_driver_data common; + + DEVICE_MMIO_NAMED_RAM(reg_base); + mem_addr_t base; +}; + +static int gpio_brcmstb_pin_configure(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + struct gpio_brcmstb_data *data = port->data; + + if (flags & (GPIO_SINGLE_ENDED | GPIO_PULL_UP | GPIO_PULL_DOWN)) { + return -ENOTSUP; + } + + if (flags & GPIO_INPUT) { + sys_set_bit(data->base + GIO_IODIR, pin); + } else if (flags & GPIO_OUTPUT) { + sys_clear_bit(data->base + GIO_IODIR, pin); + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + sys_set_bit(data->base + GIO_DATA, pin); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + sys_clear_bit(data->base + GIO_DATA, pin); + } + } + + return 0; +} + +static int gpio_brcmstb_port_get_raw(const struct device *port, gpio_port_value_t *value) +{ + struct gpio_brcmstb_data *data = port->data; + + *value = sys_read32(data->base + GIO_DATA); + + return 0; +} + +static int gpio_brcmstb_port_set_masked_raw(const struct device *port, gpio_port_pins_t mask, + gpio_port_value_t value) +{ + struct gpio_brcmstb_data *data = port->data; + + sys_clear_bits(data->base + GIO_DATA, mask); + sys_set_bits(data->base + GIO_DATA, (value & mask)); + + return 0; +} + +static int gpio_brcmstb_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + struct gpio_brcmstb_data *data = port->data; + + sys_set_bits(data->base + GIO_DATA, pins); + + return 0; +} + +static int gpio_brcmstb_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins) +{ + struct gpio_brcmstb_data *data = port->data; + + sys_clear_bits(data->base + GIO_DATA, pins); + + return 0; +} + +static int gpio_brcmstb_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) +{ + struct gpio_brcmstb_data *data = port->data; + uint32_t reg_data; + + reg_data = sys_read32(data->base + GIO_DATA); + reg_data ^= pins; + sys_write32(reg_data, data->base + GIO_DATA); + + return 0; +} + +static const struct gpio_driver_api gpio_brcmstb_api = { + .pin_configure = gpio_brcmstb_pin_configure, + .port_get_raw = gpio_brcmstb_port_get_raw, + .port_set_masked_raw = gpio_brcmstb_port_set_masked_raw, + .port_set_bits_raw = gpio_brcmstb_port_set_bits_raw, + .port_clear_bits_raw = gpio_brcmstb_port_clear_bits_raw, + .port_toggle_bits = gpio_brcmstb_port_toggle_bits, +}; + +int gpio_brcmstb_init(const struct device *port) +{ + const struct gpio_brcmstb_config *config = port->config; + struct gpio_brcmstb_data *data = port->data; + + DEVICE_MMIO_NAMED_MAP(port, reg_base, K_MEM_CACHE_NONE); + data->base = DEVICE_MMIO_NAMED_GET(port, reg_base) + config->offset; + + return 0; +} + +#define GPIO_BRCMSTB_INIT(n) \ + static struct gpio_brcmstb_data gpio_brcmstb_data_##n; \ + \ + static const struct gpio_brcmstb_config gpio_brcmstb_cfg_##n = { \ + .common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0)}, \ + DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_INST_PARENT(n)), \ + .offset = DT_INST_REG_ADDR(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, gpio_brcmstb_init, NULL, &gpio_brcmstb_data_##n, \ + &gpio_brcmstb_cfg_##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \ + &gpio_brcmstb_api); + +DT_INST_FOREACH_STATUS_OKAY(GPIO_BRCMSTB_INIT) diff --git a/dts/bindings/gpio/brcm,brcmstb-gpio.yaml b/dts/bindings/gpio/brcm,brcmstb-gpio.yaml new file mode 100644 index 0000000000..55f58a9f3f --- /dev/null +++ b/dts/bindings/gpio/brcm,brcmstb-gpio.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Junho Lee +# SPDX-License-Identifier: Apache-2.0 + +description: BRCMSTB GPIO + +compatible: "brcm,brcmstb-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags