|
|
|
@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2024 Renesas Electronics Corporation |
|
|
|
|
* Copyright (c) 2024-2025 Renesas Electronics Corporation |
|
|
|
|
* |
|
|
|
|
* SPDX-License-Identifier: Apache-2.0 |
|
|
|
|
*/ |
|
|
|
@ -15,6 +15,10 @@
@@ -15,6 +15,10 @@
|
|
|
|
|
#include <zephyr/drivers/gpio/gpio_utils.h> |
|
|
|
|
#include "gpio_renesas_rz.h" |
|
|
|
|
#include <zephyr/logging/log.h> |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
#include "r_icu.h" |
|
|
|
|
#include <zephyr/drivers/interrupt_controller/intc_rz_ext_irq.h> |
|
|
|
|
#endif |
|
|
|
|
LOG_MODULE_REGISTER(rz_gpio, CONFIG_GPIO_LOG_LEVEL); |
|
|
|
|
|
|
|
|
|
#define LOG_DEV_ERR(dev, format, ...) LOG_ERR("%s:" #format, (dev)->name, ##__VA_ARGS__) |
|
|
|
@ -28,7 +32,12 @@ struct gpio_rz_config {
@@ -28,7 +32,12 @@ struct gpio_rz_config {
|
|
|
|
|
const ioport_cfg_t *fsp_cfg; |
|
|
|
|
const ioport_api_t *fsp_api; |
|
|
|
|
const struct device *int_dev; |
|
|
|
|
uint8_t tint_num[GPIO_RZ_MAX_TINT_NUM]; |
|
|
|
|
uint8_t int_num[GPIO_RZ_MAX_INT_NUM]; |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
const struct device *eirq_dev[GPIO_RZ_MAX_INT_NUM]; |
|
|
|
|
|
|
|
|
|
void (*cb_list[GPIO_RZ_MAX_INT_NUM])(void *arg); |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct gpio_rz_data { |
|
|
|
@ -36,15 +45,18 @@ struct gpio_rz_data {
@@ -36,15 +45,18 @@ struct gpio_rz_data {
|
|
|
|
|
sys_slist_t cb; |
|
|
|
|
ioport_instance_ctrl_t *fsp_ctrl; |
|
|
|
|
struct k_spinlock lock; |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
uint8_t pin[GPIO_RZ_MAX_INT_NUM]; |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct gpio_rz_tint_isr_data { |
|
|
|
|
struct gpio_rz_isr_data { |
|
|
|
|
const struct device *gpio_dev; |
|
|
|
|
gpio_pin_t pin; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct gpio_rz_tint_data { |
|
|
|
|
struct gpio_rz_tint_isr_data tint_data[GPIO_RZ_MAX_TINT_NUM]; |
|
|
|
|
struct gpio_rz_int_data { |
|
|
|
|
struct gpio_rz_isr_data gpio_mapping[GPIO_RZ_MAX_INT_NUM]; |
|
|
|
|
uint32_t irq_set_edge; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -70,18 +82,12 @@ static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, uint32_t *flag
@@ -70,18 +82,12 @@ static int gpio_rz_pin_config_get_raw(bsp_io_port_pin_t port_pin, uint32_t *flag
|
|
|
|
|
{ |
|
|
|
|
bsp_io_port_t port = (port_pin >> 8U) & 0xFF; |
|
|
|
|
gpio_pin_t pin = port_pin & 0xFF; |
|
|
|
|
volatile uint8_t *p_p = GPIO_RZ_IOPORT_P_REG_BASE_GET; |
|
|
|
|
volatile uint16_t *p_pm = GPIO_RZ_IOPORT_PM_REG_BASE_GET; |
|
|
|
|
volatile uint8_t *p_p = GPIO_RZ_IOPORT_P_REG_GET(port, pin); |
|
|
|
|
volatile uint16_t *p_pm = GPIO_RZ_IOPORT_PM_REG_GET(port, pin); |
|
|
|
|
|
|
|
|
|
uint8_t adr_offset; |
|
|
|
|
uint8_t p_value; |
|
|
|
|
uint16_t pm_value; |
|
|
|
|
|
|
|
|
|
adr_offset = (uint8_t)GPIO_RZ_REG_OFFSET(port, pin); |
|
|
|
|
|
|
|
|
|
p_p = &p_p[adr_offset]; |
|
|
|
|
p_pm = &p_pm[adr_offset]; |
|
|
|
|
|
|
|
|
|
p_value = GPIO_RZ_P_VALUE_GET(*p_p, pin); |
|
|
|
|
pm_value = GPIO_RZ_PM_VALUE_GET(*p_pm, pin); |
|
|
|
|
|
|
|
|
@ -108,7 +114,11 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
@@ -108,7 +114,11 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
|
|
|
|
|
|
|
|
|
|
if (!flags) { |
|
|
|
|
/* Disconnect mode */ |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
GPIO_RZ_PIN_DISCONNECT(config->fsp_port, pin); |
|
|
|
|
#elif defined(CONFIG_SOC_SERIES_RZG3S) |
|
|
|
|
ioport_config_data = 0; |
|
|
|
|
#endif /* CONFIG_SOC_SERIES_* */ |
|
|
|
|
} else if (!(flags & GPIO_OPEN_DRAIN)) { |
|
|
|
|
/* PM register */ |
|
|
|
|
ioport_config_data &= GPIO_RZ_PIN_CONFIGURE_INPUT_OUTPUT_RESET; |
|
|
|
@ -136,7 +146,7 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
@@ -136,7 +146,7 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
|
|
|
|
|
if (flags & GPIO_PULL_UP) { |
|
|
|
|
ioport_config_data |= IOPORT_CFG_PULLUP_ENABLE; |
|
|
|
|
} else if (flags & GPIO_PULL_DOWN) { |
|
|
|
|
ioport_config_data |= IOPORT_CFG_PULLUP_ENABLE; |
|
|
|
|
ioport_config_data |= IOPORT_CFG_PULLDOWN_ENABLE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* ISEL register */ |
|
|
|
@ -147,10 +157,14 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
@@ -147,10 +157,14 @@ static int gpio_rz_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Drive Ability register */ |
|
|
|
|
ioport_config_data |= GPIO_RZ_PIN_CONFIGURE_GET_DRIVE_ABILITY(flags); |
|
|
|
|
|
|
|
|
|
ioport_config_data |= GPIO_RZ_PIN_CONFIGURE_GET(flags); |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZG3S) |
|
|
|
|
/* Filter register, see in renesas-rz-gpio-ioport.h */ |
|
|
|
|
ioport_config_data |= GPIO_RZ_PIN_CONFIGURE_GET_FILTER(flags); |
|
|
|
|
#elif defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
/* RSEL reg */ |
|
|
|
|
ioport_config_data |= IOPORT_CFG_REGION_NSAFETY; |
|
|
|
|
#endif /* CONFIG_SOC_SERIES_* */ |
|
|
|
|
} else { |
|
|
|
|
return -ENOTSUP; |
|
|
|
|
} |
|
|
|
@ -251,60 +265,92 @@ static int gpio_rz_port_toggle_bits(const struct device *dev, gpio_port_pins_t p
@@ -251,60 +265,92 @@ static int gpio_rz_port_toggle_bits(const struct device *dev, gpio_port_pins_t p
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define GPIO_RZ_HAS_INTERRUPT DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_gpio_int) |
|
|
|
|
#define GPIO_RZ_HAS_INTERRUPT \ |
|
|
|
|
DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_gpio_int) | \ |
|
|
|
|
DT_HAS_COMPAT_STATUS_OKAY(renesas_rz_ext_irq) |
|
|
|
|
|
|
|
|
|
#if GPIO_RZ_HAS_INTERRUPT |
|
|
|
|
static int gpio_rz_int_disable(const struct device *dev, uint8_t tint_num) |
|
|
|
|
static int gpio_rz_int_disable(const struct device *dev, const struct device *gpio_dev, |
|
|
|
|
uint8_t int_num, gpio_pin_t pin) |
|
|
|
|
{ |
|
|
|
|
struct gpio_rz_tint_data *data = dev->data; |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZG3S) |
|
|
|
|
volatile uint32_t *tssr = &R_INTC_IM33->TSSR0; |
|
|
|
|
volatile uint32_t *titsr = &R_INTC_IM33->TITSR0; |
|
|
|
|
volatile uint32_t *tscr = &R_INTC_IM33->TSCR; |
|
|
|
|
struct gpio_rz_int_data *data = dev->data; |
|
|
|
|
|
|
|
|
|
/* Get register offset base on interrupt number. */ |
|
|
|
|
tssr = &tssr[tint_num / 4]; |
|
|
|
|
titsr = &titsr[tint_num / 16]; |
|
|
|
|
tssr = &tssr[int_num / 4]; |
|
|
|
|
titsr = &titsr[int_num / 16]; |
|
|
|
|
|
|
|
|
|
irq_disable(GPIO_RZ_TINT_IRQ_GET(tint_num)); |
|
|
|
|
irq_disable(GPIO_RZ_TINT_IRQ_GET(int_num)); |
|
|
|
|
/* Disable interrupt and clear interrupt source. */ |
|
|
|
|
*tssr &= ~(0xFF << GPIO_RZ_TSSR_OFFSET(tint_num)); |
|
|
|
|
*tssr &= ~(0xFF << GPIO_RZ_TSSR_OFFSET(int_num)); |
|
|
|
|
/* Reset interrupt dectect type to default. */ |
|
|
|
|
*titsr &= ~(0x3 << GPIO_RZ_TITSR_OFFSET(tint_num)); |
|
|
|
|
*titsr &= ~(0x3 << GPIO_RZ_TITSR_OFFSET(int_num)); |
|
|
|
|
|
|
|
|
|
/* Clear interrupt detection status. */ |
|
|
|
|
if (data->irq_set_edge & BIT(tint_num)) { |
|
|
|
|
*tscr &= ~BIT(tint_num); |
|
|
|
|
data->irq_set_edge &= ~BIT(tint_num); |
|
|
|
|
if (data->irq_set_edge & BIT(int_num)) { |
|
|
|
|
*tscr &= ~BIT(int_num); |
|
|
|
|
data->irq_set_edge &= ~BIT(int_num); |
|
|
|
|
} |
|
|
|
|
data->tint_data[tint_num].gpio_dev = NULL; |
|
|
|
|
data->tint_data[tint_num].pin = UINT8_MAX; |
|
|
|
|
|
|
|
|
|
data->gpio_mapping[int_num].gpio_dev = NULL; |
|
|
|
|
data->gpio_mapping[int_num].pin = UINT8_MAX; |
|
|
|
|
#elif defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
const struct gpio_rz_config *gpio_config = gpio_dev->config; |
|
|
|
|
const struct device *eirq_dev = gpio_config->eirq_dev[pin]; |
|
|
|
|
|
|
|
|
|
if (device_is_ready(eirq_dev)) { |
|
|
|
|
intc_rz_ext_irq_disable(eirq_dev); |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_SOC_SERIES_* */ |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int gpio_rz_int_enable(const struct device *int_dev, const struct device *gpio_dev, |
|
|
|
|
uint8_t tint_num, uint8_t irq_type, gpio_pin_t pin) |
|
|
|
|
uint8_t int_num, uint8_t irq_type, gpio_pin_t pin) |
|
|
|
|
{ |
|
|
|
|
struct gpio_rz_tint_data *int_data = int_dev->data; |
|
|
|
|
if (irq_type == GPIO_RZ_INT_UNSUPPORTED) { |
|
|
|
|
return -ENOTSUP; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const struct gpio_rz_config *gpio_config = gpio_dev->config; |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZG3S) |
|
|
|
|
volatile uint32_t *tssr = &R_INTC_IM33->TSSR0; |
|
|
|
|
volatile uint32_t *titsr = &R_INTC_IM33->TITSR0; |
|
|
|
|
struct gpio_rz_int_data *int_data = int_dev->data; |
|
|
|
|
|
|
|
|
|
tssr = &tssr[tint_num / 4]; |
|
|
|
|
titsr = &titsr[tint_num / 16]; |
|
|
|
|
tssr = &tssr[int_num / 4]; |
|
|
|
|
titsr = &titsr[int_num / 16]; |
|
|
|
|
/* Select interrupt detect type. */ |
|
|
|
|
*titsr |= (irq_type << GPIO_RZ_TITSR_OFFSET(tint_num)); |
|
|
|
|
*titsr &= ~(3U << GPIO_RZ_TITSR_OFFSET(int_num)); |
|
|
|
|
*titsr |= (irq_type << GPIO_RZ_TITSR_OFFSET(int_num)); |
|
|
|
|
/* Select interrupt source base on port and pin number.*/ |
|
|
|
|
*tssr |= (GPIO_RZ_TSSR_VAL(gpio_config->port_num, pin)) << GPIO_RZ_TSSR_OFFSET(tint_num); |
|
|
|
|
*tssr |= (GPIO_RZ_TSSR_VAL(gpio_config->port_num, pin)) << GPIO_RZ_TSSR_OFFSET(int_num); |
|
|
|
|
|
|
|
|
|
if (irq_type == GPIO_RZ_TINT_EDGE_RISING || irq_type == GPIO_RZ_TINT_EDGE_FALLING) { |
|
|
|
|
int_data->irq_set_edge |= BIT(tint_num); |
|
|
|
|
if (irq_type == GPIO_RZ_INT_EDGE_RISING || irq_type == GPIO_RZ_INT_EDGE_FALLING) { |
|
|
|
|
int_data->irq_set_edge |= BIT(int_num); |
|
|
|
|
/* Clear interrupt status. */ |
|
|
|
|
R_INTC_IM33->TSCR &= ~BIT(tint_num); |
|
|
|
|
R_INTC_IM33->TSCR &= ~BIT(int_num); |
|
|
|
|
} |
|
|
|
|
int_data->tint_data[tint_num].gpio_dev = gpio_dev; |
|
|
|
|
int_data->tint_data[tint_num].pin = pin; |
|
|
|
|
irq_enable(GPIO_RZ_TINT_IRQ_GET(tint_num)); |
|
|
|
|
irq_enable(GPIO_RZ_TINT_IRQ_GET(int_num)); |
|
|
|
|
int_data->gpio_mapping[int_num].gpio_dev = gpio_dev; |
|
|
|
|
int_data->gpio_mapping[int_num].pin = pin; |
|
|
|
|
#elif defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
const struct device *eirq_dev = gpio_config->eirq_dev[pin]; |
|
|
|
|
struct gpio_rz_data *gpio_data = gpio_dev->data; |
|
|
|
|
|
|
|
|
|
gpio_data->pin[int_num] = pin; |
|
|
|
|
if (device_is_ready(eirq_dev)) { |
|
|
|
|
intc_rz_ext_irq_set_type(eirq_dev, irq_type); |
|
|
|
|
intc_rz_ext_irq_enable(eirq_dev); |
|
|
|
|
intc_rz_ext_irq_set_callback(eirq_dev, gpio_config->cb_list[int_num], |
|
|
|
|
(void *)gpio_dev); |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_SOC_SERIES_* */ |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -315,54 +361,56 @@ static int gpio_rz_pin_interrupt_configure(const struct device *dev, gpio_pin_t
@@ -315,54 +361,56 @@ static int gpio_rz_pin_interrupt_configure(const struct device *dev, gpio_pin_t
|
|
|
|
|
const struct gpio_rz_config *config = dev->config; |
|
|
|
|
struct gpio_rz_data *data = dev->data; |
|
|
|
|
bsp_io_port_pin_t port_pin = config->fsp_port | pin; |
|
|
|
|
uint8_t tint_num = config->tint_num[pin]; |
|
|
|
|
uint8_t int_num = config->int_num[pin]; |
|
|
|
|
uint8_t irq_type = 0; |
|
|
|
|
gpio_flags_t pre_flags = 0; |
|
|
|
|
k_spinlock_key_t key; |
|
|
|
|
int ret = 0; |
|
|
|
|
|
|
|
|
|
if (tint_num >= GPIO_RZ_MAX_TINT_NUM) { |
|
|
|
|
LOG_DEV_ERR(dev, "Invalid TINT interrupt:%d >= %d", tint_num, GPIO_RZ_MAX_TINT_NUM); |
|
|
|
|
if (int_num >= GPIO_RZ_MAX_INT_NUM) { |
|
|
|
|
LOG_DEV_ERR(dev, "Invalid interrupt:%d >= %d", int_num, GPIO_RZ_MAX_INT_NUM); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pin > config->ngpios) { |
|
|
|
|
return -EINVAL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (trig == GPIO_INT_TRIG_BOTH) { |
|
|
|
|
return -ENOTSUP; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
key = k_spin_lock(&data->lock); |
|
|
|
|
|
|
|
|
|
if (mode == GPIO_INT_MODE_DISABLED) { |
|
|
|
|
gpio_rz_pin_config_get_raw(port_pin, &pre_flags); |
|
|
|
|
pre_flags |= GPIO_INT_DISABLE; |
|
|
|
|
gpio_rz_pin_configure(dev, pin, pre_flags); |
|
|
|
|
gpio_rz_int_disable(config->int_dev, tint_num); |
|
|
|
|
gpio_rz_int_disable(config->int_dev, dev, int_num, pin); |
|
|
|
|
goto exit_unlock; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mode == GPIO_INT_MODE_EDGE) { |
|
|
|
|
irq_type = GPIO_RZ_TINT_EDGE_RISING; |
|
|
|
|
if (trig == GPIO_INT_TRIG_LOW) { |
|
|
|
|
irq_type = GPIO_RZ_TINT_EDGE_FALLING; |
|
|
|
|
irq_type = GPIO_RZ_INT_EDGE_FALLING; |
|
|
|
|
} else if (trig == GPIO_INT_TRIG_HIGH) { |
|
|
|
|
irq_type = GPIO_RZ_INT_EDGE_RISING; |
|
|
|
|
} else if (trig == GPIO_INT_TRIG_BOTH) { |
|
|
|
|
irq_type = GPIO_RZ_INT_BOTH_EDGE; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
irq_type = GPIO_RZ_TINT_LEVEL_HIGH; |
|
|
|
|
if (trig == GPIO_INT_TRIG_LOW) { |
|
|
|
|
irq_type = GPIO_RZ_TINT_LEVEL_LOW; |
|
|
|
|
irq_type = GPIO_RZ_INT_LEVEL_LOW; |
|
|
|
|
} else if (trig == GPIO_INT_TRIG_HIGH) { |
|
|
|
|
irq_type = GPIO_RZ_INT_LEVEL_HIGH; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Set register ISEL */ |
|
|
|
|
gpio_rz_pin_config_get_raw(port_pin, &pre_flags); |
|
|
|
|
pre_flags |= GPIO_INT_ENABLE; |
|
|
|
|
gpio_rz_pin_configure(dev, pin, pre_flags); |
|
|
|
|
gpio_rz_int_enable(config->int_dev, dev, tint_num, irq_type, pin); |
|
|
|
|
ret = gpio_rz_int_enable(config->int_dev, dev, int_num, irq_type, pin); |
|
|
|
|
if (ret == 0) { |
|
|
|
|
gpio_rz_pin_config_get_raw(port_pin, &pre_flags); |
|
|
|
|
pre_flags |= GPIO_INT_ENABLE; |
|
|
|
|
gpio_rz_pin_configure(dev, pin, pre_flags); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
exit_unlock: |
|
|
|
|
k_spin_unlock(&data->lock, key); |
|
|
|
|
return 0; |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int gpio_rz_manage_callback(const struct device *dev, struct gpio_callback *callback, |
|
|
|
@ -373,41 +421,37 @@ static int gpio_rz_manage_callback(const struct device *dev, struct gpio_callbac
@@ -373,41 +421,37 @@ static int gpio_rz_manage_callback(const struct device *dev, struct gpio_callbac
|
|
|
|
|
return gpio_manage_callback(&data->cb, callback, set); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void gpio_rz_isr(const struct device *dev, uint8_t pin) |
|
|
|
|
static void gpio_rz_isr(uint16_t irq, void *param) |
|
|
|
|
{ |
|
|
|
|
struct gpio_rz_data *data = dev->data; |
|
|
|
|
|
|
|
|
|
gpio_fire_callbacks(&data->cb, dev, BIT(pin)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void gpio_rz_tint_isr(uint16_t irq, const struct device *dev) |
|
|
|
|
{ |
|
|
|
|
struct gpio_rz_tint_data *data = dev->data; |
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZG3S) |
|
|
|
|
const struct device *dev = param; |
|
|
|
|
struct gpio_rz_int_data *int_data = dev->data; |
|
|
|
|
volatile uint32_t *tscr = &R_INTC_IM33->TSCR; |
|
|
|
|
uint8_t tint_num; |
|
|
|
|
|
|
|
|
|
tint_num = irq - GPIO_RZ_TINT_IRQ_OFFSET; |
|
|
|
|
|
|
|
|
|
if (!(*tscr & BIT(tint_num))) { |
|
|
|
|
LOG_DEV_DBG(dev, "tint:%u spurious irq, status 0", tint_num); |
|
|
|
|
if (!(*tscr & BIT(irq))) { |
|
|
|
|
LOG_DEV_DBG(dev, "tint:%u spurious irq, status 0", irq); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (data->irq_set_edge & BIT(tint_num)) { |
|
|
|
|
*tscr &= ~BIT(tint_num); |
|
|
|
|
if (int_data->irq_set_edge & BIT(irq)) { |
|
|
|
|
*tscr &= ~BIT(irq); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpio_rz_isr(data->tint_data[tint_num].gpio_dev, data->tint_data[tint_num].pin); |
|
|
|
|
} |
|
|
|
|
uint8_t pin = int_data->gpio_mapping[irq].pin; |
|
|
|
|
const struct device *gpio_dev = int_data->gpio_mapping[irq].gpio_dev; |
|
|
|
|
struct gpio_rz_data *gpio_data = gpio_dev->data; |
|
|
|
|
|
|
|
|
|
static int gpio_rz_int_init(const struct device *dev) |
|
|
|
|
{ |
|
|
|
|
const struct gpio_rz_tint_config *config = dev->config; |
|
|
|
|
gpio_fire_callbacks(&gpio_data->cb, gpio_dev, BIT(pin)); |
|
|
|
|
#elif defined(CONFIG_SOC_SERIES_RZN2L) |
|
|
|
|
const struct device *gpio_dev = (const struct device *)param; |
|
|
|
|
struct gpio_rz_data *gpio_data = gpio_dev->data; |
|
|
|
|
uint8_t pin = gpio_data->pin[irq]; |
|
|
|
|
|
|
|
|
|
config->gpio_int_init(); |
|
|
|
|
return 0; |
|
|
|
|
gpio_fire_callbacks(&gpio_data->cb, gpio_dev, BIT(pin)); |
|
|
|
|
#endif /* CONFIG_SOC_SERIES_* */ |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#endif /* GPIO_RZ_HAS_INTERRUPT */ |
|
|
|
|
|
|
|
|
|
static DEVICE_API(gpio, gpio_rz_driver_api) = { |
|
|
|
|
.pin_configure = gpio_rz_pin_configure, |
|
|
|
@ -426,18 +470,29 @@ static DEVICE_API(gpio, gpio_rz_driver_api) = {
@@ -426,18 +470,29 @@ static DEVICE_API(gpio, gpio_rz_driver_api) = {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/*Initialize GPIO interrupt device*/ |
|
|
|
|
#define GPIO_RZ_TINT_ISR_DECLARE(irq_num, node_id) \ |
|
|
|
|
static void rz_gpio_isr_##irq_num(void *param) \ |
|
|
|
|
#define GPIO_RZ_ISR_DEFINE(irq_num, _) \ |
|
|
|
|
static void rz_gpio_isr##irq_num(void *param) \ |
|
|
|
|
{ \ |
|
|
|
|
gpio_rz_tint_isr(DT_IRQ_BY_IDX(node_id, irq_num, irq), param); \ |
|
|
|
|
gpio_rz_isr(irq_num, param); \ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define GPIO_RZ_TINT_ISR_INIT(node_id, irq_num) LISTIFY(irq_num, \ |
|
|
|
|
GPIO_RZ_TINT_ISR_DECLARE, (), node_id) |
|
|
|
|
#define GPIO_RZ_ALL_ISR_DEFINE(irq_num) LISTIFY(irq_num, GPIO_RZ_ISR_DEFINE, ()) |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_SOC_SERIES_RZG3S) |
|
|
|
|
|
|
|
|
|
#define GPIO_RZ_INT_DEFINE(inst) .int_dev = DEVICE_DT_GET_OR_NULL(DT_INST(0, renesas_rz_gpio_int)) |
|
|
|
|
|
|
|
|
|
static int gpio_rz_int_init(const struct device *dev) |
|
|
|
|
{ |
|
|
|
|
const struct gpio_rz_tint_config *config = dev->config; |
|
|
|
|
|
|
|
|
|
config->gpio_int_init(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define GPIO_RZ_TINT_CONNECT(irq_num, node_id) \ |
|
|
|
|
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, irq_num, irq), \ |
|
|
|
|
DT_IRQ_BY_IDX(node_id, irq_num, priority), rz_gpio_isr_##irq_num, \ |
|
|
|
|
DT_IRQ_BY_IDX(node_id, irq_num, priority), rz_gpio_isr##irq_num, \ |
|
|
|
|
DEVICE_DT_GET(node_id), 0); |
|
|
|
|
|
|
|
|
|
#define GPIO_RZ_TINT_CONNECT_FUNC(node_id) \ |
|
|
|
@ -449,18 +504,42 @@ static DEVICE_API(gpio, gpio_rz_driver_api) = {
@@ -449,18 +504,42 @@ static DEVICE_API(gpio, gpio_rz_driver_api) = {
|
|
|
|
|
} |
|
|
|
|
/* Initialize GPIO device*/ |
|
|
|
|
#define GPIO_RZ_INT_INIT(node_id) \ |
|
|
|
|
GPIO_RZ_TINT_ISR_INIT(node_id, DT_NUM_IRQS(node_id)) \ |
|
|
|
|
GPIO_RZ_ALL_ISR_DEFINE(DT_NUM_IRQS(node_id)) \ |
|
|
|
|
GPIO_RZ_TINT_CONNECT_FUNC(node_id) \ |
|
|
|
|
static const struct gpio_rz_tint_config rz_gpio_tint_cfg_##node_id = { \ |
|
|
|
|
.gpio_int_init = rz_gpio_tint_connect_func##node_id, \ |
|
|
|
|
}; \ |
|
|
|
|
static struct gpio_rz_tint_data rz_gpio_tint_data_##node_id = {}; \ |
|
|
|
|
static struct gpio_rz_int_data rz_gpio_tint_data_##node_id = {}; \ |
|
|
|
|
DEVICE_DT_DEFINE(node_id, gpio_rz_int_init, NULL, &rz_gpio_tint_data_##node_id, \ |
|
|
|
|
&rz_gpio_tint_cfg_##node_id, POST_KERNEL, \ |
|
|
|
|
UTIL_DEC(CONFIG_GPIO_INIT_PRIORITY), NULL); |
|
|
|
|
|
|
|
|
|
DT_FOREACH_STATUS_OKAY(renesas_rz_gpio_int, GPIO_RZ_INT_INIT) |
|
|
|
|
|
|
|
|
|
#elif defined(CONFIG_SOC_SERIES_RZN2L) && GPIO_RZ_HAS_INTERRUPT |
|
|
|
|
|
|
|
|
|
GPIO_RZ_ALL_ISR_DEFINE(GPIO_RZ_MAX_INT_NUM) |
|
|
|
|
|
|
|
|
|
#define EIRQ_CB_GET(eirq_line, _) [eirq_line] = rz_gpio_isr##eirq_line |
|
|
|
|
|
|
|
|
|
#define EIRQ_DEV_LABEL_GET(inst, idx) CONCAT(irq, DT_INST_PROP_BY_IDX(inst, irqs, UTIL_INC(idx))) |
|
|
|
|
|
|
|
|
|
#define EIRQ_DEV_GET(idx, inst) \ |
|
|
|
|
COND_CODE_1(DT_INST_PROP_HAS_IDX(inst, irqs, idx), \ |
|
|
|
|
([DT_INST_PROP_BY_IDX(inst, irqs, idx)] = \ |
|
|
|
|
DEVICE_DT_GET_OR_NULL(DT_NODELABEL(EIRQ_DEV_LABEL_GET(inst, idx))),), \ |
|
|
|
|
()) |
|
|
|
|
|
|
|
|
|
#define ALL_EIRQ_DEV_GET(inst) \ |
|
|
|
|
FOR_EACH_FIXED_ARG(EIRQ_DEV_GET, (), inst, \ |
|
|
|
|
LISTIFY(DT_INST_PROP_LEN_OR(inst, irqs, 0), VALUE_2X, (,))) |
|
|
|
|
|
|
|
|
|
#define GPIO_RZ_INT_DEFINE(inst) \ |
|
|
|
|
.eirq_dev = {ALL_EIRQ_DEV_GET(inst)}, \ |
|
|
|
|
.cb_list = {LISTIFY(GPIO_RZ_MAX_INT_NUM, EIRQ_CB_GET, (,))} |
|
|
|
|
#else |
|
|
|
|
#define GPIO_RZ_INT_DEFINE(inst) |
|
|
|
|
#endif /* CONFIG_SOC_SERIES_* */ |
|
|
|
|
|
|
|
|
|
#define VALUE_2X(i, _) UTIL_X2(i) |
|
|
|
|
#define PIN_IRQ_GET(idx, inst) \ |
|
|
|
|
COND_CODE_1(DT_INST_PROP_HAS_IDX(inst, irqs, idx), \ |
|
|
|
@ -489,9 +568,8 @@ DT_FOREACH_STATUS_OKAY(renesas_rz_gpio_int, GPIO_RZ_INT_INIT)
@@ -489,9 +568,8 @@ DT_FOREACH_STATUS_OKAY(renesas_rz_gpio_int, GPIO_RZ_INT_INIT)
|
|
|
|
|
.ngpios = (uint8_t)DT_INST_PROP(inst, ngpios), \ |
|
|
|
|
.fsp_cfg = &g_ioport_##inst##_cfg, \ |
|
|
|
|
.fsp_api = &g_ioport_on_ioport, \ |
|
|
|
|
.int_dev = DEVICE_DT_GET_OR_NULL(DT_INST(0, renesas_rz_gpio_int)), \ |
|
|
|
|
.tint_num = {PIN_IRQS_GET(inst)}, \ |
|
|
|
|
}; \ |
|
|
|
|
.int_num = {PIN_IRQS_GET(inst)}, \ |
|
|
|
|
GPIO_RZ_INT_DEFINE(inst)}; \ |
|
|
|
|
static ioport_instance_ctrl_t g_ioport_##inst##_ctrl; \ |
|
|
|
|
static struct gpio_rz_data gpio_rz_##inst##_data = { \ |
|
|
|
|
.fsp_ctrl = &g_ioport_##inst##_ctrl, \ |
|
|
|
|