x1000: Allow setting IRQ handlers dynamically

Avoids having to #define the names of GPIO pin interrupt handlers,
as they can now be set at runtime instead.

Change-Id: Ib5da1bdb475ff7b64280fe7cdd00adab63389152
This commit is contained in:
Aidan MacDonald 2021-06-05 11:58:17 +01:00
parent e85bc74b30
commit 2b23d3ecaf
6 changed files with 26 additions and 16 deletions

View File

@ -35,8 +35,6 @@
# include "font.h"
#endif
#define ft_interrupt GPIOB12
/* Touch event types */
#define EVENT_NONE (-1)
#define EVENT_PRESS 0
@ -348,7 +346,8 @@ static void ft_i2c_callback(int status, i2c_descriptor* desc)
ft_step_state(__ost_read32(), evt, tx, ty);
}
void ft_interrupt(void)
/* ft6x06 interrupt pin */
void GPIOB12(void)
{
/* We don't care if this fails */
i2c_async_queue(FT6x06_BUS, TIMEOUT_NOBLOCK, I2C_Q_ONCE,

View File

@ -57,6 +57,9 @@
#define GPIO_PC(x) GPION_CREATE(GPIO_C, x)
#define GPIO_PD(x) GPION_CREATE(GPIO_D, x)
/* GPIO number to IRQ number (need to include "irq-x1000.h") */
#define GPIO_TO_IRQ(gpio) IRQ_GPIO(GPION_PORT(gpio), GPION_PIN(gpio))
/* Pingroup settings are used for system devices */
struct pingroup_setting {
int port;

View File

@ -42,7 +42,6 @@
static const msc_config msc_configs[] = {
#ifdef FIIO_M3K
#define MSC_CLOCK_SOURCE X1000_CLK_SCLK_A
#define msc0_cd_interrupt GPIOB06
{
.msc_nr = 0,
.msc_type = MSC_TYPE_SD,
@ -67,6 +66,9 @@ static const msc_config* msc_lookup_config(int msc)
static msc_drv msc_drivers[MSC_COUNT];
static void msc0_cd_interrupt(void);
static void msc1_cd_interrupt(void);
/* ---------------------------------------------------------------------------
* Initialization
*/
@ -123,6 +125,8 @@ static void msc_init_one(msc_drv* d, int msc)
if(gpio_get_level(d->config->cd_gpio) != d->config->cd_active_level)
d->card_present = 0;
system_set_irq_handler(GPIO_TO_IRQ(d->config->cd_gpio),
msc == 0 ? msc0_cd_interrupt : msc1_cd_interrupt);
gpio_set_function(d->config->cd_gpio, GPIOF_IRQ_EDGE(1));
gpio_flip_edge_irq(d->config->cd_gpio);
gpio_enable_irq(d->config->cd_gpio);
@ -647,19 +651,15 @@ void MSC1(void)
msc_interrupt(&msc_drivers[1]);
}
#ifdef msc0_cd_interrupt
void msc0_cd_interrupt(void)
static void msc0_cd_interrupt(void)
{
msc_cd_interrupt(&msc_drivers[0]);
}
#endif
#ifdef msc1_cd_interrupt
void msc1_cd_interrupt(void)
static void msc1_cd_interrupt(void)
{
msc_cd_interrupt(&msc_drivers[1]);
}
#endif
/* ---------------------------------------------------------------------------
* SD command helpers

View File

@ -90,6 +90,9 @@ static inline void core_sleep(void)
}
/* IRQ control */
typedef void(*irq_handler_t)(void);
extern irq_handler_t system_set_irq_handler(int irq, irq_handler_t handler);
extern void system_enable_irq(int irq);
extern void system_disable_irq(int irq);

View File

@ -233,7 +233,7 @@ intr(OST);
#undef intr
static void(*const irqvector[])(void) = {
static void(*irqvector[])(void) = {
/* ICSR0: 0 - 31 */
DMIC, AIC, UIRQ, UIRQ, UIRQ, UIRQ, UIRQ, SFC,
SSI0, UIRQ, PDMA, PDMAD, UIRQ, UIRQ, UIRQ, UIRQ,
@ -263,6 +263,13 @@ static void(*const irqvector[])(void) = {
GPIOD00, GPIOD01, GPIOD02, GPIOD03, GPIOD04, GPIOD05,
};
irq_handler_t system_set_irq_handler(int irq, irq_handler_t handler)
{
irq_handler_t old_handler = irqvector[irq];
irqvector[irq] = handler;
return old_handler;
}
void system_enable_irq(int irq)
{
if(IRQ_IS_GROUP0(irq)) {

View File

@ -28,10 +28,6 @@
#include "gpio-x1000.h"
#include "x1000/cpm.h"
#ifdef FIIO_M3K
# define USB_DETECT_PIN_INT GPIOB11 // TODO remove me
#endif
/*
* USB-Designware driver API
*/
@ -150,6 +146,7 @@ void usb_dw_target_clear_irq(void)
#ifdef USB_STATUS_BY_EVENT
static volatile int usb_status = USB_EXTRACTED;
static void usb_detect_interrupt(void);
#endif
static int __usb_detect(void)
@ -184,6 +181,7 @@ void usb_init_device(void)
#ifdef USB_STATUS_BY_EVENT
/* Setup USB detect pin IRQ */
usb_status = __usb_detect();
system_set_irq_handler(GPIO_TO_IRQ(GPIO_USB_DETECT), usb_detect_interrupt);
gpio_set_function(GPIO_USB_DETECT, GPIOF_IRQ_EDGE(1));
gpio_flip_edge_irq(GPIO_USB_DETECT);
gpio_enable_irq(GPIO_USB_DETECT);
@ -201,7 +199,7 @@ int usb_detect(void)
return usb_status;
}
void USB_DETECT_PIN_INT(void)
static void usb_detect_interrupt(void)
{
/* Update status and flip the IRQ trigger edge */
usb_status = __usb_detect();