summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMihail Zenkov <mihail.zenkov@gmail.com>2016-02-20 03:36:26 +0000
committerMihail Zenkov <mihail.zenkov@gmail.com>2016-04-05 01:55:38 +0000
commitc7daef36c5c75b8541d38cec4793826ab085d5ad (patch)
tree7a690b321d942ad4f12a88682a0689d253c4eb7c
parentce90c0481a6c7a5a455791e4e7366c589e52b68c (diff)
downloadrockbox-c7daef36c5c75.tar.gz
rockbox-c7daef36c5c75.tar.bz2
rockbox-c7daef36c5c75.zip
as3525: reverting I2C2 to non-interrupts version
Interrupts version is cause of freeze on USB extraction. Also non-interrupts version much simpler and faster. Change-Id: I30a2993cdcaa85abfba77ca06bfacd5b6b4353e2
-rw-r--r--firmware/drivers/adc-as3514.c32
-rw-r--r--firmware/export/ascodec.h6
-rw-r--r--firmware/target/arm/as3525/ascodec-as3525.c469
-rw-r--r--firmware/target/arm/as3525/system-as3525.c1
4 files changed, 116 insertions, 392 deletions
diff --git a/firmware/drivers/adc-as3514.c b/firmware/drivers/adc-as3514.c
index 8c661eb133..3b411a379d 100644
--- a/firmware/drivers/adc-as3514.c
+++ b/firmware/drivers/adc-as3514.c
@@ -26,40 +26,18 @@
/* Read 10-bit channel data */
unsigned short adc_read(int channel)
{
- unsigned short data = 0;
-
- if ((unsigned)channel >= NUM_ADC_CHANNELS)
- return 0;
+ unsigned char buf[2];
ascodec_lock();
/* Select channel */
- if (ascodec_write(AS3514_ADC_0, (channel << 4)) >= 0)
- {
- unsigned char buf[2];
-
- /*
- * The AS3514 ADC will trigger an interrupt when the conversion
- * is finished, if the corresponding enable bit in IRQ_ENRD2
- * is set.
- * Previously the code did not wait and this apparently did
- * not pose any problems, but this should be more correct.
- * Without the wait the data read back may be completely or
- * partially (first one of the two bytes) stale.
- */
- ascodec_wait_adc_finished();
+ ascodec_write(AS3514_ADC_0, (channel << 4));
-
- /* Read data */
- if (ascodec_readbytes(AS3514_ADC_0, 2, buf) >= 0)
- {
- data = (((buf[0] & 0x3) << 8) | buf[1]);
- }
- }
+ ascodec_readbytes(AS3514_ADC_0, 2, buf);
ascodec_unlock();
-
- return data;
+
+ return (((buf[0] & 0x3) << 8) | buf[1]);
}
void adc_init(void)
diff --git a/firmware/export/ascodec.h b/firmware/export/ascodec.h
index 8697adb00d..c2ff3c8242 100644
--- a/firmware/export/ascodec.h
+++ b/firmware/export/ascodec.h
@@ -37,13 +37,11 @@ void ascodec_close(void);
void ascodec_lock(void);
void ascodec_unlock(void);
-int ascodec_write(unsigned int index, unsigned int value);
+void ascodec_write(unsigned int index, unsigned int value);
int ascodec_read(unsigned int index);
-int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);
-
-void ascodec_wait_adc_finished(void);
+void ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);
#if CONFIG_CHARGING
bool ascodec_endofch(void);
diff --git a/firmware/target/arm/as3525/ascodec-as3525.c b/firmware/target/arm/as3525/ascodec-as3525.c
index d930d266a6..ec25a415a5 100644
--- a/firmware/target/arm/as3525/ascodec-as3525.c
+++ b/firmware/target/arm/as3525/ascodec-as3525.c
@@ -24,7 +24,7 @@
This part is on address 0x46 of the internal i2c bus in the as3525.
Registers in the codec part seem to be nearly identical to the registers
in the AS3514 (used in the "v1" versions of the sansa c200 and e200).
-
+
I2C register description:
* I2C2_CNTRL needs to be set to 0x51 for transfers to work at all.
bit 0: ? possibly related to using ACKs during transfers
@@ -39,7 +39,7 @@
* I2C2_SLAD0 contains the i2c slave address to read from / write to.
* I2C2_CPSR0/1 is the divider from the peripheral clock to the i2c clock.
* I2C2_DACNT sets the number of bytes to transfer and actually starts it.
-
+
When a transfer is attempted to a non-existing i2c slave address,
interrupt bit 7 is raised and DACNT is not decremented after the transfer.
*/
@@ -50,6 +50,7 @@
#include "system.h"
#include "as3525.h"
#include "i2c.h"
+#include "logf.h"
#define I2C2_DATA *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x00))
#define I2C2_SLAD0 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x04))
@@ -77,223 +78,50 @@
#define I2C2_IRQ_RXOVER 0x10
#define I2C2_IRQ_ACKTIMEO 0x80
-#define REQ_UNFINISHED 0
-#define REQ_FINISHED 1
-#define REQ_RETRY 2
-
-#ifdef DEBUG
-#define IFDEBUG(x) x
-#else
-#define IFDEBUG(x)
-#endif
-
-#define ASCODEC_REQ_READ 0
-#define ASCODEC_REQ_WRITE 1
-
-/*
- * How many bytes we using in struct ascodec_request for the data buffer.
- * 4 fits the alignment best right now.
- * We don't actually use more than 3 at the moment (when reading interrupts)
- * Upper limit would be 255 since DACNT is 8 bits!
- */
-#define ASCODEC_REQ_MAXLEN 4
-
-typedef void (ascodec_cb_fn)(unsigned const char *data, unsigned cnt);
-
-struct ascodec_request {
- unsigned char type;
- unsigned char index;
- unsigned char status;
- unsigned char cnt;
- unsigned char data[ASCODEC_REQ_MAXLEN];
- struct semaphore complete;
- ascodec_cb_fn *callback;
- struct ascodec_request *next;
-};
-
static struct mutex as_mtx;
-static unsigned long ascodec_enrd0_shadow = 0;
-
-static unsigned char *req_data_ptr = NULL;
-static struct ascodec_request *req_head = NULL;
-static struct ascodec_request *req_tail = NULL;
-
-static struct semaphore adc_done_sem;
-static struct ascodec_request as_audio_req;
-
-#ifdef DEBUG
-static int int_audio_ctr = 0;
-static int int_chg_finished = 0;
-static int int_chg_insert = 0;
-static int int_chg_remove = 0;
-static int int_usb_insert = 0;
-static int int_usb_remove = 0;
-static int int_rtc = 0;
-static int int_adc = 0;
-#endif /* DEBUG */
+#if CONFIG_CHARGING
+static bool chg_status = false;
+static bool endofch = false;
+#endif
-/* returns != 0 when busy */
-static inline int i2c_busy(void)
+/* returns true when busy */
+static inline bool i2c_busy(void)
{
return (I2C2_SR & 1);
}
-static void ascodec_finish_req(struct ascodec_request *req)
-{
- /*
- * Wait if still busy, unfortunately this happens since
- * the controller is running at a low divisor, so it's
- * still busy when we serviced the interrupt.
- * I tried upping the i2c speed to 4MHz which
- * made the number of busywait cycles much smaller
- * (none for reads and only a few for writes),
- * but who knows if it's reliable at that frequency. ;)
- * For one thing, 8MHz doesn't work, so 4MHz is likely
- * borderline.
- * In general writes need much more wait cycles than reads
- * for some reason, possibly because we read the data register
- * for reads, which will likely block the processor while
- * the i2c controller responds to the register read.
- */
- while (i2c_busy());
-
- req->status = 1;
-
- if (req->callback) {
- req->callback(req->data, req_data_ptr - req->data);
- }
- semaphore_release(&req->complete);
-}
-
-static int ascodec_continue_req(struct ascodec_request *req, int irq_status)
+void i2c_init(void)
{
- if ((irq_status & (I2C2_IRQ_RXOVER|I2C2_IRQ_ACKTIMEO)) > 0) {
- /* some error occured, restart the request */
- return REQ_RETRY;
- }
- if (req->type == ASCODEC_REQ_READ &&
- (irq_status & I2C2_IRQ_RXFULL) > 0) {
- *(req_data_ptr++) = I2C2_DATA;
- } else {
- if (req->cnt > 1 &&
- (irq_status & I2C2_IRQ_TXEMPTY) > 0) {
- I2C2_DATA = *(req_data_ptr++);
- }
- }
-
- req->index++;
- if (--req->cnt > 0)
- return REQ_UNFINISHED;
-
- return REQ_FINISHED;
}
-static void ascodec_start_req(struct ascodec_request *req)
+static void i2c2_init(void)
{
- int unmask = 0;
-
- /* enable clock */
- bitset32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE);
-
- /* start transfer */
- I2C2_SADDR = req->index;
- if (req->type == ASCODEC_REQ_READ) {
- req_data_ptr = req->data;
- /* start transfer */
- I2C2_CNTRL = I2C2_CNTRL_DEFAULT | I2C2_CNTRL_READ;
- unmask = I2C2_IRQ_RXFULL|I2C2_IRQ_RXOVER;
- } else {
- req_data_ptr = &req->data[1];
- I2C2_CNTRL = I2C2_CNTRL_DEFAULT | I2C2_CNTRL_WRITE;
- I2C2_DATA = req->data[0];
- unmask = I2C2_IRQ_TXEMPTY|I2C2_IRQ_ACKTIMEO;
- }
-
- I2C2_DACNT = req->cnt;
- I2C2_IMR |= unmask; /* enable interrupts */
-}
-
-void INT_I2C_AUDIO(void)
-{
- struct ascodec_request *req = req_head;
-
- int irq_status = I2C2_MIS;
- int status = ascodec_continue_req(req, irq_status);
-
- I2C2_INT_CLR = irq_status; /* clear interrupt status */
-
- if (status != REQ_UNFINISHED) {
- /* mask rx/tx interrupts */
- I2C2_IMR &= ~(I2C2_IRQ_TXEMPTY|I2C2_IRQ_RXFULL|
- I2C2_IRQ_RXOVER|I2C2_IRQ_ACKTIMEO);
-
- if (status == REQ_FINISHED)
- ascodec_finish_req(req);
-
- int oldlevel = disable_irq_save(); /* IRQs are stacked */
-
- /*
- * If status == REQ_RETRY, this will restart
- * the request because we didn't remove it from
- * the request list
- */
-
- if (status == REQ_FINISHED) {
- req_head = req->next;
- req->next = NULL;
- }
+ int prescaler;
- if (req_head == NULL) {
- req_tail = NULL;
+ /* prescaler for i2c clock */
+ prescaler = AS3525_I2C_PRESCALER;
+ I2C2_CPSR0 = prescaler & 0xFF; /* 8 lsb */
+ I2C2_CPSR1 = (prescaler >> 8) & 0x3; /* 2 msb */
- /* disable clock */
- bitclr32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE);
- } else {
- ascodec_start_req(req_head);
- }
+ /* set i2c slave address of codec part */
+ I2C2_SLAD0 = AS3514_I2C_ADDR << 1;
- restore_irq(oldlevel);
- }
-}
+ I2C2_CNTRL = I2C2_CNTRL_DEFAULT;
-void i2c_init(void)
-{
}
/* initialises the internal i2c bus and prepares for transfers to the codec */
void ascodec_init(void)
{
- int prescaler;
mutex_init(&as_mtx);
- semaphore_init(&adc_done_sem, 1, 0);
/* enable clock */
bitset32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE);
- /* prescaler for i2c clock */
- prescaler = AS3525_I2C_PRESCALER;
- I2C2_CPSR0 = prescaler & 0xFF; /* 8 lsb */
- I2C2_CPSR1 = (prescaler >> 8) & 0x3; /* 2 msb */
-
- /* set i2c slave address of codec part */
- I2C2_SLAD0 = AS3514_I2C_ADDR << 1;
-
- I2C2_CNTRL = I2C2_CNTRL_DEFAULT;
-
- I2C2_IMR = 0x00; /* disable interrupts */
- I2C2_INT_CLR = I2C2_RIS; /* clear interrupt status */
- VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO;
- VIC_INT_ENABLE = INTERRUPT_AUDIO;
-
- /* detect if USB was connected at startup since there is no transition */
- ascodec_enrd0_shadow = ascodec_read(AS3514_IRQ_ENRD0);
- if(ascodec_enrd0_shadow & USB_STATUS)
- usb_insert_int();
- else
- usb_remove_int();
+ i2c2_init();
/* Generate irq for usb+charge status change */
ascodec_write(AS3514_IRQ_ENRD0,
@@ -305,242 +133,172 @@ void ascodec_init(void)
#if CONFIG_CPU == AS3525v2
/* XIRQ = IRQ, active low reset signal, 6mA push-pull output */
ascodec_write_pmu(0x1a, 3, (1<<2)|3); /* 1A-3 = Out_Cntr3 register */
- /* Generate irq on (rtc,) adc change */
- ascodec_write(AS3514_IRQ_ENRD2, /*IRQ_RTC |*/ IRQ_ADC);
+ /* reset for compatible with old bootloader */
+ ascodec_write(AS3514_IRQ_ENRD2, 0x0);
#else
/* Generate irq for push-pull, active high, irq on rtc+adc change */
- ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE |
- /*IRQ_RTC |*/ IRQ_ADC);
+ ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE);
#endif
-}
-static void ascodec_req_init(struct ascodec_request *req, int type,
- unsigned int index, unsigned int cnt)
-{
- semaphore_init(&req->complete, 1, 0);
- req->next = NULL;
- req->callback = NULL;
- req->type = type;
- req->index = index;
- req->cnt = cnt;
+ VIC_INT_ENABLE = INTERRUPT_AUDIO;
+
+ /* detect if USB was connected at startup since there is no transition */
+ int data = ascodec_read(AS3514_IRQ_ENRD0);
+
+ if(data & USB_STATUS)
+ usb_insert_int();
+
+#if CONFIG_CHARGING
+ chg_status = data & CHG_STATUS;
+#endif
}
-static void ascodec_submit(struct ascodec_request *req)
+/* returns false if transfer incomplete */
+static bool i2c2_transfer(void)
{
- int oldlevel = disable_irq_save();
+ static int try = 0;
- req->status = 0;
+ /* wait for transfer*/
+ int i = 10000;
+ while (I2C2_DACNT != 0 && i--);
- if (req_head == NULL) {
- req_tail = req_head = req;
- ascodec_start_req(req);
- } else {
- req_tail->next = req;
- req_tail = req;
- }
+ if (!i) {
+ if (try == 5)
+ panicf("I2C2 reset failed");
- restore_irq(oldlevel);
-}
+ logf("reset I2C2 %d", try);
-static void ascodec_wait(struct ascodec_request *req)
-{
- /* NOTE: Only safe from thread context */
+ i2c2_init();
- if (irq_enabled()) {
- semaphore_wait(&req->complete, TIMEOUT_BLOCK);
- return;
+ try++;
+ return false;
}
- while (req->status == 0) {
- if (I2C2_MIS) INT_I2C_AUDIO();
- }
+ try = 0;
+ return true;
}
-/*
- * The request struct passed in must be allocated statically.
- * If you call ascodec_async_write from different places, each
- * call needs it's own request struct.
- */
-static void ascodec_async_write(unsigned int index, unsigned int value,
- struct ascodec_request *req)
+void ascodec_write(unsigned int index, unsigned int value)
{
+ ascodec_lock();
+
#ifndef HAVE_AS3543
if (index == AS3514_CVDD_DCDC3) /* prevent setting of the LREG_CP_not bit */
value &= ~(1 << 5);
#endif
- ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1);
- req->data[0] = value;
- ascodec_submit(req);
-}
+ do {
+ /* wait if still busy */
+ while (i2c_busy());
-/* returns 0 on success, <0 otherwise */
-int ascodec_write(unsigned int index, unsigned int value)
-{
- struct ascodec_request req;
+ /* start transfer */
+ I2C2_SADDR = index;
+ I2C2_CNTRL &= ~(1 << 1);
+ I2C2_DATA = value;
+ I2C2_DACNT = 1;
- ascodec_async_write(index, value, &req);
- ascodec_wait(&req);
+ } while (!i2c2_transfer());
- return 0;
+ ascodec_unlock();
}
-/*
- * The request struct passed in must be allocated statically.
- * If you call ascodec_async_read from different places, each
- * call needs it's own request struct.
- * If len is bigger than ASCODEC_REQ_MAXLEN it will be
- * set to ASCODEC_REQ_MAXLEN.
- */
-static void ascodec_async_read(unsigned int index, unsigned int len,
- struct ascodec_request *req, ascodec_cb_fn *cb)
-{
- if (len > ASCODEC_REQ_MAXLEN)
- len = ASCODEC_REQ_MAXLEN; /* can't fit more in one request */
-
- ascodec_req_init(req, ASCODEC_REQ_READ, index, len);
- req->callback = cb;
- ascodec_submit(req);
-}
-
-/* returns value read on success, <0 otherwise */
int ascodec_read(unsigned int index)
{
- struct ascodec_request req;
-
- ascodec_async_read(index, 1, &req, NULL);
- ascodec_wait(&req);
+ int data;
- return req.data[0];
-}
+ ascodec_lock();
-int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
-{
- int i, j;
- struct ascodec_request req;
+ do {
+ /* wait if still busy */
+ while (i2c_busy());
- /* index and cnt will be filled in later, just use 0 */
- ascodec_req_init(&req, ASCODEC_REQ_READ, 0, 0);
+ /* start transfer */
+ I2C2_SADDR = index;
+ I2C2_CNTRL |= (1 << 1);
+ I2C2_DACNT = 1;
- i = 0;
- while (len > 0) {
- int cnt = len > ASCODEC_REQ_MAXLEN ? ASCODEC_REQ_MAXLEN : len;
+ } while (!i2c2_transfer());
- req.index = index;
- req.cnt = cnt;
+ data = I2C2_DATA;
- ascodec_submit(&req);
- ascodec_wait(&req);
+ ascodec_unlock();
- for (j=0; j<cnt; j++) data[i++] = req.data[j];
+ return data;
+}
- len -= cnt;
- index += cnt;
- }
+void ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
+{
+ unsigned int i;
- return i;
+ for(i = 0; i < len; i++)
+ data[i] = ascodec_read(index+i);
}
#if CONFIG_CPU == AS3525v2
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
unsigned int value)
{
- struct ascodec_request reqs[2];
-
- int oldstatus = disable_irq_save();
+ ascodec_lock();
/* we submit consecutive requests to make sure no operations happen on the
* i2c bus between selecting the sub register and writing to it */
- ascodec_async_write(AS3543_PMU_ENABLE, 8 | subreg, &reqs[0]);
- ascodec_async_write(index, value, &reqs[1]);
- restore_irq(oldstatus);
+ ascodec_write(AS3543_PMU_ENABLE, 8 | subreg);
+ ascodec_write(index, value);
- /* Wait for second request to finish */
- ascodec_wait(&reqs[1]);
+ ascodec_unlock();
}
int ascodec_read_pmu(unsigned int index, unsigned int subreg)
{
- struct ascodec_request reqs[2];
-
- int oldstatus = disable_irq_save();
+ ascodec_lock();
/* we submit consecutive requests to make sure no operations happen on the
* i2c bus between selecting the sub register and reading it */
- ascodec_async_write(AS3543_PMU_ENABLE, subreg, &reqs[0]);
- ascodec_async_read(index, 1, &reqs[1], NULL);
- restore_irq(oldstatus);
+ ascodec_write(AS3543_PMU_ENABLE, subreg);
+ int ret = ascodec_read(index);
- /* Wait for second request to finish */
- ascodec_wait(&reqs[1]);
+ ascodec_unlock();
- return reqs[1].data[0];
+ return ret;
}
#endif /* CONFIG_CPU == AS3525v2 */
-static void ascodec_read_cb(unsigned const char *data, unsigned int len)
+void INT_AUDIO(void)
{
- if (UNLIKELY(len != 3)) /* some error happened? */
- panicf("INT_AUDIO callback got %d regs", len);
+ int oldstatus = disable_irq_save();
+ int data = ascodec_read(AS3514_IRQ_ENRD0);
- if (data[0] & CHG_ENDOFCH) { /* chg finished */
- ascodec_enrd0_shadow |= CHG_ENDOFCH;
- IFDEBUG(int_chg_finished++);
- }
- if (data[0] & CHG_CHANGED) { /* chg status changed */
- if (data[0] & CHG_STATUS) {
- ascodec_enrd0_shadow |= CHG_STATUS;
- IFDEBUG(int_chg_insert++);
- } else {
- ascodec_enrd0_shadow &= ~CHG_STATUS;
- IFDEBUG(int_chg_remove++);
- }
+#if CONFIG_CHARGING
+ if (data & CHG_ENDOFCH) { /* chg finished */
+ endofch = true;
}
- if (data[0] & USB_CHANGED) { /* usb status changed */
- if (data[0] & USB_STATUS) {
- IFDEBUG(int_usb_insert++);
+
+ chg_status = data & CHG_STATUS;
+#endif
+
+ if (data & USB_CHANGED) { /* usb status changed */
+ if (data & USB_STATUS) {
usb_insert_int();
} else {
- IFDEBUG(int_usb_remove++);
usb_remove_int();
}
}
- if (data[2] & IRQ_RTC) { /* rtc irq */
- /*
- * Can be configured for once per second or once per minute,
- * default is once per second
- */
- IFDEBUG(int_rtc++);
- }
- if (data[2] & IRQ_ADC) { /* adc finished */
- IFDEBUG(int_adc++);
- semaphore_release(&adc_done_sem);
- }
- VIC_INT_ENABLE = INTERRUPT_AUDIO;
-}
-void INT_AUDIO(void)
-{
- VIC_INT_EN_CLEAR = INTERRUPT_AUDIO;
- IFDEBUG(int_audio_ctr++);
-
- ascodec_async_read(AS3514_IRQ_ENRD0, 3, &as_audio_req, ascodec_read_cb);
-}
-
-void ascodec_wait_adc_finished(void)
-{
- semaphore_wait(&adc_done_sem, TIMEOUT_BLOCK);
+ restore_irq(oldstatus);
}
#if CONFIG_CHARGING
bool ascodec_endofch(void)
{
- bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH;
- bitclr32(&ascodec_enrd0_shadow, CHG_ENDOFCH); /* clear interrupt */
+ int oldstatus = disable_irq_save();
+ bool ret = endofch;
+ endofch = false;
+ restore_irq(oldstatus);
+
return ret;
}
bool ascodec_chg_status(void)
{
- return ascodec_enrd0_shadow & CHG_STATUS;
+ return chg_status;
}
void ascodec_monitor_endofch(void)
@@ -567,15 +325,6 @@ int ascodec_read_charger(void)
}
#endif /* CONFIG_CHARGING */
-/*
- * NOTE:
- * After the conversion to interrupts, ascodec_(lock|unlock) are only used by
- * adc-as3514.c to protect against other threads corrupting the result by using
- * the ADC at the same time.
- * Concurrent ascodec_(async_)?(read|write) calls are instead protected
- * because ascodec_submit() is atomic and concurrent requests will wait
- * in the queue until the current request is finished.
- */
void ascodec_lock(void)
{
mutex_lock(&as_mtx);
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index edd80f4fb2..238cdd0b26 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -137,7 +137,6 @@ static const struct { int source; void (*isr) (void); } vec_int_srcs[] =
{ INT_SRC_USB, INT_USB_FUNC, },
{ INT_SRC_TIMER1, INT_TIMER1 },
{ INT_SRC_TIMER2, INT_TIMER2 },
- { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO },
{ INT_SRC_AUDIO, INT_AUDIO },
/* Lowest priority at the end of the list */
};