diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/s5l8700/pcm-s5l8700.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/firmware/target/arm/s5l8700/pcm-s5l8700.c b/firmware/target/arm/s5l8700/pcm-s5l8700.c index aeb3912cfb..5fd5c424ab 100644 --- a/firmware/target/arm/s5l8700/pcm-s5l8700.c +++ b/firmware/target/arm/s5l8700/pcm-s5l8700.c | |||
@@ -42,8 +42,9 @@ | |||
42 | 42 | ||
43 | static volatile int locked = 0; | 43 | static volatile int locked = 0; |
44 | size_t nextsize; | 44 | size_t nextsize; |
45 | size_t dblbufsize; | ||
45 | int dmamode; | 46 | int dmamode; |
46 | unsigned char* dblbuf; | 47 | const unsigned char* dblbuf; |
47 | 48 | ||
48 | /* table of recommended PLL/MCLK dividers for mode 256Fs from the datasheet */ | 49 | /* table of recommended PLL/MCLK dividers for mode 256Fs from the datasheet */ |
49 | static const struct div_entry { | 50 | static const struct div_entry { |
@@ -96,8 +97,8 @@ void pcm_play_unlock(void) | |||
96 | } | 97 | } |
97 | } | 98 | } |
98 | 99 | ||
99 | static void* dma_callback(void) ICODE_ATTR __attribute__((unused)); | 100 | static const void* dma_callback(void) ICODE_ATTR __attribute__((unused)); |
100 | static void* dma_callback(void) | 101 | static const void* dma_callback(void) |
101 | { | 102 | { |
102 | if (dmamode) | 103 | if (dmamode) |
103 | { | 104 | { |
@@ -106,9 +107,10 @@ static void* dma_callback(void) | |||
106 | if (get_more) | 107 | if (get_more) |
107 | { | 108 | { |
108 | get_more(&dma_start_addr, &nextsize); | 109 | get_more(&dma_start_addr, &nextsize); |
109 | if (nextsize > 4096) | 110 | if (nextsize >= 4096) |
110 | { | 111 | { |
111 | nextsize = nextsize - 2048; | 112 | dblbufsize = nextsize >> 4; |
113 | nextsize = nextsize - dblbufsize; | ||
112 | dblbuf = dma_start_addr + nextsize; | 114 | dblbuf = dma_start_addr + nextsize; |
113 | dmamode = 0; | 115 | dmamode = 0; |
114 | } | 116 | } |
@@ -125,7 +127,7 @@ static void* dma_callback(void) | |||
125 | else | 127 | else |
126 | { | 128 | { |
127 | dmamode = 1; | 129 | dmamode = 1; |
128 | nextsize = 1023; | 130 | nextsize = (dblbufsize >> 1) - 1; |
129 | return dblbuf; | 131 | return dblbuf; |
130 | } | 132 | } |
131 | } | 133 | } |
@@ -180,8 +182,10 @@ void bootstrap_fiq(const void* addr, size_t tcnt) | |||
180 | ); | 182 | ); |
181 | } | 183 | } |
182 | 184 | ||
183 | void pcm_play_dma_start(const void *addr, size_t size) | 185 | void pcm_play_dma_start(const void *addr_in, size_t size) |
184 | { | 186 | { |
187 | unsigned char* addr = (unsigned char*)addr_in; | ||
188 | |||
185 | /* S1: DMA channel 0 set */ | 189 | /* S1: DMA channel 0 set */ |
186 | DMACON0 = (0 << 30) | /* DEVSEL */ | 190 | DMACON0 = (0 << 30) | /* DEVSEL */ |
187 | (1 << 29) | /* DIR */ | 191 | (1 << 29) | /* DIR */ |
@@ -221,10 +225,23 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
221 | #endif | 225 | #endif |
222 | 226 | ||
223 | /* S3: DMA channel 0 on */ | 227 | /* S3: DMA channel 0 on */ |
228 | if (!size) | ||
229 | { | ||
230 | register pcm_more_callback_type get_more = pcm_callback_for_more; | ||
231 | if (get_more) get_more(&addr, &size); | ||
232 | else return; /* Nothing to play!? */ | ||
233 | } | ||
234 | if (!size) return; /* Nothing to play!? */ | ||
224 | clean_dcache(); | 235 | clean_dcache(); |
225 | dmamode = 0; | 236 | if (size >= 4096) |
226 | dblbuf = (unsigned char*)addr + size - 2048; | 237 | { |
227 | bootstrap_fiq(addr, (size >> 1) - 1025); | 238 | dblbufsize = size >> 4; |
239 | size = size - dblbufsize; | ||
240 | dblbuf = addr + size; | ||
241 | dmamode = 0; | ||
242 | } | ||
243 | else dmamode = 1; | ||
244 | bootstrap_fiq(addr, (size >> 1) - 1); | ||
228 | 245 | ||
229 | /* S4: IIS Tx clock on */ | 246 | /* S4: IIS Tx clock on */ |
230 | I2SCLKCON = (1 << 0); /* 1 = power on */ | 247 | I2SCLKCON = (1 << 0); /* 1 = power on */ |
@@ -319,7 +336,7 @@ void pcm_dma_apply_settings(void) | |||
319 | 336 | ||
320 | size_t pcm_get_bytes_waiting(void) | 337 | size_t pcm_get_bytes_waiting(void) |
321 | { | 338 | { |
322 | return (DMACTCNT0 + 1) << 1; | 339 | return (nextsize + DMACTCNT0 + 2) << 1; |
323 | } | 340 | } |
324 | 341 | ||
325 | const void * pcm_play_dma_get_peak_buffer(int *count) | 342 | const void * pcm_play_dma_get_peak_buffer(int *count) |