drivers: gpio: add rzt2m gpio driver
Add Renesas rzt2m gpio driver with basic functionality. It supports pin mode configuration and writing/reading to/from gpio ports. Includes dts changes to build blinky sample. Signed-off-by: Jakub Michalski <jmichalski@internships.antmicro.com>
This commit is contained in:
parent
9e44f59e9a
commit
9265d2de0c
|
@ -17,6 +17,30 @@
|
|||
zephyr,console = &uart0;
|
||||
zephyr,shell-uart = &uart0;
|
||||
};
|
||||
|
||||
aliases {
|
||||
led0 = &led0;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
led0: led0 {
|
||||
gpios = <&gpio19 6 0>;
|
||||
label = "led0";
|
||||
};
|
||||
led1: led1 {
|
||||
gpios = <&gpio19 4 0>;
|
||||
label = "led1";
|
||||
};
|
||||
led2: led2 {
|
||||
gpios = <&gpio20 0 0>;
|
||||
label = "led2";
|
||||
};
|
||||
led3: led3 {
|
||||
gpios = <&gpio23 4 0>;
|
||||
label = "led3";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_SEDI gpio_sedi.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GPIO_ALTERA_PIO gpio_altera_pio.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_RA gpio_ra.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_RZT2M gpio_rzt2m.c)
|
||||
|
||||
if (CONFIG_GPIO_EMUL_SDL)
|
||||
zephyr_library_sources(gpio_emul_sdl.c)
|
||||
|
|
|
@ -214,4 +214,6 @@ source "drivers/gpio/Kconfig.bcm2711"
|
|||
|
||||
source "drivers/gpio/Kconfig.ra"
|
||||
|
||||
source "drivers/gpio/Kconfig.rzt2m"
|
||||
|
||||
endif # GPIO
|
||||
|
|
9
drivers/gpio/Kconfig.rzt2m
Normal file
9
drivers/gpio/Kconfig.rzt2m
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config GPIO_RZT2M
|
||||
bool "Renesas RZT2M GPIO"
|
||||
default y
|
||||
depends on DT_HAS_RENESAS_RZT2M_GPIO_ENABLED
|
||||
help
|
||||
Enable Renesas RZT2M GPIO driver.
|
233
drivers/gpio/gpio_rzt2m.c
Normal file
233
drivers/gpio/gpio_rzt2m.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT renesas_rzt2m_gpio
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/gpio/gpio_utils.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/errno_private.h>
|
||||
#include <zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h>
|
||||
#include <soc.h>
|
||||
|
||||
#define PMm_OFFSET 0x200
|
||||
#define PINm_OFFSET 0x800
|
||||
#define DRCTLm_OFFSET 0xa00
|
||||
|
||||
#define DRIVE_SHIFT 0
|
||||
#define SCHMITT_TRIGGER_SHIFT 4
|
||||
#define SLEW_RATE_SHIFT 5
|
||||
|
||||
#define PULL_SHIFT 2
|
||||
#define PULL_NONE (0 << PULL_SHIFT)
|
||||
#define PULL_UP (1 << PULL_SHIFT)
|
||||
#define PULL_DOWN (2 << PULL_SHIFT)
|
||||
|
||||
struct rzt2m_gpio_config {
|
||||
struct gpio_driver_config common;
|
||||
uint8_t *port_nsr;
|
||||
uint8_t *ptadr;
|
||||
uint8_t port;
|
||||
};
|
||||
|
||||
struct rzt2m_gpio_data {
|
||||
struct gpio_driver_data common;
|
||||
};
|
||||
|
||||
static void rzt2m_gpio_unlock(void)
|
||||
{
|
||||
rzt2m_unlock_prcrn(PRCRN_PRC1);
|
||||
rzt2m_unlock_prcrs(PRCRS_GPIO);
|
||||
}
|
||||
|
||||
static void rzt2m_gpio_lock(void)
|
||||
{
|
||||
rzt2m_lock_prcrn(PRCRN_PRC1);
|
||||
rzt2m_lock_prcrs(PRCRS_GPIO);
|
||||
}
|
||||
|
||||
/* Port m output data store */
|
||||
static volatile uint8_t *rzt2m_gpio_get_p_reg(const struct device *dev)
|
||||
{
|
||||
const struct rzt2m_gpio_config *config = dev->config;
|
||||
|
||||
return (volatile uint8_t *)(config->port_nsr + config->port);
|
||||
}
|
||||
|
||||
/* Port m input data store */
|
||||
static volatile uint8_t *rzt2m_gpio_get_pin_reg(const struct device *dev)
|
||||
{
|
||||
const struct rzt2m_gpio_config *config = dev->config;
|
||||
|
||||
return (volatile uint8_t *)(config->port_nsr + PINm_OFFSET + config->port);
|
||||
}
|
||||
|
||||
/* Port m mode register */
|
||||
static volatile uint16_t *rzt2m_gpio_get_pm_reg(const struct device *dev)
|
||||
{
|
||||
const struct rzt2m_gpio_config *config = dev->config;
|
||||
|
||||
return (volatile uint16_t *)(config->port_nsr + PMm_OFFSET + 0x2 * config->port);
|
||||
}
|
||||
|
||||
/* IO Buffer m function switching register */
|
||||
static volatile uint64_t *rzt2m_gpio_get_drctl_reg(const struct device *dev)
|
||||
{
|
||||
const struct rzt2m_gpio_config *config = dev->config;
|
||||
|
||||
return (volatile uint64_t *)(config->port_nsr + DRCTLm_OFFSET + 0x8 * config->port);
|
||||
}
|
||||
|
||||
/* Port m region select register */
|
||||
static volatile uint8_t *rzt2m_gpio_get_rselp_reg(const struct device *dev)
|
||||
{
|
||||
const struct rzt2m_gpio_config *config = dev->config;
|
||||
|
||||
return (volatile uint8_t *)(config->ptadr + config->port);
|
||||
}
|
||||
|
||||
static int rzt2m_gpio_init(const struct device *dev)
|
||||
{
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
volatile uint8_t *rselp_reg = rzt2m_gpio_get_rselp_reg(dev);
|
||||
*rselp_reg = 0xFF;
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzt2m_gpio_get_raw(const struct device *dev, gpio_port_value_t *value)
|
||||
{
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
volatile uint8_t *pin_reg = rzt2m_gpio_get_pin_reg(dev);
|
||||
*value = *pin_reg;
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzt2m_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
|
||||
gpio_port_value_t value)
|
||||
{
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
|
||||
*p_reg = (*p_reg & ~mask) | (value & mask);
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzt2m_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
|
||||
*p_reg |= pins;
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzt2m_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
|
||||
*p_reg &= ~pins;
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzt2m_gpio_toggle(const struct device *dev, gpio_port_pins_t pins)
|
||||
{
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
volatile uint8_t *p_reg = rzt2m_gpio_get_p_reg(dev);
|
||||
*p_reg ^= pins;
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzt2m_gpio_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
|
||||
{
|
||||
volatile uint16_t *pm_reg = rzt2m_gpio_get_pm_reg(dev);
|
||||
volatile uint64_t *drctl_reg = rzt2m_gpio_get_drctl_reg(dev);
|
||||
|
||||
rzt2m_gpio_unlock();
|
||||
|
||||
WRITE_BIT(*pm_reg, pin * 2, flags & GPIO_INPUT);
|
||||
WRITE_BIT(*pm_reg, pin * 2 + 1, flags & GPIO_OUTPUT);
|
||||
|
||||
if (flags & GPIO_OUTPUT) {
|
||||
if (flags & GPIO_OUTPUT_INIT_LOW) {
|
||||
rzt2m_port_clear_bits_raw(dev, 1 << pin);
|
||||
} else if (flags & GPIO_OUTPUT_INIT_HIGH) {
|
||||
rzt2m_port_set_bits_raw(dev, 1 << pin);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & GPIO_PULL_UP && flags & GPIO_PULL_DOWN) {
|
||||
rzt2m_gpio_lock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uint8_t drctl_pin_config = 0;
|
||||
|
||||
if (flags & GPIO_PULL_UP) {
|
||||
drctl_pin_config |= PULL_UP;
|
||||
} else if (flags & GPIO_PULL_DOWN) {
|
||||
drctl_pin_config |= PULL_DOWN;
|
||||
} else {
|
||||
drctl_pin_config |= PULL_NONE;
|
||||
}
|
||||
|
||||
drctl_pin_config |=
|
||||
(flags & RZT2M_GPIO_DRIVE_MASK) >> (RZT2M_GPIO_DRIVE_OFFSET - DRIVE_SHIFT);
|
||||
drctl_pin_config |= (flags & RZT2M_GPIO_SCHMITT_TRIGGER_MASK) >>
|
||||
(RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET - SCHMITT_TRIGGER_SHIFT);
|
||||
drctl_pin_config |= (flags & RZT2M_GPIO_SLEW_RATE_MASK) >>
|
||||
(RZT2M_GPIO_SLEW_RATE_OFFSET - SLEW_RATE_SHIFT);
|
||||
|
||||
uint64_t drctl_pin_value = *drctl_reg & ~(0xFFULL << (pin * 8));
|
||||
*drctl_reg = drctl_pin_value | ((uint64_t)drctl_pin_config << (pin * 8));
|
||||
|
||||
rzt2m_gpio_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct gpio_driver_api rzt2m_gpio_driver_api = {
|
||||
.pin_configure = rzt2m_gpio_configure,
|
||||
.port_get_raw = rzt2m_gpio_get_raw,
|
||||
.port_set_masked_raw = rzt2m_port_set_masked_raw,
|
||||
.port_set_bits_raw = rzt2m_port_set_bits_raw,
|
||||
.port_clear_bits_raw = rzt2m_port_clear_bits_raw,
|
||||
.port_toggle_bits = rzt2m_gpio_toggle};
|
||||
|
||||
#define RZT2M_GPIO_DEFINE(inst) \
|
||||
static struct rzt2m_gpio_data rzt2m_gpio_data##inst; \
|
||||
static struct rzt2m_gpio_config rzt2m_gpio_config##inst = { \
|
||||
.port_nsr = (uint8_t *)DT_REG_ADDR_BY_NAME(DT_INST_PARENT(inst), port_nsr), \
|
||||
.ptadr = (uint8_t *)DT_REG_ADDR_BY_NAME(DT_INST_PARENT(inst), ptadr), \
|
||||
.port = DT_INST_REG_ADDR(inst), \
|
||||
.common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)}}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, rzt2m_gpio_init, NULL, &rzt2m_gpio_data##inst, \
|
||||
&rzt2m_gpio_config##inst, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \
|
||||
&rzt2m_gpio_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(RZT2M_GPIO_DEFINE)
|
|
@ -117,6 +117,32 @@
|
|||
compatible = "renesas,rzt2m-pinctrl";
|
||||
reg = <0x800a0000 0x1000 0x81030c00 0x1000>;
|
||||
reg-names = "port_nsr", "ptadr";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gpio19: gpio@13 {
|
||||
compatible = "renesas,rzt2m-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <8>;
|
||||
reg = <0x13>;
|
||||
};
|
||||
|
||||
gpio20: gpio@14 {
|
||||
compatible = "renesas,rzt2m-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <8>;
|
||||
reg = <0x14>;
|
||||
};
|
||||
|
||||
gpio23: gpio@17 {
|
||||
compatible = "renesas,rzt2m-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
ngpios = <8>;
|
||||
reg = <0x17>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
18
dts/bindings/gpio/renesas,rzt2m-gpio.yaml
Normal file
18
dts/bindings/gpio/renesas,rzt2m-gpio.yaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
description: Renesas RZT2M GPIO
|
||||
|
||||
compatible: "renesas,rzt2m-gpio"
|
||||
|
||||
include: [gpio-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
gpio-cells:
|
||||
- pin
|
||||
- flags
|
39
include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h
Normal file
39
include/zephyr/dt-bindings/gpio/renesas-rzt2m-gpio.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZT2M_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZT2M_H_
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
#define RZT2M_GPIO_DRIVE_OFFSET 8
|
||||
#define RZT2M_GPIO_DRIVE_MASK GENMASK(RZT2M_GPIO_DRIVE_OFFSET + 2, RZT2M_GPIO_DRIVE_OFFSET)
|
||||
|
||||
/**
|
||||
* @brief Select GPIO pin drive strength
|
||||
*/
|
||||
#define RZT2M_GPIO_DRIVE_LOW (0U << RZT2M_GPIO_DRIVE_OFFSET)
|
||||
#define RZT2M_GPIO_DRIVE_MIDDLE (1U << RZT2M_GPIO_DRIVE_OFFSET)
|
||||
#define RZT2M_GPIO_DRIVE_HIGH (2U << RZT2M_GPIO_DRIVE_OFFSET)
|
||||
#define RZT2M_GPIO_DRIVE_ULTRA_HIGH (3U << RZT2M_GPIO_DRIVE_OFFSET)
|
||||
|
||||
#define RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET 10
|
||||
#define RZT2M_GPIO_SCHMITT_TRIGGER_MASK BIT(RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET)
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin schmitt trigger
|
||||
*/
|
||||
#define RZT2M_GPIO_SCHMITT_TRIGGER BIT(RZT2M_GPIO_SCHMITT_TRIGGER_OFFSET)
|
||||
|
||||
#define RZT2M_GPIO_SLEW_RATE_OFFSET 11
|
||||
#define RZT2M_GPIO_SLEW_RATE_MASK BIT(RZT2M_GPIO_SLEW_RATE_OFFSET)
|
||||
|
||||
/**
|
||||
* @brief Select GPIO pin slew rate
|
||||
*/
|
||||
#define RZT2M_GPIO_SLEW_RATE_SLOW 0U
|
||||
#define RZT2M_GPIO_SLEW_RATE_FAST BIT(RZT2M_GPIO_SLEW_RATE_OFFSET)
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_RENESAS_RZT2M_H_ */
|
Loading…
Reference in a new issue