Browse Source
Add interrupt controller driver support for RX130 series Signed-off-by: Tatsuya Ogawa <tatsuya.ogawa.nx@renesas.com> Signed-off-by: Quy Tran <quy.tran.pz@renesas.com>pull/91872/head
6 changed files with 135 additions and 2 deletions
@ -0,0 +1,9 @@ |
|||||||
|
# Copyright (c) 2025 Renesas Electronics Corporation |
||||||
|
# SPDX-License-Identifier: Apache-2.0 |
||||||
|
|
||||||
|
config RENESAS_RX_ICU |
||||||
|
bool "Renesas RX series interrupt controller unit" |
||||||
|
default y |
||||||
|
depends on DT_HAS_RENESAS_RX_ICU_ENABLED |
||||||
|
help |
||||||
|
Renesas RX series interrupt controller unit |
@ -0,0 +1,81 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Renesas Electronics Corporation |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#define DT_DRV_COMPAT renesas_rx_icu |
||||||
|
|
||||||
|
#include <zephyr/device.h> |
||||||
|
#include <zephyr/irq.h> |
||||||
|
#include <soc.h> |
||||||
|
#include <zephyr/spinlock.h> |
||||||
|
#include <zephyr/drivers/interrupt_controller/intc_rx_icu.h> |
||||||
|
#include <zephyr/sw_isr_table.h> |
||||||
|
#include <errno.h> |
||||||
|
|
||||||
|
#define IR_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), IR) |
||||||
|
#define IRQCR_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), IRQCR) |
||||||
|
#define IRQFLTE_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), IRQFLTE) |
||||||
|
#define IRQFLTC0_BASE_ADDRESS DT_REG_ADDR_BY_NAME(DT_NODELABEL(icu), IRQFLTC0) |
||||||
|
|
||||||
|
#define IRi_REG(i) (IR_BASE_ADDRESS + (i)) |
||||||
|
#define IRQCRi_REG(i) (IRQCR_BASE_ADDRESS + (i)) |
||||||
|
|
||||||
|
static struct k_spinlock lock; |
||||||
|
|
||||||
|
void rx_icu_clear_ir_flag(unsigned int irqn) |
||||||
|
{ |
||||||
|
volatile uint8_t *icu_ir = (uint8_t *)IRi_REG(irqn); |
||||||
|
|
||||||
|
/* Clear IR Register */ |
||||||
|
*icu_ir = 0x0; |
||||||
|
} |
||||||
|
|
||||||
|
int rx_icu_get_ir_flag(unsigned int irqn) |
||||||
|
{ |
||||||
|
volatile uint8_t *icu_ir = (uint8_t *)IRi_REG(irqn); |
||||||
|
|
||||||
|
/* Return IR Register */ |
||||||
|
return *icu_ir; |
||||||
|
} |
||||||
|
|
||||||
|
int rx_icu_set_irq_control(unsigned int pin_irqn, enum icu_irq_mode mode) |
||||||
|
{ |
||||||
|
|
||||||
|
volatile uint8_t *icu_irqcr = (uint8_t *)IRQCRi_REG(pin_irqn); |
||||||
|
|
||||||
|
if (mode >= ICU_MODE_NONE) { |
||||||
|
return -EINVAL; |
||||||
|
} |
||||||
|
|
||||||
|
/* Set IRQ Control Register */ |
||||||
|
*icu_irqcr = (uint8_t)(mode << 2); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void rx_icu_set_irq_dig_filt(unsigned int pin_irqn, rx_irq_dig_filt_t dig_filt) |
||||||
|
{ |
||||||
|
volatile uint8_t *icu_irqflte = (uint8_t *)IRQFLTE_BASE_ADDRESS; |
||||||
|
volatile uint16_t *icu_irqfltc0 = (uint16_t *)IRQFLTC0_BASE_ADDRESS; |
||||||
|
uint8_t temp_8bit; |
||||||
|
uint16_t temp_16bit; |
||||||
|
|
||||||
|
k_spinlock_key_t key = k_spin_lock(&lock); |
||||||
|
/* Set IRQ Pin Digital Filter Setting Register 0 (IRQFLTC0) */ |
||||||
|
temp_16bit = *icu_irqfltc0; |
||||||
|
temp_16bit &= (uint16_t) ~(0x0003 << (pin_irqn * 2)); |
||||||
|
temp_16bit |= ((uint16_t)(dig_filt.filt_clk_div) << (pin_irqn * 2)); |
||||||
|
*icu_irqfltc0 = temp_16bit; |
||||||
|
k_spin_unlock(&lock, key); |
||||||
|
|
||||||
|
key = k_spin_lock(&lock); |
||||||
|
/* Set IRQ Pin Digital Filter Enable Register 0 (IRQFLTE0) */ |
||||||
|
temp_8bit = *icu_irqflte; |
||||||
|
temp_8bit &= (uint8_t) ~(1 << pin_irqn); |
||||||
|
temp_8bit |= (uint8_t)(dig_filt.filt_enable << pin_irqn); |
||||||
|
*icu_irqflte = temp_8bit; |
||||||
|
k_spin_unlock(&lock, key); |
||||||
|
} |
||||||
|
|
||||||
|
DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, NULL, PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL); |
@ -0,0 +1,37 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Renesas Electronics Corporation |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RX_ICU_H_ |
||||||
|
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RX_ICU_H_ |
||||||
|
|
||||||
|
#define IRQ_CFG_PCLK_DIV1 (0) |
||||||
|
#define IRQ_CFG_PCLK_DIV8 (1) |
||||||
|
#define IRQ_CFG_PCLK_DIV32 (2) |
||||||
|
#define IRQ_CFG_PCLK_DIV64 (3) |
||||||
|
|
||||||
|
enum icu_irq_mode { |
||||||
|
ICU_LOW_LEVEL, |
||||||
|
ICU_FALLING, |
||||||
|
ICU_RISING, |
||||||
|
ICU_BOTH_EDGE, |
||||||
|
ICU_MODE_NONE, |
||||||
|
}; |
||||||
|
|
||||||
|
enum icu_dig_filt { |
||||||
|
DISENABLE_DIG_FILT, |
||||||
|
ENABLE_DIG_FILT, |
||||||
|
}; |
||||||
|
|
||||||
|
typedef struct rx_irq_dig_filt_s { |
||||||
|
uint8_t filt_clk_div; /* PCLK divisor setting for the input pin digital filter. */ |
||||||
|
uint8_t filt_enable; /* Filter enable setting for the input pin digital filter. */ |
||||||
|
} rx_irq_dig_filt_t; |
||||||
|
|
||||||
|
extern void rx_icu_clear_ir_flag(unsigned int irqn); |
||||||
|
extern int rx_icu_get_ir_flag(unsigned int irqn); |
||||||
|
extern int rx_icu_set_irq_control(unsigned int pin_irqn, enum icu_irq_mode mode); |
||||||
|
extern void rx_icu_set_irq_dig_filt(unsigned int pin_irqn, rx_irq_dig_filt_t dig_filt); |
||||||
|
|
||||||
|
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RX_ICU_H_ */ |
Loading…
Reference in new issue