diff options
author | Tobias Diedrich <ranma+coreboot@tdiedrich.de> | 2010-03-23 05:02:37 +0000 |
---|---|---|
committer | Tobias Diedrich <ranma+coreboot@tdiedrich.de> | 2010-03-23 05:02:37 +0000 |
commit | 47ab95904efe238568e4cc66f0d3aacd9e7a8c10 (patch) | |
tree | 8da94d74b9e0ef3ad01011d706781577eeec0e26 /firmware/target/arm/as3525 | |
parent | 655034983547c0678842e7407cebe0ea12b006cc (diff) | |
download | rockbox-47ab95904efe238568e4cc66f0d3aacd9e7a8c10.tar.gz rockbox-47ab95904efe238568e4cc66f0d3aacd9e7a8c10.zip |
Add handler for audio irq.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25299 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525')
-rw-r--r-- | firmware/target/arm/as3525/ascodec-as3525.c | 108 | ||||
-rw-r--r-- | firmware/target/arm/as3525/ascodec-target.h | 8 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-as3525.c | 1 | ||||
-rw-r--r-- | firmware/target/arm/as3525/usb-as3525.c | 30 | ||||
-rw-r--r-- | firmware/target/arm/as3525/usb-target.h | 29 |
5 files changed, 155 insertions, 21 deletions
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 @@ | |||
50 | #include "system.h" | 50 | #include "system.h" |
51 | #include "as3525.h" | 51 | #include "as3525.h" |
52 | #include "i2c.h" | 52 | #include "i2c.h" |
53 | #include "usb-target.h" | ||
53 | 54 | ||
54 | #define I2C2_DATA *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x00)) | 55 | #define I2C2_DATA *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x00)) |
55 | #define I2C2_SLAD0 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x04)) | 56 | #define I2C2_SLAD0 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x04)) |
@@ -81,15 +82,47 @@ | |||
81 | #define REQ_FINISHED 1 | 82 | #define REQ_FINISHED 1 |
82 | #define REQ_RETRY 2 | 83 | #define REQ_RETRY 2 |
83 | 84 | ||
85 | #ifdef DEBUG | ||
86 | #define IFDEBUG(x) x | ||
87 | #else | ||
88 | #define IFDEBUG(x) | ||
89 | #endif | ||
90 | |||
84 | static struct mutex as_mtx; | 91 | static struct mutex as_mtx; |
85 | 92 | ||
93 | static int ascodec_enrd0_shadow = 0; | ||
94 | |||
86 | static unsigned char *req_data_ptr = NULL; | 95 | static unsigned char *req_data_ptr = NULL; |
87 | static struct ascodec_request *req_head = NULL; | 96 | static struct ascodec_request *req_head = NULL; |
88 | static struct ascodec_request *req_tail = NULL; | 97 | static struct ascodec_request *req_tail = NULL; |
89 | 98 | ||
99 | static struct wakeup adc_wkup; | ||
100 | |||
101 | #ifdef DEBUG | ||
102 | static int int_audio_ctr = 0; | ||
103 | static int int_chg_finished = 0; | ||
104 | static int int_chg_insert = 0; | ||
105 | static int int_chg_remove = 0; | ||
106 | static int int_usb_insert = 0; | ||
107 | static int int_usb_remove = 0; | ||
108 | static int int_rtc = 0; | ||
109 | static int int_adc = 0; | ||
110 | #endif | ||
111 | |||
112 | static struct ascodec_request as_audio_req; | ||
113 | |||
90 | static void ascodec_start_req(struct ascodec_request *req); | 114 | static void ascodec_start_req(struct ascodec_request *req); |
91 | static int ascodec_continue_req(struct ascodec_request *req, int irq_status); | 115 | static int ascodec_continue_req(struct ascodec_request *req, int irq_status); |
92 | static void ascodec_finish_req(struct ascodec_request *req); | 116 | static void ascodec_finish_req(struct ascodec_request *req); |
117 | static void ascodec_read_cb(unsigned const char *data, unsigned int len); | ||
118 | |||
119 | void INT_AUDIO(void) | ||
120 | { | ||
121 | VIC_INT_EN_CLEAR = INTERRUPT_AUDIO; | ||
122 | IFDEBUG(int_audio_ctr++); | ||
123 | |||
124 | ascodec_async_read(AS3514_IRQ_ENRD0, 3, &as_audio_req, ascodec_read_cb); | ||
125 | } | ||
93 | 126 | ||
94 | void INT_I2C_AUDIO(void) | 127 | void INT_I2C_AUDIO(void) |
95 | { | 128 | { |
@@ -129,6 +162,7 @@ void ascodec_init(void) | |||
129 | int prescaler; | 162 | int prescaler; |
130 | 163 | ||
131 | mutex_init(&as_mtx); | 164 | mutex_init(&as_mtx); |
165 | wakeup_init(&adc_wkup); | ||
132 | 166 | ||
133 | /* enable clock */ | 167 | /* enable clock */ |
134 | CGU_PERI |= CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE; | 168 | CGU_PERI |= CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE; |
@@ -145,9 +179,14 @@ void ascodec_init(void) | |||
145 | 179 | ||
146 | I2C2_IMR = 0x00; /* disable interrupts */ | 180 | I2C2_IMR = 0x00; /* disable interrupts */ |
147 | I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ | 181 | I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ |
148 | VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO; | 182 | VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO | INTERRUPT_AUDIO; |
149 | } | ||
150 | 183 | ||
184 | /* Generate irq for usb+charge status change */ | ||
185 | ascodec_write(AS3514_IRQ_ENRD0, /*IRQ_CHGSTAT |*/ IRQ_USBSTAT); | ||
186 | /* Generate irq for push-pull, active high, irq on rtc+adc change */ | ||
187 | ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE | | ||
188 | /*IRQ_RTC |*/ IRQ_ADC); | ||
189 | } | ||
151 | 190 | ||
152 | /* returns != 0 when busy */ | 191 | /* returns != 0 when busy */ |
153 | static int i2c_busy(void) | 192 | static int i2c_busy(void) |
@@ -297,9 +336,18 @@ static void ascodec_wait(struct ascodec_request *req) | |||
297 | void ascodec_async_write(unsigned int index, unsigned int value, | 336 | void ascodec_async_write(unsigned int index, unsigned int value, |
298 | struct ascodec_request *req) | 337 | struct ascodec_request *req) |
299 | { | 338 | { |
300 | if (index == AS3514_CVDD_DCDC3) { | 339 | switch(index) { |
340 | case AS3514_CVDD_DCDC3: | ||
301 | /* prevent setting of the LREG_CP_not bit */ | 341 | /* prevent setting of the LREG_CP_not bit */ |
302 | value &= ~(1 << 5); | 342 | value &= ~(1 << 5); |
343 | break; | ||
344 | case AS3514_IRQ_ENRD0: | ||
345 | /* save value in register shadow | ||
346 | * for ascodec_(en|dis)able_endofch_irq() */ | ||
347 | ascodec_enrd0_shadow = value; | ||
348 | break; | ||
349 | default: | ||
350 | break; | ||
303 | } | 351 | } |
304 | 352 | ||
305 | ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1); | 353 | 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) | |||
375 | return i; | 423 | return i; |
376 | } | 424 | } |
377 | 425 | ||
426 | static void ascodec_read_cb(unsigned const char *data, unsigned int len) | ||
427 | { | ||
428 | if (len != 3) /* some error happened? */ | ||
429 | return; | ||
430 | |||
431 | if (data[0] & CHG_ENDOFCH) { /* chg finished */ | ||
432 | IFDEBUG(int_chg_finished++); | ||
433 | } | ||
434 | if (data[0] & CHG_CHANGED) { /* chg status changed */ | ||
435 | if (data[0] & CHG_STATUS) { | ||
436 | IFDEBUG(int_chg_insert++); | ||
437 | } else { | ||
438 | IFDEBUG(int_chg_remove++); | ||
439 | } | ||
440 | } | ||
441 | if (data[0] & USB_CHANGED) { /* usb status changed */ | ||
442 | if (data[0] & USB_STATUS) { | ||
443 | IFDEBUG(int_usb_insert++); | ||
444 | usb_insert_int(); | ||
445 | } else { | ||
446 | IFDEBUG(int_usb_remove++); | ||
447 | usb_remove_int(); | ||
448 | } | ||
449 | } | ||
450 | if (data[2] & IRQ_RTC) { /* rtc irq */ | ||
451 | /* | ||
452 | * Can be configured for once per second or once per minute, | ||
453 | * default is once per second | ||
454 | */ | ||
455 | IFDEBUG(int_rtc++); | ||
456 | } | ||
457 | if (data[2] & IRQ_ADC) { /* adc finished */ | ||
458 | IFDEBUG(int_adc++); | ||
459 | wakeup_signal(&adc_wkup); | ||
460 | } | ||
461 | VIC_INT_ENABLE = INTERRUPT_AUDIO; | ||
462 | } | ||
463 | |||
464 | void ascodec_wait_adc_finished(void) | ||
465 | { | ||
466 | wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); | ||
467 | } | ||
468 | |||
469 | |||
470 | void ascodec_enable_endofch_irq(void) | ||
471 | { | ||
472 | ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow | CHG_ENDOFCH); | ||
473 | } | ||
474 | |||
475 | void ascodec_disable_endofch_irq(void) | ||
476 | { | ||
477 | ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow & ~CHG_ENDOFCH); | ||
478 | } | ||
479 | |||
378 | /* | 480 | /* |
379 | * NOTE: | 481 | * NOTE: |
380 | * After the conversion to interrupts, ascodec_(lock|unlock) are only used by | 482 | * 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 { | |||
68 | 68 | ||
69 | void ascodec_init(void); | 69 | void ascodec_init(void); |
70 | 70 | ||
71 | void ascodec_init_late(void); | ||
72 | |||
71 | int ascodec_write(unsigned int index, unsigned int value); | 73 | int ascodec_write(unsigned int index, unsigned int value); |
72 | 74 | ||
73 | int ascodec_read(unsigned int index); | 75 | int ascodec_read(unsigned int index); |
@@ -102,4 +104,10 @@ void ascodec_lock(void); | |||
102 | 104 | ||
103 | void ascodec_unlock(void); | 105 | void ascodec_unlock(void); |
104 | 106 | ||
107 | void ascodec_wait_adc_finished(void); | ||
108 | |||
109 | void ascodec_enable_endofch_irq(void); | ||
110 | |||
111 | void ascodec_disable_endofch_irq(void); | ||
112 | |||
105 | #endif /* !_ASCODEC_TARGET_H */ | 113 | #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[] = | |||
112 | { INT_SRC_DMAC, INT_DMAC }, | 112 | { INT_SRC_DMAC, INT_DMAC }, |
113 | { INT_SRC_NAND, INT_NAND }, | 113 | { INT_SRC_NAND, INT_NAND }, |
114 | { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO }, | 114 | { INT_SRC_I2C_AUDIO, INT_I2C_AUDIO }, |
115 | { INT_SRC_AUDIO, INT_AUDIO }, | ||
115 | #ifdef HAVE_MULTIDRIVE | 116 | #ifdef HAVE_MULTIDRIVE |
116 | { INT_SRC_MCI0, INT_MCI0 }, | 117 | { INT_SRC_MCI0, INT_MCI0 }, |
117 | #endif | 118 | #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 @@ | |||
29 | #include "power.h" | 29 | #include "power.h" |
30 | #include "as3525.h" | 30 | #include "as3525.h" |
31 | 31 | ||
32 | #if defined(SANSA_CLIP) | 32 | static int usb_status = USB_EXTRACTED; |
33 | #define USB_DETECT_PIN 6 | ||
34 | |||
35 | #elif defined(SANSA_FUZE) || defined(SANSA_E200V2) | ||
36 | #define USB_DETECT_PIN 3 | ||
37 | |||
38 | #elif defined(SANSA_C200V2) | ||
39 | #define USB_DETECT_PIN 1 | ||
40 | #endif | ||
41 | 33 | ||
42 | void usb_enable(bool on) | 34 | void usb_enable(bool on) |
43 | { | 35 | { |
@@ -51,19 +43,21 @@ void usb_enable(bool on) | |||
51 | #endif | 43 | #endif |
52 | } | 44 | } |
53 | 45 | ||
46 | void usb_insert_int(void) | ||
47 | { | ||
48 | usb_status = USB_INSERTED; | ||
49 | } | ||
50 | |||
51 | void usb_remove_int(void) | ||
52 | { | ||
53 | usb_status = USB_EXTRACTED; | ||
54 | } | ||
55 | |||
54 | void usb_init_device(void) | 56 | void usb_init_device(void) |
55 | { | 57 | { |
56 | #ifdef USB_DETECT_PIN | ||
57 | GPIOA_DIR &= ~(1 << USB_DETECT_PIN); /* set as input */ | ||
58 | #endif | ||
59 | } | 58 | } |
60 | 59 | ||
61 | int usb_detect(void) | 60 | int usb_detect(void) |
62 | { | 61 | { |
63 | #ifdef USB_DETECT_PIN | 62 | return usb_status; |
64 | if (GPIOA_PIN( USB_DETECT_PIN )) | ||
65 | return USB_INSERTED; | ||
66 | else | ||
67 | #endif | ||
68 | return USB_EXTRACTED; | ||
69 | } | 63 | } |
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 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardelll | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef USB_TARGET_H | ||
22 | #define USB_TARGET_H | ||
23 | |||
24 | void usb_init_device(void); | ||
25 | void usb_insert_int(void); | ||
26 | void usb_remove_int(void); | ||
27 | int usb_detect(void); | ||
28 | |||
29 | #endif | ||