From 47ab95904efe238568e4cc66f0d3aacd9e7a8c10 Mon Sep 17 00:00:00 2001 From: Tobias Diedrich Date: Tue, 23 Mar 2010 05:02:37 +0000 Subject: Add handler for audio irq. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25299 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/as3525/ascodec-as3525.c | 108 +++++++++++++++++++++++++++- firmware/target/arm/as3525/ascodec-target.h | 8 +++ firmware/target/arm/as3525/system-as3525.c | 1 + firmware/target/arm/as3525/usb-as3525.c | 30 ++++---- firmware/target/arm/as3525/usb-target.h | 29 ++++++++ 5 files changed, 155 insertions(+), 21 deletions(-) create mode 100644 firmware/target/arm/as3525/usb-target.h (limited to 'firmware/target/arm/as3525') diff --git a/firmware/target/arm/as3525/ascodec-as3525.c b/firmware/target/arm/as3525/ascodec-as3525.c index ca81d7842f..441008493c 100644 --- a/firmware/target/arm/as3525/ascodec-as3525.c +++ b/firmware/target/arm/as3525/ascodec-as3525.c @@ -50,6 +50,7 @@ #include "system.h" #include "as3525.h" #include "i2c.h" +#include "usb-target.h" #define I2C2_DATA *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x00)) #define I2C2_SLAD0 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x04)) @@ -81,15 +82,47 @@ #define REQ_FINISHED 1 #define REQ_RETRY 2 +#ifdef DEBUG +#define IFDEBUG(x) x +#else +#define IFDEBUG(x) +#endif + static struct mutex as_mtx; +static int 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 wakeup adc_wkup; + +#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 + +static struct ascodec_request as_audio_req; + 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); +static void ascodec_read_cb(unsigned const char *data, unsigned int len); + +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 INT_I2C_AUDIO(void) { @@ -129,6 +162,7 @@ void ascodec_init(void) int prescaler; mutex_init(&as_mtx); + wakeup_init(&adc_wkup); /* enable clock */ CGU_PERI |= CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE; @@ -145,9 +179,14 @@ void ascodec_init(void) I2C2_IMR = 0x00; /* disable interrupts */ I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ - VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO; -} + VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO | INTERRUPT_AUDIO; + /* Generate irq for usb+charge status change */ + ascodec_write(AS3514_IRQ_ENRD0, /*IRQ_CHGSTAT |*/ IRQ_USBSTAT); + /* 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); +} /* returns != 0 when busy */ static int i2c_busy(void) @@ -297,9 +336,18 @@ static void ascodec_wait(struct ascodec_request *req) void ascodec_async_write(unsigned int index, unsigned int value, struct ascodec_request *req) { - if (index == AS3514_CVDD_DCDC3) { + switch(index) { + case AS3514_CVDD_DCDC3: /* prevent setting of the LREG_CP_not bit */ value &= ~(1 << 5); + break; + case AS3514_IRQ_ENRD0: + /* save value in register shadow + * for ascodec_(en|dis)able_endofch_irq() */ + ascodec_enrd0_shadow = value; + break; + default: + break; } ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1); @@ -375,6 +423,60 @@ int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data) return i; } +static void ascodec_read_cb(unsigned const char *data, unsigned int len) +{ + if (len != 3) /* some error happened? */ + return; + + if (data[0] & CHG_ENDOFCH) { /* chg finished */ + IFDEBUG(int_chg_finished++); + } + if (data[0] & CHG_CHANGED) { /* chg status changed */ + if (data[0] & CHG_STATUS) { + IFDEBUG(int_chg_insert++); + } else { + IFDEBUG(int_chg_remove++); + } + } + if (data[0] & USB_CHANGED) { /* usb status changed */ + if (data[0] & USB_STATUS) { + IFDEBUG(int_usb_insert++); + 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++); + wakeup_signal(&adc_wkup); + } + VIC_INT_ENABLE = INTERRUPT_AUDIO; +} + +void ascodec_wait_adc_finished(void) +{ + wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); +} + + +void ascodec_enable_endofch_irq(void) +{ + ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow | CHG_ENDOFCH); +} + +void ascodec_disable_endofch_irq(void) +{ + ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow & ~CHG_ENDOFCH); +} + /* * NOTE: * After the conversion to interrupts, ascodec_(lock|unlock) are only used by diff --git a/firmware/target/arm/as3525/ascodec-target.h b/firmware/target/arm/as3525/ascodec-target.h index 4b110412c1..13946099c0 100644 --- a/firmware/target/arm/as3525/ascodec-target.h +++ b/firmware/target/arm/as3525/ascodec-target.h @@ -68,6 +68,8 @@ struct ascodec_request { void ascodec_init(void); +void ascodec_init_late(void); + int ascodec_write(unsigned int index, unsigned int value); int ascodec_read(unsigned int index); @@ -102,4 +104,10 @@ void ascodec_lock(void); void ascodec_unlock(void); +void ascodec_wait_adc_finished(void); + +void ascodec_enable_endofch_irq(void); + +void ascodec_disable_endofch_irq(void); + #endif /* !_ASCODEC_TARGET_H */ diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 4ee3e594a5..4e1714b8aa 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -112,6 +112,7 @@ struct vec_int_src vec_int_srcs[] = { INT_SRC_DMAC, INT_DMAC }, { INT_SRC_NAND, INT_NAND }, { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO }, + { INT_SRC_AUDIO, INT_AUDIO }, #ifdef HAVE_MULTIDRIVE { INT_SRC_MCI0, INT_MCI0 }, #endif diff --git a/firmware/target/arm/as3525/usb-as3525.c b/firmware/target/arm/as3525/usb-as3525.c index d5535d00b8..65edb598a3 100644 --- a/firmware/target/arm/as3525/usb-as3525.c +++ b/firmware/target/arm/as3525/usb-as3525.c @@ -29,15 +29,7 @@ #include "power.h" #include "as3525.h" -#if defined(SANSA_CLIP) -#define USB_DETECT_PIN 6 - -#elif defined(SANSA_FUZE) || defined(SANSA_E200V2) -#define USB_DETECT_PIN 3 - -#elif defined(SANSA_C200V2) -#define USB_DETECT_PIN 1 -#endif +static int usb_status = USB_EXTRACTED; void usb_enable(bool on) { @@ -51,19 +43,21 @@ void usb_enable(bool on) #endif } +void usb_insert_int(void) +{ + usb_status = USB_INSERTED; +} + +void usb_remove_int(void) +{ + usb_status = USB_EXTRACTED; +} + void usb_init_device(void) { -#ifdef USB_DETECT_PIN - GPIOA_DIR &= ~(1 << USB_DETECT_PIN); /* set as input */ -#endif } int usb_detect(void) { -#ifdef USB_DETECT_PIN - if (GPIOA_PIN( USB_DETECT_PIN )) - return USB_INSERTED; - else -#endif - return USB_EXTRACTED; + return usb_status; } diff --git a/firmware/target/arm/as3525/usb-target.h b/firmware/target/arm/as3525/usb-target.h new file mode 100644 index 0000000000..55a7d87857 --- /dev/null +++ b/firmware/target/arm/as3525/usb-target.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2006 by Barry Wardelll + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef USB_TARGET_H +#define USB_TARGET_H + +void usb_init_device(void); +void usb_insert_int(void); +void usb_remove_int(void); +int usb_detect(void); + +#endif -- cgit v1.2.3