as3525v2: enable AFE (AUDIO Front End) interrupts

We needed to set the XIRQ output pin

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26238 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Rafaël Carré 2010-05-21 17:49:04 +00:00
parent 76aeb6028e
commit eacc32248e

View file

@ -96,7 +96,6 @@ static unsigned char *req_data_ptr = NULL;
static struct ascodec_request *req_head = NULL; static struct ascodec_request *req_head = NULL;
static struct ascodec_request *req_tail = NULL; static struct ascodec_request *req_tail = NULL;
#if CONFIG_CPU == AS3525
static struct wakeup adc_wkup; static struct wakeup adc_wkup;
static struct ascodec_request as_audio_req; static struct ascodec_request as_audio_req;
@ -112,13 +111,11 @@ static int int_adc = 0;
#endif /* DEBUG */ #endif /* DEBUG */
static void ascodec_read_cb(unsigned const char *data, unsigned int len); static void ascodec_read_cb(unsigned const char *data, unsigned int len);
#endif /* CONFIG_CPU == AS3525 */
static void ascodec_start_req(struct ascodec_request *req); static void ascodec_start_req(struct ascodec_request *req);
static int ascodec_continue_req(struct ascodec_request *req, int irq_status); static int ascodec_continue_req(struct ascodec_request *req, int irq_status);
static void ascodec_finish_req(struct ascodec_request *req); static void ascodec_finish_req(struct ascodec_request *req);
#if CONFIG_CPU == AS3525
void INT_AUDIO(void) void INT_AUDIO(void)
{ {
VIC_INT_EN_CLEAR = INTERRUPT_AUDIO; VIC_INT_EN_CLEAR = INTERRUPT_AUDIO;
@ -126,7 +123,6 @@ void INT_AUDIO(void)
ascodec_async_read(AS3514_IRQ_ENRD0, 3, &as_audio_req, ascodec_read_cb); ascodec_async_read(AS3514_IRQ_ENRD0, 3, &as_audio_req, ascodec_read_cb);
} }
#endif /* CONFIG_CPU == AS3525 */
void INT_I2C_AUDIO(void) void INT_I2C_AUDIO(void)
{ {
@ -166,9 +162,7 @@ void ascodec_init(void)
int prescaler; int prescaler;
mutex_init(&as_mtx); mutex_init(&as_mtx);
#if CONFIG_CPU == AS3525
wakeup_init(&adc_wkup); wakeup_init(&adc_wkup);
#endif
/* enable clock */ /* enable clock */
CGU_PERI |= CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE; CGU_PERI |= CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE;
@ -186,9 +180,7 @@ void ascodec_init(void)
I2C2_IMR = 0x00; /* disable interrupts */ I2C2_IMR = 0x00; /* disable interrupts */
I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */
VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO; VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO;
#if CONFIG_CPU == AS3525 /* interrupts do not work correctly on as3525v2 */
VIC_INT_ENABLE = INTERRUPT_AUDIO; VIC_INT_ENABLE = INTERRUPT_AUDIO;
#endif
/* detect if USB was connected at startup since there is no transition */ /* detect if USB was connected at startup since there is no transition */
if(ascodec_read(AS3514_IRQ_ENRD0) & USB_STATUS) if(ascodec_read(AS3514_IRQ_ENRD0) & USB_STATUS)
@ -203,9 +195,16 @@ void ascodec_init(void)
#endif #endif
IRQ_USBSTAT); IRQ_USBSTAT);
#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);
#else
/* Generate irq for push-pull, active high, irq on rtc+adc change */ /* Generate irq for push-pull, active high, irq on rtc+adc change */
ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE | ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE |
/*IRQ_RTC |*/ IRQ_ADC); /*IRQ_RTC |*/ IRQ_ADC);
#endif
} }
/* returns != 0 when busy */ /* returns != 0 when busy */
@ -432,28 +431,17 @@ int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
return i; return i;
} }
/* static void ascodec_read_cb(unsigned const char *data, unsigned int len)
* Reading AS3514_IRQ_ENRD0 clears all interrupt bits, so we cache the results
* and clear individual bits when a specific interrupt is checked:
* - we clear the ENDOFCH (end of charge) interrupt when it's read
* - we set the usb and charger presence when the status change is detected
*
* on AS3525(v1) ENRD0 is only read in an interrupt handler
* on AS3525v2 the interrupt handler doesn't work (yet), so we read the register
* synchronously.
* - To avoid race conditions all the reads to this register must be atomic.
* We don't need to disable interrupts when reading it because all the reads
* (in powermgmt-ascodec.c and power-as3525.c) are performed by the same
* thread (the power thread).
*/
static void cache_enrd0(int enrd0)
{ {
if (enrd0 & CHG_ENDOFCH) { /* chg finished */ if (len != 3) /* some error happened? */
return;
if (data[0] & CHG_ENDOFCH) { /* chg finished */
ascodec_enrd0_shadow |= CHG_ENDOFCH; ascodec_enrd0_shadow |= CHG_ENDOFCH;
IFDEBUG(int_chg_finished++); IFDEBUG(int_chg_finished++);
} }
if (enrd0 & CHG_CHANGED) { /* chg status changed */ if (data[0] & CHG_CHANGED) { /* chg status changed */
if (enrd0 & CHG_STATUS) { if (data[0] & CHG_STATUS) {
ascodec_enrd0_shadow |= CHG_STATUS; ascodec_enrd0_shadow |= CHG_STATUS;
IFDEBUG(int_chg_insert++); IFDEBUG(int_chg_insert++);
} else { } else {
@ -461,8 +449,8 @@ static void cache_enrd0(int enrd0)
IFDEBUG(int_chg_remove++); IFDEBUG(int_chg_remove++);
} }
} }
if (enrd0 & USB_CHANGED) { /* usb status changed */ if (data[0] & USB_CHANGED) { /* usb status changed */
if (enrd0 & USB_STATUS) { if (data[0] & USB_STATUS) {
IFDEBUG(int_usb_insert++); IFDEBUG(int_usb_insert++);
usb_insert_int(); usb_insert_int();
} else { } else {
@ -470,16 +458,6 @@ static void cache_enrd0(int enrd0)
usb_remove_int(); usb_remove_int();
} }
} }
}
#if CONFIG_CPU == AS3525
static void ascodec_read_cb(unsigned const char *data, unsigned int len)
{
if (len != 3) /* some error happened? */
return;
cache_enrd0(data[0]);
if (data[2] & IRQ_RTC) { /* rtc irq */ if (data[2] & IRQ_RTC) { /* rtc irq */
/* /*
* Can be configured for once per second or once per minute, * Can be configured for once per second or once per minute,
@ -494,27 +472,14 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len)
VIC_INT_ENABLE = INTERRUPT_AUDIO; VIC_INT_ENABLE = INTERRUPT_AUDIO;
} }
#endif /* CONFIG_CPU == AS3525 */
void ascodec_wait_adc_finished(void) void ascodec_wait_adc_finished(void)
{ {
#if CONFIG_CPU == AS3525
wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); wakeup_wait(&adc_wkup, TIMEOUT_BLOCK);
#else
/* no interrupts, busy wait
* XXX: make sure this is the only reader of IRQ_ENRD2
*/
while(!(ascodec_read(AS3514_IRQ_ENRD2) & IRQ_ADC))
yield();
#endif
} }
#ifdef CONFIG_CHARGING #ifdef CONFIG_CHARGING
bool ascodec_endofch(void) bool ascodec_endofch(void)
{ {
#if CONFIG_CPU != AS3525
cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0));
#endif
bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH; bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH;
ascodec_enrd0_shadow &= ~CHG_ENDOFCH; // clear interrupt ascodec_enrd0_shadow &= ~CHG_ENDOFCH; // clear interrupt
return ret; return ret;
@ -522,9 +487,6 @@ bool ascodec_endofch(void)
bool ascodec_chg_status(void) bool ascodec_chg_status(void)
{ {
#if CONFIG_CPU != AS3525
cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0));
#endif
return ascodec_enrd0_shadow & CHG_STATUS; return ascodec_enrd0_shadow & CHG_STATUS;
} }
#endif /* CONFIG_CHARGING */ #endif /* CONFIG_CHARGING */