summaryrefslogtreecommitdiff
path: root/firmware/target
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 /firmware/target
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
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/pnx0101/pcm-pnx0101.c161
1 files changed, 161 insertions, 0 deletions
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