Index: rockbox-irqwork/firmware/target/arm/as3525/system-as3525.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/as3525/system-as3525.c 2010-03-20 04:11:10.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/as3525/system-as3525.c 2010-03-20 04:11:57.522844855 +0900 @@ -112,6 +112,7 @@ { 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 Index: rockbox-irqwork/firmware/target/arm/as3525/usb-as3525.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/as3525/usb-as3525.c 2010-03-17 23:53:02.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/as3525/usb-as3525.c 2010-03-20 04:15:55.849747461 +0900 @@ -39,6 +39,8 @@ #define USB_DETECT_PIN 1 #endif +static int usb_status = USB_EXTRACTED; + void usb_enable(bool on) { #ifdef HAVE_USBSTACK @@ -51,19 +53,21 @@ #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; } Index: rockbox-irqwork/firmware/target/arm/as3525/audio-as3525.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/as3525/audio-as3525.c 2010-03-17 23:53:02.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/as3525/audio-as3525.c 2010-03-20 04:11:57.526846275 +0900 @@ -24,6 +24,109 @@ #include "audio.h" #include "audiohw.h" #include "sound.h" +#include "ascodec-target.h" +#include "kernel.h" +#include "system.h" +#include "as3525.h" +#include "usb-target.h" +#include "audio-target.h" + +static struct wakeup adc_wkup; +static int adc_wkup_initok = 0; +static int adc_wkup_called_without_init = 0; + +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; +static int int_unknown = 0; +static char int_unknown_state[3] = { 0 }; + +static struct ascodec_request as_audio_req; + +static void as_read_cb(unsigned const char *data, unsigned int len) +{ + int got_reason = 0; + + if (len != 3) /* some error happened? */ + return; + + if (data[0] & CHG_ENDOFCH) { /* chg finished */ + got_reason = 1; + int_chg_finished++; + } + if (data[0] & CHG_CHANGED) { /* chg status changed */ + got_reason = 1; + if (data[0] & CHG_STATUS) { + int_chg_insert++; + } else { + int_chg_remove++; + } + } + if (data[0] & USB_CHANGED) { /* usb status changed */ + got_reason = 1; + if (data[0] & USB_STATUS) { + int_usb_insert++; + usb_insert_int(); + } else { + int_usb_remove++; + usb_remove_int(); + } + } + if (data[2] & IRQ_RTC) { /* rtc irq */ + /* can be configure for once per second or once per minute */ + got_reason = 1; + int_rtc++; + } + if (data[2] & IRQ_ADC) { /* adc finished */ + got_reason = 1; + int_adc++; + wakeup_signal(&adc_wkup); + } + if (!got_reason) { + int_unknown++; + int_unknown_state[0] = data[0]; + int_unknown_state[1] = data[1]; + int_unknown_state[2] = data[2]; + } + VIC_INT_ENABLE = INTERRUPT_AUDIO; +} + +void INT_AUDIO(void) +{ + VIC_INT_EN_CLEAR = INTERRUPT_AUDIO; + int_audio_ctr++; + + ascodec_async_read(AS3514_IRQ_ENRD0, 3, &as_audio_req, as_read_cb); +} + +void audio_wait_adc_finished(void) +{ + if (!adc_wkup_initok) { + /* FIXME: Check ordering? Use delay loop? */ + adc_wkup_called_without_init++; + return; + } + wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); +} + +void audio_irq_init(void) +{ + wakeup_init(&adc_wkup); + adc_wkup_initok = 1; + + /* 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); + + VIC_INT_ENABLE = INTERRUPT_AUDIO; +} void audio_set_output_source(int source) { @@ -100,3 +203,5 @@ last_source = source; } + +/* vim:set ts=4 sw=4 et: */ Index: rockbox-irqwork/firmware/target/arm/as3525/power-as3525.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/as3525/power-as3525.c 2010-03-17 23:53:02.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/as3525/power-as3525.c 2010-03-20 04:11:57.530846999 +0900 @@ -23,6 +23,7 @@ #include "ascodec-target.h" #include "as3514.h" #include "power.h" +#include "audio-target.h" void power_off(void) { @@ -36,6 +37,7 @@ void power_init(void) { + audio_irq_init(); } #if CONFIG_CHARGING Index: rockbox-irqwork/firmware/target/arm/adc-as3514.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/adc-as3514.c 2010-03-20 04:11:10.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/adc-as3514.c 2010-03-20 04:11:57.530846999 +0900 @@ -22,6 +22,7 @@ #include "kernel.h" #include "ascodec.h" #include "as3514.h" +#include "audio-target.h" static struct mutex adc_mtx; @@ -39,7 +40,7 @@ { unsigned char buf[2]; - /* FIXME: Should wait until 'conversion finished' is signaled. */ + audio_wait_adc_finished(); /* Read data */ if (ascodec_readbytes(AS3514_ADC_0, 2, buf) >= 0) { Index: rockbox-irqwork/firmware/export/as3514.h =================================================================== --- rockbox-irqwork.orig/firmware/export/as3514.h 2010-03-17 23:52:24.000000000 +0900 +++ rockbox-irqwork/firmware/export/as3514.h 2010-03-20 04:11:57.534846535 +0900 @@ -282,6 +282,21 @@ #define RVDD_WASLOW (0x1 << 1) #define BVDD_ISLOW (0x1 << 0) +#define IRQ_ENDOFCH (0x1 << 6) +#define IRQ_CHGSTAT (0x1 << 4) +#define IRQ_USBSTAT (0x1 << 2) + +/* AS3514_IRQ_ENRD2 */ +#define DEBOUNCE_128MS (0x2 << 6) +#define DEBOUNCE_256MS (0x1 << 6) +#define DEBOUNCE_512MS (0x0 << 6) +#define IRQ_HIGHACTIVE (0x1 << 5) +#define IRQ_PUSHPULL (0x1 << 4) +#define IRQ_REMDET2 (0x1 << 3) +#define IRQ_REMDET1 (0x1 << 2) +#define IRQ_RTC (0x1 << 1) +#define IRQ_ADC (0x1 << 0) + #define AS3514_I2C_ADDR 0x46 #endif /* _AS3514_H */ Index: rockbox-irqwork/firmware/target/arm/ascodec-target.h =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/ascodec-target.h 2010-03-17 23:53:21.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/ascodec-target.h 2010-03-20 04:11:57.534846535 +0900 @@ -59,6 +59,16 @@ i2c_unlock(); } +static inline void ascodec_enable_endofch_irq(void) +{ + ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH); +} + +static inline void ascodec_disable_endofch_irq(void) +{ + ascodec_write(AS3514_IRQ_ENRD0, 0); +} + extern void ascodec_suppressor_on(bool on); #endif /* CPU_PP */ Index: rockbox-irqwork/firmware/target/arm/powermgmt-ascodec.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/powermgmt-ascodec.c 2010-03-17 23:53:21.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/powermgmt-ascodec.c 2010-03-20 04:11:57.534846535 +0900 @@ -94,7 +94,7 @@ /* Disable charger and minimize all settings. Reset timers, etc. */ static void disable_charger(void) { - ascodec_write(AS3514_IRQ_ENRD0, 0); + ascodec_disable_endofch_irq(); ascodec_write(AS3514_CHARGER, TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF); @@ -111,11 +111,11 @@ ascodec_write(AS3514_CHARGER, BATT_CHG_I | BATT_CHG_V); /* Watch for end of charge. Temperature supervision is handled in * hardware. Charger status can be read and has no interrupt enable. */ - ascodec_write(AS3514_IRQ_ENRD0, CHG_ENDOFCH); + ascodec_enable_endofch_irq(); sleep(HZ/10); /* Allow charger turn-on time (it could be gradual). */ - ascodec_read(AS3514_IRQ_ENRD0); /* Clear out interrupts (important!) */ + ascodec_disable_endofch_irq(); charge_state = CHARGING; charger_total_timer = CHARGER_TOTAL_TIMER; @@ -125,7 +125,7 @@ void powermgmt_init_target(void) { /* Everything CHARGER, OFF! */ - ascodec_write(AS3514_IRQ_ENRD0, 0); + ascodec_disable_endofch_irq(); ascodec_write(AS3514_CHARGER, TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF); } Index: rockbox-irqwork/firmware/target/arm/as3525/usb-target.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ rockbox-irqwork/firmware/target/arm/as3525/usb-target.h 2010-03-20 04:11:57.538845721 +0900 @@ -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 Index: rockbox-irqwork/firmware/target/arm/as3525/ascodec-target.h =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/as3525/ascodec-target.h 2010-03-20 04:11:10.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/as3525/ascodec-target.h 2010-03-20 04:11:57.538845721 +0900 @@ -107,4 +107,14 @@ static inline void ascodec_unlock(void) { } +static inline void ascodec_enable_endofch_irq(void) +{ + ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow | CHG_ENDOFCH); +} + +static inline void ascodec_disable_endofch_irq(void) +{ + ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow & ~CHG_ENDOFCH); +} + #endif /* !_ASCODEC_TARGET_H */ Index: rockbox-irqwork/firmware/target/arm/as3525/ascodec-as3525.c =================================================================== --- rockbox-irqwork.orig/firmware/target/arm/as3525/ascodec-as3525.c 2010-03-20 04:11:10.000000000 +0900 +++ rockbox-irqwork/firmware/target/arm/as3525/ascodec-as3525.c 2010-03-20 04:11:57.538845721 +0900 @@ -73,6 +73,8 @@ #define REQ_FINISHED 1 #define REQ_RETRY 2 +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; @@ -261,9 +263,18 @@ 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); Index: rockbox-irqwork/firmware/target/arm/as3525/audio-target.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ rockbox-irqwork/firmware/target/arm/as3525/audio-target.h 2010-03-20 04:11:57.538845721 +0900 @@ -0,0 +1,28 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright © 2010 Tobias Diedrich + * + * 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 AUDIO_TARGET_H +#define AUDIO_TARGET_H + +void audio_irq_init(void); +void audio_wait_adc_finished(void); + +#endif