From eacc32248e1cde47ac4a267baadc13598ab4b808 Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Fri, 21 May 2010 17:49:04 +0000 Subject: 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 --- firmware/target/arm/as3525/ascodec-as3525.c | 70 +++++++---------------------- 1 file changed, 16 insertions(+), 54 deletions(-) (limited to 'firmware/target/arm') diff --git a/firmware/target/arm/as3525/ascodec-as3525.c b/firmware/target/arm/as3525/ascodec-as3525.c index adc9b7f9a8..708215deed 100644 --- a/firmware/target/arm/as3525/ascodec-as3525.c +++ b/firmware/target/arm/as3525/ascodec-as3525.c @@ -96,7 +96,6 @@ static unsigned char *req_data_ptr = NULL; static struct ascodec_request *req_head = NULL; static struct ascodec_request *req_tail = NULL; -#if CONFIG_CPU == AS3525 static struct wakeup adc_wkup; static struct ascodec_request as_audio_req; @@ -112,13 +111,11 @@ static int int_adc = 0; #endif /* DEBUG */ 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 int ascodec_continue_req(struct ascodec_request *req, int irq_status); static void ascodec_finish_req(struct ascodec_request *req); -#if CONFIG_CPU == AS3525 void INT_AUDIO(void) { 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); } -#endif /* CONFIG_CPU == AS3525 */ void INT_I2C_AUDIO(void) { @@ -166,9 +162,7 @@ void ascodec_init(void) int prescaler; mutex_init(&as_mtx); -#if CONFIG_CPU == AS3525 wakeup_init(&adc_wkup); -#endif /* enable clock */ CGU_PERI |= CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE; @@ -186,9 +180,7 @@ void ascodec_init(void) I2C2_IMR = 0x00; /* disable interrupts */ I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO; -#if CONFIG_CPU == AS3525 /* interrupts do not work correctly on as3525v2 */ VIC_INT_ENABLE = INTERRUPT_AUDIO; -#endif /* detect if USB was connected at startup since there is no transition */ if(ascodec_read(AS3514_IRQ_ENRD0) & USB_STATUS) @@ -203,9 +195,16 @@ void ascodec_init(void) #endif 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 */ ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE | /*IRQ_RTC |*/ IRQ_ADC); +#endif } /* returns != 0 when busy */ @@ -432,28 +431,17 @@ int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data) return i; } -/* - * 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) +static void ascodec_read_cb(unsigned const char *data, unsigned int len) { - 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; IFDEBUG(int_chg_finished++); } - if (enrd0 & CHG_CHANGED) { /* chg status changed */ - if (enrd0 & CHG_STATUS) { + if (data[0] & CHG_CHANGED) { /* chg status changed */ + if (data[0] & CHG_STATUS) { ascodec_enrd0_shadow |= CHG_STATUS; IFDEBUG(int_chg_insert++); } else { @@ -461,8 +449,8 @@ static void cache_enrd0(int enrd0) IFDEBUG(int_chg_remove++); } } - if (enrd0 & USB_CHANGED) { /* usb status changed */ - if (enrd0 & USB_STATUS) { + if (data[0] & USB_CHANGED) { /* usb status changed */ + if (data[0] & USB_STATUS) { IFDEBUG(int_usb_insert++); usb_insert_int(); } else { @@ -470,16 +458,6 @@ static void cache_enrd0(int enrd0) 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 */ /* * 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; } -#endif /* CONFIG_CPU == AS3525 */ - void ascodec_wait_adc_finished(void) { -#if CONFIG_CPU == AS3525 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 bool ascodec_endofch(void) { -#if CONFIG_CPU != AS3525 - cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0)); -#endif bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH; ascodec_enrd0_shadow &= ~CHG_ENDOFCH; // clear interrupt return ret; @@ -522,9 +487,6 @@ bool ascodec_endofch(void) bool ascodec_chg_status(void) { -#if CONFIG_CPU != AS3525 - cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0)); -#endif return ascodec_enrd0_shadow & CHG_STATUS; } #endif /* CONFIG_CHARGING */ -- cgit v1.2.3