summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2007-09-11 15:34:54 +0000
committerNils Wallménius <nils@rockbox.org>2007-09-11 15:34:54 +0000
commitcab33b64a02cc17e9da85695817e6196cec4a345 (patch)
treedd10cc714ca73478ebe5f32103cd01e384c1240a
parentc643692201418c631b7ea8b9c68a9595323b1d5a (diff)
downloadrockbox-cab33b64a02cc17e9da85695817e6196cec4a345.tar.gz
rockbox-cab33b64a02cc17e9da85695817e6196cec4a345.zip
Accept patch in FS#7751 by Catalin Patulea, move ifp port specific pcm code to a new file
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14670 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/pcm_playback.c185
-rw-r--r--firmware/target/arm/pnx0101/pcm-pnx0101.c161
3 files changed, 188 insertions, 162 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 7a6e253a81..ab99167a8f 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -745,5 +745,9 @@ target/arm/pnx0101/iriver-ifp7xx/lcd-ifp7xx.c
745target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c 745target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c
746target/arm/pnx0101/iriver-ifp7xx/powermgmt-ifp7xx.c 746target/arm/pnx0101/iriver-ifp7xx/powermgmt-ifp7xx.c
747target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c 747target/arm/pnx0101/iriver-ifp7xx/usb-ifp7xx.c
748#ifndef BOOTLOADER
749target/arm/pnx0101/pcm-pnx0101.c
750#endif
748#endif 751#endif
749#endif 752#endif
753
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index d81853e1cb..e6e59ca604 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -21,9 +21,6 @@
21#include "logf.h" 21#include "logf.h"
22#include "audio.h" 22#include "audio.h"
23#include "sound.h" 23#include "sound.h"
24#if CONFIG_CPU == PNX0101
25#include "string.h"
26#endif /* CONFIG_CPU == PNX0101 */
27 24
28/** 25/**
29 * APIs implemented in the target-specific portion: 26 * APIs implemented in the target-specific portion:
@@ -53,15 +50,29 @@ void pcm_play_pause_unpause(void);
53 50
54/** Functions that require targeted implementation **/ 51/** Functions that require targeted implementation **/
55 52
56#if !defined(CPU_COLDFIRE) && (CONFIG_CPU != S3C2440) 53#if defined(CPU_COLDFIRE) || (CONFIG_CPU == S3C2440)
57 54/* Implemented in target/... */
58#if (CONFIG_CPU == PNX0101) 55#else
59 56/* dummy functions for those not actually supporting all this yet */
60#define DMA_BUF_SAMPLES 0x100 57void pcm_apply_settings(void)
58{
59}
60/** **/
61 61
62short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES]; 62void pcm_mute(bool mute)
63short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES]; 63{
64#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
65 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
66 audiohw_mute(mute);
67#endif
68 if (mute)
69 sleep(HZ/16);
70}
71#endif /* defined(CPU_COLDFIRE) || (CONFIG_CPU == S3C2440) */
64 72
73#if defined(CPU_COLDFIRE) || (CONFIG_CPU == S3C2440) || defined(CPU_PP)
74/* Implemented in target/... */
75#else
65static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ 76static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */
66 77
67unsigned short* p IBSS_ATTR; 78unsigned short* p IBSS_ATTR;
@@ -90,136 +101,6 @@ void pcm_play_pause_unpause(void)
90{ 101{
91} 102}
92 103
93static inline void fill_dma_buf(int offset)
94{
95 short *l, *r, *lend;
96
97 l = dma_buf_left + offset;
98 lend = l + DMA_BUF_SAMPLES / 2;
99 r = dma_buf_right + offset;
100
101 if (pcm_playing && !pcm_paused)
102 {
103 do
104 {
105 int count;
106 unsigned short *tmp_p;
107 count = MIN(p_size / 4, (size_t)(lend - l));
108 tmp_p = p;
109 p_size -= count * 4;
110
111 if ((int)l & 3)
112 {
113 *l++ = *tmp_p++;
114 *r++ = *tmp_p++;
115 count--;
116 }
117 while (count >= 4)
118 {
119 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
120 "and r4, r0, %3\n\t"
121 "orr r4, r4, r1, lsl #16\n\t"
122 "and r5, r2, %3\n\t"
123 "orr r5, r5, r3, lsl #16\n\t"
124 "stmia %1!, {r4, r5}\n\t"
125 "bic r4, r1, %3\n\t"
126 "orr r4, r4, r0, lsr #16\n\t"
127 "bic r5, r3, %3\n\t"
128 "orr r5, r5, r2, lsr #16\n\t"
129 "stmia %2!, {r4, r5}"
130 : "+r" (tmp_p), "+r" (l), "+r" (r)
131 : "r" (0xffff)
132 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
133 count -= 4;
134 }
135 while (count > 0)
136 {
137 *l++ = *tmp_p++;
138 *r++ = *tmp_p++;
139 count--;
140 }
141 p = tmp_p;
142 if (l >= lend)
143 return;
144 else if (pcm_callback_for_more)
145 pcm_callback_for_more((unsigned char**)&p,
146 &p_size);
147 }
148 while (p_size);
149 pcm_playing = false;
150 }
151
152 if (l < lend)
153 {
154 memset(l, 0, sizeof(short) * (lend - l));
155 memset(r, 0, sizeof(short) * (lend - l));
156 }
157}
158
159static void audio_irq(void)
160{
161 unsigned long st = DMAINTSTAT & ~DMAINTEN;
162 int i;
163 for (i = 0; i < 2; i++)
164 if (st & (1 << i))
165 {
166 fill_dma_buf((i == 1) ? 0 : DMA_BUF_SAMPLES / 2);
167 DMAINTSTAT = 1 << i;
168 }
169}
170
171unsigned long physical_address(void *p)
172{
173 unsigned long adr = (unsigned long)p;
174 return (MMUBLOCK((adr >> 21) & 0xf) << 21) | (adr & ((1 << 21) - 1));
175}
176
177void pcm_init(void)
178{
179 int i;
180
181 pcm_playing = false;
182 pcm_paused = false;
183 pcm_callback_for_more = NULL;
184
185 memset(dma_buf_left, 0, sizeof(dma_buf_left));
186 memset(dma_buf_right, 0, sizeof(dma_buf_right));
187
188 for (i = 0; i < 8; i++)
189 {
190 DMASRC(i) = 0;
191 DMADEST(i) = 0;
192 DMALEN(i) = 0x1ffff;
193 DMAR0C(i) = 0;
194 DMAR10(i) = 0;
195 DMAR1C(i) = 0;
196 }
197
198 DMAINTSTAT = 0xc000ffff;
199 DMAINTEN = 0xc000ffff;
200
201 DMASRC(0) = physical_address(dma_buf_left);
202 DMADEST(0) = 0x80200280;
203 DMALEN(0) = 0xff;
204 DMAR1C(0) = 0;
205 DMAR0C(0) = 0x40408;
206
207 DMASRC(1) = physical_address(dma_buf_right);
208 DMADEST(1) = 0x80200284;
209 DMALEN(1) = 0xff;
210 DMAR1C(1) = 0;
211 DMAR0C(1) = 0x40409;
212
213 irq_set_int_handler(0x1b, audio_irq);
214 irq_enable_int(0x1b);
215
216 DMAINTSTAT = 1;
217 DMAINTSTAT = 2;
218 DMAINTEN &= ~3;
219 DMAR10(0) |= 1;
220 DMAR10(1) |= 1;
221}
222
223void pcm_postinit(void) 104void pcm_postinit(void)
224{ 105{
225 audiohw_postinit(); 106 audiohw_postinit();
@@ -234,24 +115,7 @@ size_t pcm_get_bytes_waiting(void)
234{ 115{
235 return p_size; 116 return p_size;
236} 117}
237#endif /* CONFIG_CPU == */
238 118
239/* dummy functions for those not actually supporting all this yet */
240void pcm_apply_settings(void)
241{
242}
243/** **/
244
245void pcm_mute(bool mute)
246{
247#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
248 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
249 audiohw_mute(mute);
250#endif
251 if (mute)
252 sleep(HZ/16);
253}
254#if !defined(CPU_PP)
255/* 119/*
256 * This function goes directly into the DMA buffer to calculate the left and 120 * This function goes directly into the DMA buffer to calculate the left and
257 * right peak values. To avoid missing peaks it tries to look forward two full 121 * right peak values. To avoid missing peaks it tries to look forward two full
@@ -271,10 +135,8 @@ void pcm_calculate_peaks(int *left, int *right)
271 short *addr; 135 short *addr;
272 short *end; 136 short *end;
273 { 137 {
274#if CONFIG_CPU == PNX0101
275 size_t samples = p_size / 4; 138 size_t samples = p_size / 4;
276 addr = p; 139 addr = p;
277#endif /* CONFIG_CPU */.
278 140
279 if (samples > PEAK_SAMPLES) 141 if (samples > PEAK_SAMPLES)
280 samples = PEAK_SAMPLES - (PEAK_STRIDE - 1); 142 samples = PEAK_SAMPLES - (PEAK_STRIDE - 1);
@@ -326,9 +188,7 @@ void pcm_calculate_peaks(int *left, int *right)
326 *right = peak_value; 188 *right = peak_value;
327 } 189 }
328} 190}
329#endif /* !defined(CPU_PP) */ 191#endif /* defined(CPU_COLDFIRE) || (CONFIG_CPU == S3C2440) || defined(CPU_PP) */
330
331#endif /* !defined(CPU_COLDFIRE) && (CONFIG_CPU != S3C2440) */
332 192
333/**************************************************************************** 193/****************************************************************************
334 * Functions that do not require targeted implementation but only a targeted 194 * Functions that do not require targeted implementation but only a targeted
@@ -418,3 +278,4 @@ bool pcm_is_paused(void)
418{ 278{
419 return pcm_paused; 279 return pcm_paused;
420} 280}
281
diff --git a/firmware/target/arm/pnx0101/pcm-pnx0101.c b/firmware/target/arm/pnx0101/pcm-pnx0101.c
new file mode 100644
index 0000000000..8b076cc918
--- /dev/null
+++ b/firmware/target/arm/pnx0101/pcm-pnx0101.c
@@ -0,0 +1,161 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Tomek Malesinski
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "system.h"
20#include "audio.h"
21#include "string.h"
22
23#define DMA_BUF_SAMPLES 0x100
24
25short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES];
26short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES];
27
28/* From pcm_playback.c */
29extern unsigned short* p;
30extern size_t p_size;
31
32static inline void fill_dma_buf(int offset)
33{
34 short *l, *r, *lend;
35
36 l = dma_buf_left + offset;
37 lend = l + DMA_BUF_SAMPLES / 2;
38 r = dma_buf_right + offset;
39
40 if (pcm_playing && !pcm_paused)
41 {
42 do
43 {
44 int count;
45 unsigned short *tmp_p;
46 count = MIN(p_size / 4, (size_t)(lend - l));
47 tmp_p = p;
48 p_size -= count * 4;
49
50 if ((int)l & 3)
51 {
52 *l++ = *tmp_p++;
53 *r++ = *tmp_p++;
54 count--;
55 }
56 while (count >= 4)
57 {
58 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
59 "and r4, r0, %3\n\t"
60 "orr r4, r4, r1, lsl #16\n\t"
61 "and r5, r2, %3\n\t"
62 "orr r5, r5, r3, lsl #16\n\t"
63 "stmia %1!, {r4, r5}\n\t"
64 "bic r4, r1, %3\n\t"
65 "orr r4, r4, r0, lsr #16\n\t"
66 "bic r5, r3, %3\n\t"
67 "orr r5, r5, r2, lsr #16\n\t"
68 "stmia %2!, {r4, r5}"
69 : "+r" (tmp_p), "+r" (l), "+r" (r)
70 : "r" (0xffff)
71 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
72 count -= 4;
73 }
74 while (count > 0)
75 {
76 *l++ = *tmp_p++;
77 *r++ = *tmp_p++;
78 count--;
79 }
80 p = tmp_p;
81 if (l >= lend)
82 return;
83 else if (pcm_callback_for_more)
84 pcm_callback_for_more((unsigned char**)&p,
85 &p_size);
86 }
87 while (p_size);
88 pcm_playing = false;
89 }
90
91 if (l < lend)
92 {
93 memset(l, 0, sizeof(short) * (lend - l));
94 memset(r, 0, sizeof(short) * (lend - l));
95 }
96}
97
98static void audio_irq(void)
99{
100 unsigned long st = DMAINTSTAT & ~DMAINTEN;
101 int i;
102 for (i = 0; i < 2; i++)
103 if (st & (1 << i))
104 {
105 fill_dma_buf((i == 1) ? 0 : DMA_BUF_SAMPLES / 2);
106 DMAINTSTAT = 1 << i;
107 }
108}
109
110unsigned long physical_address(void *p)
111{
112 unsigned long adr = (unsigned long)p;
113 return (MMUBLOCK((adr >> 21) & 0xf) << 21) | (adr & ((1 << 21) - 1));
114}
115
116void pcm_init(void)
117{
118 int i;
119
120 pcm_playing = false;
121 pcm_paused = false;
122 pcm_callback_for_more = NULL;
123
124 memset(dma_buf_left, 0, sizeof(dma_buf_left));
125 memset(dma_buf_right, 0, sizeof(dma_buf_right));
126
127 for (i = 0; i < 8; i++)
128 {
129 DMASRC(i) = 0;
130 DMADEST(i) = 0;
131 DMALEN(i) = 0x1ffff;
132 DMAR0C(i) = 0;
133 DMAR10(i) = 0;
134 DMAR1C(i) = 0;
135 }
136
137 DMAINTSTAT = 0xc000ffff;
138 DMAINTEN = 0xc000ffff;
139
140 DMASRC(0) = physical_address(dma_buf_left);
141 DMADEST(0) = 0x80200280;
142 DMALEN(0) = 0xff;
143 DMAR1C(0) = 0;
144 DMAR0C(0) = 0x40408;
145
146 DMASRC(1) = physical_address(dma_buf_right);
147 DMADEST(1) = 0x80200284;
148 DMALEN(1) = 0xff;
149 DMAR1C(1) = 0;
150 DMAR0C(1) = 0x40409;
151
152 irq_set_int_handler(0x1b, audio_irq);
153 irq_enable_int(0x1b);
154
155 DMAINTSTAT = 1;
156 DMAINTSTAT = 2;
157 DMAINTEN &= ~3;
158 DMAR10(0) |= 1;
159 DMAR10(1) |= 1;
160}
161