summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2011-11-16 14:08:01 +0000
committerTomasz Moń <desowin@gmail.com>2011-11-16 14:08:01 +0000
commite8a8a1be43afe63079ae48ce1a9eb3052df3b1a4 (patch)
tree084e1cdf27a339ce58e24cff8fec8c31432b52db /firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c
parent992d4eb775cac48e107e18d72783ebfb39c4234f (diff)
downloadrockbox-e8a8a1be43afe63079ae48ce1a9eb3052df3b1a4.tar.gz
rockbox-e8a8a1be43afe63079ae48ce1a9eb3052df3b1a4.zip
Sandisk Sansa Connect port (FS #12363)
Included are drivers for buttons, backlight, lcd, audio and storage. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31000 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c')
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c
new file mode 100644
index 0000000000..3f04838388
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/sansa-connect/pcm-sansaconnect.c
@@ -0,0 +1,207 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2011 by Tomasz Moń
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#include <stdlib.h>
22#include "system.h"
23#include "kernel.h"
24#include "logf.h"
25#include "audio.h"
26#include "sound.h"
27#include "file.h"
28#include "dsp-target.h"
29#include "dsp/ipc.h"
30#include "mmu-arm.h"
31#include "pcm-internal.h"
32#include "dma-target.h"
33
34/* This is global to save some latency when pcm_play_dma_get_peak_buffer is
35 * called.
36 */
37static void *start;
38static int dma_channel;
39
40void pcm_play_dma_postinit(void)
41{
42 audiohw_postinit();
43}
44
45/* Return the current location in the SDRAM to SARAM transfer along with the
46 * number of bytes read in the current buffer (count). There is latency with
47 * this method equivalent to ~ the size of the SARAM buffer since there is
48 * another buffer between your ears and this calculation, but this works for
49 * key clicks and an approximate peak meter.
50 */
51const void * pcm_play_dma_get_peak_buffer(int *count)
52{
53 int cnt = DSP_(_sdem_level);
54
55 unsigned long addr = (unsigned long) start + cnt;
56
57 *count = (cnt & 0xFFFFF) >> 1;
58 return (void *)((addr + 2) & ~3);
59}
60
61void pcm_play_dma_init(void)
62{
63 /* GIO16 is DSP/AIC3X CLK */
64 IO_GIO_FSEL0 &= 0x3FFF;
65 IO_CLK_OSEL = (IO_CLK_OSEL & 0xFFF0) | 4; /* PLLIN clock */
66 IO_CLK_O0DIV = 7;
67 IO_GIO_DIR1 &= ~(1 << 0); /* GIO16 - output */
68 IO_GIO_FSEL0 |= 0xC000; /* GIO16 - CLKOUT0 */
69
70 audiohw_init();
71 audiohw_set_frequency(HW_FREQ_DEFAULT);
72
73 IO_INTC_IRQ0 = INTR_IRQ0_IMGBUF;
74 bitset16(&IO_INTC_EINT0, INTR_EINT0_IMGBUF);
75
76 /* Set this as a FIQ */
77 bitset16(&IO_INTC_FISEL0, INTR_EINT0_IMGBUF);
78
79 /* Enable the HPIB clock */
80 bitset16(&IO_CLK_MOD0, (CLK_MOD0_HPIB | CLK_MOD0_DSP));
81
82 /* Enable IMGBUF clock */
83 bitset16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF);
84
85 dma_channel = dma_request_channel(DMA_PERIPHERAL_DSP,
86 DMA_MODE_1_BURST);
87
88 IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
89
90 dsp_reset();
91 dsp_load(dsp_image);
92
93 DSP_(_dma0_stopped)=1;
94 dsp_wake();
95}
96
97void pcm_dma_apply_settings(void)
98{
99 audiohw_set_frequency(pcm_fsel);
100}
101
102/* Note that size is actually limited to the size of a short right now due to
103 * the implementation on the DSP side (and the way that we access it)
104 */
105void pcm_play_dma_start(const void *addr, size_t size)
106{
107 unsigned long sdem_addr=(unsigned long)addr - CONFIG_SDRAM_START;
108 /* Initialize codec. */
109 DSP_(_sdem_addrl) = sdem_addr & 0xffff;
110 DSP_(_sdem_addrh) = sdem_addr >> 16;
111 DSP_(_sdem_dsp_size) = size;
112 DSP_(_dma0_stopped)=0;
113
114 dsp_wake();
115}
116
117void pcm_play_dma_stop(void)
118{
119 DSP_(_dma0_stopped)=1;
120 dsp_wake();
121}
122
123void pcm_play_lock(void)
124{
125
126}
127
128void pcm_play_unlock(void)
129{
130
131}
132
133void pcm_play_dma_pause(bool pause)
134{
135 if (pause)
136 {
137 DSP_(_dma0_stopped)=2;
138 dsp_wake();
139 }
140 else
141 {
142 DSP_(_dma0_stopped)=0;
143 dsp_wake();
144 }
145}
146
147size_t pcm_get_bytes_waiting(void)
148{
149 return DSP_(_sdem_dsp_size)-DSP_(_sdem_level);
150}
151
152/* Only used when debugging */
153static char buffer[80];
154
155void DSPHINT(void) __attribute__ ((section(".icode")));
156void DSPHINT(void)
157{
158 unsigned int i;
159 size_t size;
160
161 IO_INTC_FIQ0 = INTR_IRQ0_IMGBUF;
162
163 switch (dsp_message.msg)
164 {
165 case MSG_DEBUGF:
166 /* DSP stores one character per word. */
167 for (i = 0; i < sizeof(buffer); i++)
168 {
169 buffer[i] = dsp_message.payload.debugf.buffer[i];
170 }
171
172 DEBUGF("DSP: %s", buffer);
173 break;
174
175 case MSG_REFILL:
176 /* Buffer empty. Try to get more. */
177 pcm_play_get_more_callback(&start, &size);
178
179 if (size != 0)
180 {
181 unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
182 /* Flush any pending cache writes */
183 clean_dcache_range(start, size);
184
185 /* set the new DMA values */
186 DSP_(_sdem_addrl) = sdem_addr & 0xffff;
187 DSP_(_sdem_addrh) = sdem_addr >> 16;
188 DSP_(_sdem_dsp_size) = size;
189
190 DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
191 (unsigned long)start, (unsigned long)sdem_addr);
192
193 pcm_play_dma_started_callback();
194 }
195
196 break;
197 default:
198 DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg);
199 break;
200 }
201
202 /* Re-Activate the channel */
203 dsp_wake();
204
205 DEBUGF("DSP: %s", buffer);
206}
207