From 2b23d3ecaf2074ad640f66ff198b6043f3ea9e6e Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 5 Jun 2021 11:58:17 +0100 Subject: 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 --- .../target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c | 5 ++--- firmware/target/mips/ingenic_x1000/gpio-x1000.h | 3 +++ firmware/target/mips/ingenic_x1000/msc-x1000.c | 14 +++++++------- firmware/target/mips/ingenic_x1000/system-target.h | 3 +++ firmware/target/mips/ingenic_x1000/system-x1000.c | 9 ++++++++- firmware/target/mips/ingenic_x1000/usb-x1000.c | 8 +++----- 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c index 47b5e3d6dc..d566ccb6c8 100644 --- a/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c +++ b/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c @@ -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, diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.h b/firmware/target/mips/ingenic_x1000/gpio-x1000.h index 5d147fc18f..eac5f8651f 100644 --- a/firmware/target/mips/ingenic_x1000/gpio-x1000.h +++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.h @@ -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; diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.c b/firmware/target/mips/ingenic_x1000/msc-x1000.c index 92b3d4206a..27929cced5 100644 --- a/firmware/target/mips/ingenic_x1000/msc-x1000.c +++ b/firmware/target/mips/ingenic_x1000/msc-x1000.c @@ -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 diff --git a/firmware/target/mips/ingenic_x1000/system-target.h b/firmware/target/mips/ingenic_x1000/system-target.h index 1390faf43a..7cea654865 100644 --- a/firmware/target/mips/ingenic_x1000/system-target.h +++ b/firmware/target/mips/ingenic_x1000/system-target.h @@ -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); diff --git a/firmware/target/mips/ingenic_x1000/system-x1000.c b/firmware/target/mips/ingenic_x1000/system-x1000.c index c0b0dbc65e..779bb2055c 100644 --- a/firmware/target/mips/ingenic_x1000/system-x1000.c +++ b/firmware/target/mips/ingenic_x1000/system-x1000.c @@ -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)) { diff --git a/firmware/target/mips/ingenic_x1000/usb-x1000.c b/firmware/target/mips/ingenic_x1000/usb-x1000.c index 1cedac4fa7..1a31d8db2e 100644 --- a/firmware/target/mips/ingenic_x1000/usb-x1000.c +++ b/firmware/target/mips/ingenic_x1000/usb-x1000.c @@ -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(); -- cgit v1.2.3