Fix tuning into weird frequencies at unpause after changing region setting
[Rockbox.git] / firmware / pcm_playback.c
blob7382661f4840a3d1400baf6ec7f81a4dfe01e5e6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdbool.h>
20 #include "config.h"
21 #include "debug.h"
22 #include "panic.h"
23 #include <kernel.h>
24 #include "cpu.h"
25 #include "i2c.h"
26 #if defined(HAVE_UDA1380)
27 #include "uda1380.h"
28 #elif defined(HAVE_WM8975)
29 #include "wm8975.h"
30 #elif defined(HAVE_WM8758)
31 #include "wm8758.h"
32 #elif defined(HAVE_TLV320)
33 #include "tlv320.h"
34 #elif defined(HAVE_WM8731) || defined(HAVE_WM8721)
35 #include "wm8731l.h"
36 #elif CONFIG_CPU == PNX0101
37 #include "pnx0101.h"
38 #endif
39 #include "system.h"
40 #include "logf.h"
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdarg.h>
45 #include "pcm_playback.h"
46 #include "lcd.h"
47 #include "button.h"
48 #include "file.h"
49 #include "buffer.h"
50 #include "sprintf.h"
51 #include "button.h"
52 #include <string.h>
54 static bool pcm_playing;
55 static bool pcm_paused;
57 /* the registered callback function to ask for more mp3 data */
58 static void (*callback_for_more)(unsigned char**, size_t*) IDATA_ATTR = NULL;
60 #if (CONFIG_CPU == S3C2440)
62 /* TODO: Implement for Gigabeat
63 For now, just implement some dummy functions.
66 void pcm_init(void)
71 void pcm_set_frequency(unsigned int frequency)
73 (void)frequency;
76 void pcm_play_stop(void)
80 size_t pcm_get_bytes_waiting(void)
82 return 0;
84 #else
85 #ifdef CPU_COLDFIRE
87 #ifdef HAVE_SPDIF_OUT
88 #define EBU_DEFPARM ((7 << 12) | (3 << 8) | (1 << 5) | (5 << 2))
89 #endif
90 #define IIS_DEFPARM(freq) ((freq << 12) | 0x300 | 4 << 2)
91 #define IIS_RESET 0x800
93 #ifdef IAUDIO_X5
94 #define SET_IIS_CONFIG(x) IIS1CONFIG = (x);
95 #else
96 #define SET_IIS_CONFIG(x) IIS2CONFIG = (x);
97 #endif
99 static int pcm_freq = 0x6; /* 44.1 is default */
101 int peak_left = 0, peak_right = 0;
103 /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
104 static void dma_start(const void *addr, size_t size)
106 pcm_playing = true;
108 addr = (void *)((unsigned long)addr & ~3); /* Align data */
109 size &= ~3; /* Size must be multiple of 4 */
111 /* Reset the audio FIFO */
112 #ifdef HAVE_SPDIF_OUT
113 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
114 #endif
116 /* Set up DMA transfer */
117 SAR0 = (unsigned long)addr; /* Source address */
118 DAR0 = (unsigned long)&PDOR3; /* Destination address */
119 BCR0 = size; /* Bytes to transfer */
121 /* Enable the FIFO and force one write to it */
122 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq));
123 /* Also send the audio to S/PDIF */
124 #ifdef HAVE_SPDIF_OUT
125 EBU1CONFIG = EBU_DEFPARM;
126 #endif
127 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_SINC | (3 << 20) | DMA_START;
130 /* Stops the DMA transfer and interrupt */
131 static void dma_stop(void)
133 pcm_playing = false;
135 DCR0 = 0;
136 DSR0 = 1;
137 /* Reset the FIFO */
138 SET_IIS_CONFIG(IIS_RESET | IIS_DEFPARM(pcm_freq));
139 #ifdef HAVE_SPDIF_OUT
140 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
141 #endif
144 /* sets frequency of input to DAC */
145 void pcm_set_frequency(unsigned int frequency)
147 switch(frequency)
149 case 11025:
150 pcm_freq = 0x2;
151 #ifdef HAVE_UDA1380
152 uda1380_set_nsorder(3);
153 #endif
154 break;
155 case 22050:
156 pcm_freq = 0x4;
157 #ifdef HAVE_UDA1380
158 uda1380_set_nsorder(3);
159 #endif
160 break;
161 case 44100:
162 default:
163 pcm_freq = 0x6;
164 #ifdef HAVE_UDA1380
165 uda1380_set_nsorder(5);
166 #endif
167 break;
171 size_t pcm_get_bytes_waiting(void)
173 return (BCR0 & 0xffffff);
176 /* DMA0 Interrupt is called when the DMA has finished transfering a chunk */
177 void DMA0(void) __attribute__ ((interrupt_handler, section(".icode")));
178 void DMA0(void)
180 int res = DSR0;
182 DSR0 = 1; /* Clear interrupt */
183 DCR0 &= ~DMA_EEXT;
185 /* Stop on error */
186 if(res & 0x70)
188 dma_stop();
189 logf("DMA Error:0x%04x", res);
191 else
193 size_t next_size;
194 unsigned char *next_start;
196 void (*get_more)(unsigned char**, size_t*) = callback_for_more;
197 if (get_more)
198 get_more(&next_start, &next_size);
199 else
201 next_size = 0;
202 next_start = NULL;
205 if(next_size)
207 SAR0 = (unsigned long)next_start; /* Source address */
208 BCR0 = next_size; /* Bytes to transfer */
209 DCR0 |= DMA_EEXT;
211 else
213 /* Finished playing */
214 dma_stop();
215 logf("DMA No Data:0x%04x", res);
219 IPR |= (1<<14); /* Clear pending interrupt request */
222 void pcm_init(void)
224 pcm_playing = false;
225 pcm_paused = false;
227 MPARK = 0x81; /* PARK[1,0]=10 + BCR24BIT */
228 DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
229 DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1;
230 DMACONFIG = 1; /* DMA0Req = PDOR3 */
232 /* Reset the audio FIFO */
233 SET_IIS_CONFIG(IIS_RESET);
235 /* Enable interrupt at level 7, priority 0 */
236 ICR6 = 0x1c;
237 IMR &= ~(1<<14); /* bit 14 is DMA0 */
239 pcm_set_frequency(44100);
241 /* Prevent pops (resets DAC to zero point) */
242 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq) | IIS_RESET);
244 #if defined(HAVE_UDA1380)
245 /* Initialize default register values. */
246 uda1380_init();
248 /* Sleep a while so the power can stabilize (especially a long
249 delay is needed for the line out connector). */
250 sleep(HZ);
252 /* Power on FSDAC and HP amp. */
253 uda1380_enable_output(true);
255 /* Unmute the master channel (DAC should be at zero point now). */
256 uda1380_mute(false);
258 #elif defined(HAVE_TLV320)
259 tlv320_init();
260 sleep(HZ/4);
261 tlv320_mute(false);
262 #endif
264 /* Call dma_stop to initialize everything. */
265 dma_stop();
268 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
269 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
271 /* We need to unify this code with the uda1380 code as much as possible, but
272 we will keep it separate during early development.
275 #if CONFIG_CPU == PP5020
276 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16)
277 #elif CONFIG_CPU == PP5002
278 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
279 #elif CONFIG_CPU == PP5024
280 #define FIFO_FREE_COUNT 4 /* TODO: make this sensible */
281 #endif
283 static int pcm_freq = 44100; /* 44.1 is default */
285 /* NOTE: The order of these two variables is important if you use the iPod
286 assembler optimised fiq handler, so don't change it. */
287 unsigned short* p IBSS_ATTR;
288 size_t p_size IBSS_ATTR;
290 static void dma_start(const void *addr, size_t size)
292 p=(unsigned short*)addr;
293 p_size=size;
295 pcm_playing = true;
297 #if CONFIG_CPU == PP5020
298 /* setup I2S interrupt for FIQ */
299 outl(inl(0x6000402c) | I2S_MASK, 0x6000402c);
300 outl(I2S_MASK, 0x60004024);
301 #elif CONFIG_CPU == PP5024
302 #else
303 /* setup I2S interrupt for FIQ */
304 outl(inl(0xcf00102c) | DMA_OUT_MASK, 0xcf00102c);
305 outl(DMA_OUT_MASK, 0xcf001024);
306 #endif
308 /* Clear the FIQ disable bit in cpsr_c */
309 enable_fiq();
311 /* Enable playback FIFO */
312 #if CONFIG_CPU == PP5020
313 IISCONFIG |= 0x20000000;
314 #elif CONFIG_CPU == PP5002
315 IISCONFIG |= 0x4;
316 #endif
318 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
319 fill the 32-byte FIFO. */
320 while (p_size > 0) {
321 if (FIFO_FREE_COUNT < 2) {
322 /* Enable interrupt */
323 #if CONFIG_CPU == PP5020
324 IISCONFIG |= 0x2;
325 #elif CONFIG_CPU == PP5002
326 IISFIFO_CFG |= (1<<9);
327 #endif
328 return;
331 IISFIFO_WR = (*(p++))<<16;
332 IISFIFO_WR = (*(p++))<<16;
333 p_size-=4;
337 /* Stops the DMA transfer and interrupt */
338 static void dma_stop(void)
340 pcm_playing = false;
342 #if CONFIG_CPU == PP5020
344 /* Disable playback FIFO */
345 IISCONFIG &= ~0x20000000;
347 /* Disable the interrupt */
348 IISCONFIG &= ~0x2;
350 #elif CONFIG_CPU == PP5002
352 /* Disable playback FIFO */
353 IISCONFIG &= ~0x4;
355 /* Disable the interrupt */
356 IISFIFO_CFG &= ~(1<<9);
357 #endif
359 disable_fiq();
362 void pcm_set_frequency(unsigned int frequency)
364 pcm_freq=frequency;
367 size_t pcm_get_bytes_waiting(void)
369 return p_size;
372 /* ASM optimised FIQ handler. GCC fails to make use of the fact that FIQ mode
373 has registers r8-r14 banked, and so does not need to be saved. This routine
374 uses only these registers, and so will never touch the stack unless it
375 actually needs to do so when calling callback_for_more. C version is still
376 included below for reference.
378 #if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
379 void fiq(void) ICODE_ATTR __attribute__((naked));
380 void fiq(void)
382 /* r12 contains IISCONFIG address (set in crt0.S to minimise code in actual
383 * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
384 * addresses we need are generated by using offsets with these two.
385 * r12 + 0x40 is IISFIFO_WR, and r12 + 0x0c is IISFIFO_CFG.
386 * r8 and r9 contains local copies of p_size and p respectively.
387 * r10 is a working register.
389 asm volatile (
390 #if CONFIG_CPU == PP5002
391 "ldr r10, =0xcf001040 \n\t" /* Some magic from iPodLinux */
392 "ldr r10, [r10] \n\t"
393 "ldr r10, [r12, #0x1c]\n\t"
394 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
395 "str r10, [r12, #0x1c]\n\t"
396 #else
397 "ldr r10, [r12] \n\t"
398 "bic r10, r10, #0x2 \n\t" /* clear interrupt */
399 "str r10, [r12] \n\t"
400 #endif
401 "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
402 "ldr r9, [r11] \n\t" /* r9 = p */
403 ".loop: \n\t"
404 "cmp r8, #0 \n\t" /* is p_size 0? */
405 "beq .more_data \n\t" /* if so, ask pcmbuf for more data */
406 ".fifo_loop: \n\t"
407 #if CONFIG_CPU == PP5002
408 "ldr r10, [r12, #0x1c]\n\t" /* read IISFIFO_CFG to check FIFO status */
409 "and r10, r10, #0x7800000\n\t"
410 "cmp r10, #0x800000 \n\t"
411 #else
412 "ldr r10, [r12, #0x0c]\n\t" /* read IISFIFO_CFG to check FIFO status */
413 "and r10, r10, #0x3f0000\n\t"
414 "cmp r10, #0x10000 \n\t"
415 #endif
416 "bls .fifo_full \n\t" /* FIFO full, exit */
417 "ldr r10, [r9], #4 \n\t" /* load two samples */
418 "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
419 "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
420 "mov r10, r10, lsl #16\n\t" /* shift lower sample up */
421 "str r10, [r12, #0x40]\n\t" /* then write it */
422 "subs r8, r8, #4 \n\t" /* check if we have more samples */
423 "bne .fifo_loop \n\t" /* yes, continue */
424 ".more_data: \n\t"
425 "stmdb sp!, { r0-r3, r12, lr}\n\t" /* stack scratch regs and lr */
426 "mov r0, r11 \n\t" /* r0 = &p */
427 "add r1, r11, #4 \n\t" /* r1 = &p_size */
428 "str r9, [r0] \n\t" /* save internal copies of variables back */
429 "str r8, [r1] \n\t"
430 "ldr r2, =callback_for_more\n\t"
431 "ldr r2, [r2] \n\t" /* get callback address */
432 "cmp r2, #0 \n\t" /* check for null pointer */
433 "movne lr, pc \n\t" /* call callback_for_more */
434 "bxne r2 \n\t"
435 "ldmia sp!, { r0-r3, r12, lr}\n\t"
436 "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
437 "ldr r9, [r11] \n\t"
438 "cmp r8, #0 \n\t" /* did we actually get more data? */
439 "bne .loop \n\t" /* yes, continue to try feeding FIFO */
440 ".dma_stop: \n\t" /* no more data, do dma_stop() and exit */
441 "ldr r10, =pcm_playing\n\t"
442 "strb r8, [r10] \n\t" /* pcm_playing = false (r8=0, look above) */
443 "ldr r10, [r12] \n\t"
444 #if CONFIG_CPU == PP5002
445 "bic r10, r10, #0x4\n\t" /* disable playback FIFO */
446 "str r10, [r12] \n\t"
447 "ldr r10, [r12, #0x1c] \n\t"
448 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
449 "str r10, [r12, #0x1c] \n\t"
450 #else
451 "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
452 "str r10, [r12] \n\t"
453 #endif
454 "mrs r10, cpsr \n\t"
455 "orr r10, r10, #0x40 \n\t" /* disable FIQ */
456 "msr cpsr_c, r10 \n\t"
457 ".exit: \n\t"
458 "str r8, [r11, #4] \n\t"
459 "str r9, [r11] \n\t"
460 "subs pc, lr, #4 \n\t" /* FIQ specific return sequence */
461 ".fifo_full: \n\t" /* enable IRQ and exit */
462 #if CONFIG_CPU == PP5002
463 "ldr r10, [r12, #0x1c]\n\t"
464 "orr r10, r10, #0x200 \n\t" /* set interrupt */
465 "str r10, [r12, #0x1c]\n\t"
466 #else
467 "ldr r10, [r12] \n\t"
468 "orr r10, r10, #0x2 \n\t" /* set interrupt */
469 "str r10, [r12] \n\t"
470 #endif
471 "b .exit \n\t"
474 #else
475 void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ")));
476 void fiq(void)
478 /* Clear interrupt */
479 #if CONFIG_CPU == PP5020
480 IISCONFIG &= ~0x2;
481 #elif CONFIG_CPU == PP5002
482 inl(0xcf001040);
483 IISFIFO_CFG &= ~(1<<9);
484 #endif
486 do {
487 while (p_size) {
488 if (FIFO_FREE_COUNT < 2) {
489 /* Enable interrupt */
490 #if CONFIG_CPU == PP5020
491 IISCONFIG |= 0x2;
492 #elif CONFIG_CPU == PP5002
493 IISFIFO_CFG |= (1<<9);
494 #endif
495 return;
498 IISFIFO_WR = (*(p++))<<16;
499 IISFIFO_WR = (*(p++))<<16;
500 p_size-=4;
503 /* p is empty, get some more data */
504 if (callback_for_more) {
505 callback_for_more((unsigned char**)&p,&p_size);
507 } while (p_size);
509 /* No more data, so disable the FIFO/FIQ */
510 dma_stop();
512 #endif
514 void pcm_init(void)
516 pcm_playing = false;
517 pcm_paused = false;
519 /* Initialize default register values. */
520 wmcodec_init();
522 /* Power on */
523 wmcodec_enable_output(true);
525 /* Unmute the master channel (DAC should be at zero point now). */
526 wmcodec_mute(false);
528 /* Call dma_stop to initialize everything. */
529 dma_stop();
532 #elif (CONFIG_CPU == PNX0101)
534 #define DMA_BUF_SAMPLES 0x100
536 short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES];
537 short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES];
539 static int pcm_freq = 44100; /* 44.1 is default */
541 unsigned short* p IBSS_ATTR;
542 size_t p_size IBSS_ATTR;
544 static void dma_start(const void *addr, size_t size)
546 p = (unsigned short*)addr;
547 p_size = size;
549 pcm_playing = true;
552 static void dma_stop(void)
554 pcm_playing = false;
557 static inline void fill_dma_buf(int offset)
559 short *l, *r, *lend;
561 l = dma_buf_left + offset;
562 lend = l + DMA_BUF_SAMPLES / 2;
563 r = dma_buf_right + offset;
565 if (pcm_playing && !pcm_paused)
569 int count;
570 unsigned short *tmp_p;
571 count = MIN(p_size / 4, (size_t)(lend - l));
572 tmp_p = p;
573 p_size -= count * 4;
575 if ((int)l & 3)
577 *l++ = *tmp_p++;
578 *r++ = *tmp_p++;
579 count--;
581 while (count >= 4)
583 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
584 "and r4, r0, %3\n\t"
585 "orr r4, r4, r1, lsl #16\n\t"
586 "and r5, r2, %3\n\t"
587 "orr r5, r5, r3, lsl #16\n\t"
588 "stmia %1!, {r4, r5}\n\t"
589 "bic r4, r1, %3\n\t"
590 "orr r4, r4, r0, lsr #16\n\t"
591 "bic r5, r3, %3\n\t"
592 "orr r5, r5, r2, lsr #16\n\t"
593 "stmia %2!, {r4, r5}"
594 : "+r" (tmp_p), "+r" (l), "+r" (r)
595 : "r" (0xffff)
596 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
597 count -= 4;
599 while (count > 0)
601 *l++ = *tmp_p++;
602 *r++ = *tmp_p++;
603 count--;
605 p = tmp_p;
606 if (l >= lend)
607 return;
608 else if (callback_for_more)
609 callback_for_more((unsigned char**)&p,
610 &p_size);
612 while (p_size);
613 pcm_playing = false;
616 if (l < lend)
618 memset(l, 0, sizeof(short) * (lend - l));
619 memset(r, 0, sizeof(short) * (lend - l));
623 static void audio_irq(void)
625 unsigned long st = DMAINTSTAT & ~DMAINTEN;
626 int i;
627 for (i = 0; i < 2; i++)
628 if (st & (1 << i))
630 fill_dma_buf((i == 1) ? 0 : DMA_BUF_SAMPLES / 2);
631 DMAINTSTAT = 1 << i;
635 unsigned long physical_address(void *p)
637 unsigned long adr = (unsigned long)p;
638 return (MMUBLOCK((adr >> 21) & 0xf) << 21) | (adr & ((1 << 21) - 1));
641 void pcm_init(void)
643 int i;
644 callback_for_more = NULL;
645 pcm_playing = false;
646 pcm_paused = false;
648 memset(dma_buf_left, 0, sizeof(dma_buf_left));
649 memset(dma_buf_right, 0, sizeof(dma_buf_right));
651 for (i = 0; i < 8; i++)
653 DMASRC(i) = 0;
654 DMADEST(i) = 0;
655 DMALEN(i) = 0x1ffff;
656 DMAR0C(i) = 0;
657 DMAR10(i) = 0;
658 DMAR1C(i) = 0;
661 DMAINTSTAT = 0xc000ffff;
662 DMAINTEN = 0xc000ffff;
664 DMASRC(0) = physical_address(dma_buf_left);
665 DMADEST(0) = 0x80200280;
666 DMALEN(0) = 0xff;
667 DMAR1C(0) = 0;
668 DMAR0C(0) = 0x40408;
670 DMASRC(1) = physical_address(dma_buf_right);
671 DMADEST(1) = 0x80200284;
672 DMALEN(1) = 0xff;
673 DMAR1C(1) = 0;
674 DMAR0C(1) = 0x40409;
676 irq_set_int_handler(0x1b, audio_irq);
677 irq_enable_int(0x1b);
679 DMAINTSTAT = 1;
680 DMAINTSTAT = 2;
681 DMAINTEN &= ~3;
682 DMAR10(0) |= 1;
683 DMAR10(1) |= 1;
686 void pcm_set_frequency(unsigned int frequency)
688 pcm_freq=frequency;
690 size_t pcm_get_bytes_waiting(void)
692 return p_size;
694 #endif
696 void pcm_play_stop(void)
698 if (pcm_playing) {
699 dma_stop();
703 #endif
705 void pcm_play_data(void (*get_more)(unsigned char** start, size_t* size),
706 unsigned char* start, size_t size)
708 callback_for_more = get_more;
710 if (!(start && size))
712 if (get_more)
713 get_more(&start, &size);
714 else
715 return;
717 if (start && size)
719 dma_start(start, size);
720 if (pcm_paused) {
721 pcm_paused = false;
722 pcm_play_pause(false);
727 void pcm_mute(bool mute)
729 #ifdef HAVE_UDA1380
730 uda1380_mute(mute);
731 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
732 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
733 wmcodec_mute(mute);
734 #elif defined(HAVE_TLV320)
735 tlv320_mute(mute);
736 #endif
737 if (mute)
738 sleep(HZ/16);
741 void pcm_play_pause(bool play)
743 bool needs_change = pcm_paused == play;
745 /* This needs to be done ahead of the rest to prevent infinite
746 * recursion from dma_start */
747 pcm_paused = !play;
748 if (pcm_playing && needs_change) {
749 if(play) {
750 if (pcm_get_bytes_waiting()) {
751 logf("unpause");
753 #ifdef CPU_COLDFIRE
754 /* Enable the FIFO and force one write to it */
755 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq));
756 #ifdef HAVE_SPDIF_OUT
757 EBU1CONFIG = EBU_DEFPARM;
758 #endif
759 DCR0 |= DMA_EEXT | DMA_START;
760 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
761 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
762 /* Enable the FIFO and fill it */
764 enable_fiq();
766 /* Enable playback FIFO */
767 #if CONFIG_CPU == PP5020
768 IISCONFIG |= 0x20000000;
769 #elif CONFIG_CPU == PP5002
770 IISCONFIG |= 0x4;
771 #endif
773 /* Fill the FIFO - we assume there are enough bytes in the
774 pcm buffer to fill the 32-byte FIFO. */
775 while (p_size > 0) {
776 if (FIFO_FREE_COUNT < 2) {
777 /* Enable interrupt */
778 #if CONFIG_CPU == PP5020
779 IISCONFIG |= 0x2;
780 #elif CONFIG_CPU == PP5002
781 IISFIFO_CFG |= (1<<9);
782 #endif
783 return;
786 IISFIFO_WR = (*(p++))<<16;
787 IISFIFO_WR = (*(p++))<<16;
788 p_size-=4;
790 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
791 /* nothing yet */
792 #endif
793 } else {
794 #if (CONFIG_CPU != PNX0101 && CONFIG_CPU != S3C2440)
795 size_t next_size;
796 unsigned char *next_start;
797 void (*get_more)(unsigned char**, size_t*) = callback_for_more;
798 logf("unpause, no data waiting");
799 if (get_more)
800 get_more(&next_start, &next_size);
801 if (next_start && next_size)
802 dma_start(next_start, next_size);
803 else
805 dma_stop();
806 logf("unpause attempted, no data");
808 #endif
810 } else {
811 logf("pause");
813 #ifdef CPU_COLDFIRE
814 /* Disable DMA peripheral request. */
815 DCR0 &= ~DMA_EEXT;
816 SET_IIS_CONFIG(IIS_RESET | IIS_DEFPARM(pcm_freq));
817 #ifdef HAVE_SPDIF_OUT
818 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
819 #endif
820 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
821 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
822 #if CONFIG_CPU == PP5020
823 /* Disable the interrupt */
824 IISCONFIG &= ~0x2;
825 /* Disable playback FIFO */
826 IISCONFIG &= ~0x20000000;
827 #elif CONFIG_CPU == PP5002
828 /* Disable the interrupt */
829 IISFIFO_CFG &= ~(1<<9);
830 /* Disable playback FIFO */
831 IISCONFIG &= ~0x4;
832 #endif
834 disable_fiq();
835 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
836 /* nothing yet */
837 #endif
839 } /* pcm_playing && needs_change */
842 bool pcm_is_playing(void) {
843 return pcm_playing;
846 bool pcm_is_paused(void) {
847 return pcm_paused;
851 #if defined(CPU_COLDFIRE)
852 /* Peaks ahead in the DMA buffer based upon the calling period to
853 attempt to compensate for the delay. Keeps a moving average of
854 length four. */
855 void pcm_calculate_peaks(int *left, int *right)
857 unsigned long samples;
858 unsigned long *addr, *end;
859 long peak_p, peak_n;
861 static unsigned long last_peak_tick = 0;
862 static unsigned long frame_period = 0;
864 /* Throttled peak ahead based on calling period */
865 unsigned long period = current_tick - last_peak_tick;
867 /* Keep reasonable limits on period */
868 if (period < 1)
869 period = 1;
870 else if (period > HZ/5)
871 period = HZ/5;
873 frame_period = (3*frame_period + period) >> 2;
875 last_peak_tick = current_tick;
877 if (!pcm_playing || pcm_paused)
879 peak_left = peak_right = 0;
880 goto peak_done;
883 samples = (BCR0 & 0xffffff) >> 2;
884 addr = (long *)(SAR0 & ~3);
885 samples = MIN(frame_period*44100/HZ, samples);
886 end = addr + samples;
887 peak_p = peak_n = 0;
889 if (left && right)
891 if (samples > 0)
893 long peak_rp = 0, peak_rn = 0;
897 long value = *addr;
898 long ch;
900 ch = value >> 16;
901 if (ch > peak_p) peak_p = ch;
902 else if (ch < peak_n) peak_n = ch;
904 ch = (short)value;
905 if (ch > peak_rp) peak_rp = ch;
906 else if (ch < peak_rn) peak_rn = ch;
908 addr += 4;
910 while (addr < end);
912 peak_left = MAX(peak_p, -peak_n);
913 peak_right = MAX(peak_rp, -peak_rn);
916 else if (left || right)
918 if (samples > 0)
920 if (left)
922 /* Put left channel in low word */
923 addr = (long *)((short *)addr - 1);
924 end = (long *)((short *)end - 1);
929 long value = *(short *)addr;
931 if (value > peak_p) peak_p = value;
932 else if (value < peak_n) peak_n = value;
934 addr += 4;
936 while (addr < end);
938 if (left)
939 peak_left = MAX(peak_p, -peak_n);
940 else
941 peak_right = MAX(peak_p, -peak_n);
945 peak_done:
946 if (left)
947 *left = peak_left;
949 if (right)
950 *right = peak_right;
952 #else
954 * This function goes directly into the DMA buffer to calculate the left and
955 * right peak values. To avoid missing peaks it tries to look forward two full
956 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
957 * the entire period will not be visible. To reduce CPU load it only looks at
958 * every third sample, and this can be reduced even further if needed (even
959 * every tenth sample would still be pretty accurate).
962 /* Check for a peak every PEAK_STRIDE samples */
963 #define PEAK_STRIDE 3
964 /* Up to 1/50th of a second of audio for peak calculation */
965 /* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */
966 #define PEAK_SAMPLES (44100/50)
967 void pcm_calculate_peaks(int *left, int *right)
969 #if (CONFIG_CPU == S3C2440)
970 (void)left;
971 (void)right;
972 #else
973 short *addr;
974 short *end;
976 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
977 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
978 || (CONFIG_CPU == PNX0101)
979 size_t samples = p_size / 4;
980 addr = p;
981 #endif
983 if (samples > PEAK_SAMPLES)
984 samples = PEAK_SAMPLES - (PEAK_STRIDE - 1);
985 else
986 samples -= MIN(PEAK_STRIDE - 1, samples);
988 end = &addr[samples * 2];
991 if (left && right) {
992 int left_peak = 0, right_peak = 0;
994 while (addr < end) {
995 int value;
996 if ((value = addr [0]) > left_peak)
997 left_peak = value;
998 else if (-value > left_peak)
999 left_peak = -value;
1001 if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
1002 right_peak = value;
1003 else if (-value > right_peak)
1004 right_peak = -value;
1006 addr = &addr[PEAK_STRIDE * 2];
1009 *left = left_peak;
1010 *right = right_peak;
1012 else if (left || right) {
1013 int peak_value = 0, value;
1015 if (right)
1016 addr += (PEAK_STRIDE | 1);
1018 while (addr < end) {
1019 if ((value = addr [0]) > peak_value)
1020 peak_value = value;
1021 else if (-value > peak_value)
1022 peak_value = -value;
1024 addr += PEAK_STRIDE * 2;
1027 if (left)
1028 *left = peak_value;
1029 else
1030 *right = peak_value;
1032 #endif
1034 #endif /* CPU_COLDFIRE */