summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-06-05 11:58:17 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-06-06 11:06:43 +0000
commit2b23d3ecaf2074ad640f66ff198b6043f3ea9e6e (patch)
tree465de543e13bcada2ffe2ba7346a10d57fdbe0be
parente85bc74b307365e9a7b4adab51d646638db12fbd (diff)
downloadrockbox-2b23d3ecaf2074ad640f66ff198b6043f3ea9e6e.tar.gz
rockbox-2b23d3ecaf2074ad640f66ff198b6043f3ea9e6e.zip
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
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c5
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.h3
-rw-r--r--firmware/target/mips/ingenic_x1000/msc-x1000.c14
-rw-r--r--firmware/target/mips/ingenic_x1000/system-target.h3
-rw-r--r--firmware/target/mips/ingenic_x1000/system-x1000.c9
-rw-r--r--firmware/target/mips/ingenic_x1000/usb-x1000.c8
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();