Fix remote screen check in graphic equalizer, so that it can be used on logf-enabled...
[Rockbox.git] / firmware / pcm_playback.c
blobcd14f123d16d87258aa085c98bf2e904e9c8adfd
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 static void dma_start(const void *addr, size_t size)
73 (void)addr;
74 (void)size;
77 void pcm_set_frequency(unsigned int frequency)
79 (void)frequency;
82 void pcm_play_stop(void)
86 size_t pcm_get_bytes_waiting(void)
88 return 0;
90 #else
91 #ifdef CPU_COLDFIRE
93 #ifdef HAVE_SPDIF_OUT
94 #define EBU_DEFPARM ((7 << 12) | (3 << 8) | (1 << 5) | (5 << 2))
95 #endif
96 #define IIS_DEFPARM(freq) ((freq << 12) | 0x300 | 4 << 2)
97 #define IIS_RESET 0x800
99 #ifdef IAUDIO_X5
100 #define SET_IIS_CONFIG(x) IIS1CONFIG = (x);
101 #else
102 #define SET_IIS_CONFIG(x) IIS2CONFIG = (x);
103 #endif
105 static int pcm_freq = 0x6; /* 44.1 is default */
107 int peak_left = 0, peak_right = 0;
109 /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
110 static void dma_start(const void *addr, size_t size)
112 pcm_playing = true;
114 addr = (void *)((unsigned long)addr & ~3); /* Align data */
115 size &= ~3; /* Size must be multiple of 4 */
117 /* Reset the audio FIFO */
118 #ifdef HAVE_SPDIF_OUT
119 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
120 #endif
122 /* Set up DMA transfer */
123 SAR0 = (unsigned long)addr; /* Source address */
124 DAR0 = (unsigned long)&PDOR3; /* Destination address */
125 BCR0 = size; /* Bytes to transfer */
127 /* Enable the FIFO and force one write to it */
128 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq));
129 /* Also send the audio to S/PDIF */
130 #ifdef HAVE_SPDIF_OUT
131 EBU1CONFIG = EBU_DEFPARM;
132 #endif
133 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_SINC | (3 << 20) | DMA_START;
136 /* Stops the DMA transfer and interrupt */
137 static void dma_stop(void)
139 pcm_playing = false;
141 DCR0 = 0;
142 DSR0 = 1;
143 /* Reset the FIFO */
144 SET_IIS_CONFIG(IIS_RESET | IIS_DEFPARM(pcm_freq));
145 #ifdef HAVE_SPDIF_OUT
146 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
147 #endif
150 /* sets frequency of input to DAC */
151 void pcm_set_frequency(unsigned int frequency)
153 switch(frequency)
155 case 11025:
156 pcm_freq = 0x2;
157 #ifdef HAVE_UDA1380
158 uda1380_set_nsorder(3);
159 #endif
160 break;
161 case 22050:
162 pcm_freq = 0x4;
163 #ifdef HAVE_UDA1380
164 uda1380_set_nsorder(3);
165 #endif
166 break;
167 case 44100:
168 default:
169 pcm_freq = 0x6;
170 #ifdef HAVE_UDA1380
171 uda1380_set_nsorder(5);
172 #endif
173 break;
177 size_t pcm_get_bytes_waiting(void)
179 return (BCR0 & 0xffffff);
182 /* DMA0 Interrupt is called when the DMA has finished transfering a chunk */
183 void DMA0(void) __attribute__ ((interrupt_handler, section(".icode")));
184 void DMA0(void)
186 int res = DSR0;
188 DSR0 = 1; /* Clear interrupt */
189 DCR0 &= ~DMA_EEXT;
191 /* Stop on error */
192 if(res & 0x70)
194 dma_stop();
195 logf("DMA Error:0x%04x", res);
197 else
199 size_t next_size;
200 unsigned char *next_start;
202 void (*get_more)(unsigned char**, size_t*) = callback_for_more;
203 if (get_more)
204 get_more(&next_start, &next_size);
205 else
207 next_size = 0;
208 next_start = NULL;
211 if(next_size)
213 SAR0 = (unsigned long)next_start; /* Source address */
214 BCR0 = next_size; /* Bytes to transfer */
215 DCR0 |= DMA_EEXT;
217 else
219 /* Finished playing */
220 dma_stop();
221 logf("DMA No Data:0x%04x", res);
225 IPR |= (1<<14); /* Clear pending interrupt request */
228 void pcm_init(void)
230 pcm_playing = false;
231 pcm_paused = false;
233 MPARK = 0x81; /* PARK[1,0]=10 + BCR24BIT */
234 DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
235 DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1;
236 DMACONFIG = 1; /* DMA0Req = PDOR3 */
238 /* Reset the audio FIFO */
239 SET_IIS_CONFIG(IIS_RESET);
241 /* Enable interrupt at level 7, priority 0 */
242 ICR6 = 0x1c;
243 IMR &= ~(1<<14); /* bit 14 is DMA0 */
245 pcm_set_frequency(44100);
247 /* Prevent pops (resets DAC to zero point) */
248 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq) | IIS_RESET);
250 #if defined(HAVE_UDA1380)
251 /* Initialize default register values. */
252 uda1380_init();
254 /* Sleep a while so the power can stabilize (especially a long
255 delay is needed for the line out connector). */
256 sleep(HZ);
258 /* Power on FSDAC and HP amp. */
259 uda1380_enable_output(true);
261 /* Unmute the master channel (DAC should be at zero point now). */
262 uda1380_mute(false);
264 #elif defined(HAVE_TLV320)
265 tlv320_init();
266 sleep(HZ/4);
267 tlv320_mute(false);
268 #endif
270 /* Call dma_stop to initialize everything. */
271 dma_stop();
274 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
275 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
277 /* We need to unify this code with the uda1380 code as much as possible, but
278 we will keep it separate during early development.
281 #if CONFIG_CPU == PP5020
282 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16)
283 #elif CONFIG_CPU == PP5002
284 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
285 #elif CONFIG_CPU == PP5024
286 #define FIFO_FREE_COUNT 4 /* TODO: make this sensible */
287 #endif
289 static int pcm_freq = 44100; /* 44.1 is default */
291 /* NOTE: The order of these two variables is important if you use the iPod
292 assembler optimised fiq handler, so don't change it. */
293 unsigned short* p IBSS_ATTR;
294 size_t p_size IBSS_ATTR;
296 static void dma_start(const void *addr, size_t size)
298 p=(unsigned short*)addr;
299 p_size=size;
301 pcm_playing = true;
303 #if CONFIG_CPU == PP5020
304 /* setup I2S interrupt for FIQ */
305 outl(inl(0x6000402c) | I2S_MASK, 0x6000402c);
306 outl(I2S_MASK, 0x60004024);
307 #elif CONFIG_CPU == PP5024
308 #else
309 /* setup I2S interrupt for FIQ */
310 outl(inl(0xcf00102c) | DMA_OUT_MASK, 0xcf00102c);
311 outl(DMA_OUT_MASK, 0xcf001024);
312 #endif
314 /* Clear the FIQ disable bit in cpsr_c */
315 enable_fiq();
317 /* Enable playback FIFO */
318 #if CONFIG_CPU == PP5020
319 IISCONFIG |= 0x20000000;
320 #elif CONFIG_CPU == PP5002
321 IISCONFIG |= 0x4;
322 #endif
324 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
325 fill the 32-byte FIFO. */
326 while (p_size > 0) {
327 if (FIFO_FREE_COUNT < 2) {
328 /* Enable interrupt */
329 #if CONFIG_CPU == PP5020
330 IISCONFIG |= 0x2;
331 #elif CONFIG_CPU == PP5002
332 IISFIFO_CFG |= (1<<9);
333 #endif
334 return;
337 IISFIFO_WR = (*(p++))<<16;
338 IISFIFO_WR = (*(p++))<<16;
339 p_size-=4;
343 /* Stops the DMA transfer and interrupt */
344 static void dma_stop(void)
346 pcm_playing = false;
348 #if CONFIG_CPU == PP5020
350 /* Disable playback FIFO */
351 IISCONFIG &= ~0x20000000;
353 /* Disable the interrupt */
354 IISCONFIG &= ~0x2;
356 #elif CONFIG_CPU == PP5002
358 /* Disable playback FIFO */
359 IISCONFIG &= ~0x4;
361 /* Disable the interrupt */
362 IISFIFO_CFG &= ~(1<<9);
363 #endif
365 disable_fiq();
368 void pcm_set_frequency(unsigned int frequency)
370 pcm_freq=frequency;
373 size_t pcm_get_bytes_waiting(void)
375 return p_size;
378 /* ASM optimised FIQ handler. GCC fails to make use of the fact that FIQ mode
379 has registers r8-r14 banked, and so does not need to be saved. This routine
380 uses only these registers, and so will never touch the stack unless it
381 actually needs to do so when calling callback_for_more. C version is still
382 included below for reference.
384 #if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
385 void fiq(void) ICODE_ATTR __attribute__((naked));
386 void fiq(void)
388 /* r12 contains IISCONFIG address (set in crt0.S to minimise code in actual
389 * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
390 * addresses we need are generated by using offsets with these two.
391 * r12 + 0x40 is IISFIFO_WR, and r12 + 0x0c is IISFIFO_CFG.
392 * r8 and r9 contains local copies of p_size and p respectively.
393 * r10 is a working register.
395 asm volatile (
396 #if CONFIG_CPU == PP5002
397 "ldr r10, =0xcf001040 \n\t" /* Some magic from iPodLinux */
398 "ldr r10, [r10] \n\t"
399 "ldr r10, [r12, #0x1c]\n\t"
400 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
401 "str r10, [r12, #0x1c]\n\t"
402 #else
403 "ldr r10, [r12] \n\t"
404 "bic r10, r10, #0x2 \n\t" /* clear interrupt */
405 "str r10, [r12] \n\t"
406 #endif
407 "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
408 "ldr r9, [r11] \n\t" /* r9 = p */
409 ".loop: \n\t"
410 "cmp r8, #0 \n\t" /* is p_size 0? */
411 "beq .more_data \n\t" /* if so, ask pcmbuf for more data */
412 ".fifo_loop: \n\t"
413 #if CONFIG_CPU == PP5002
414 "ldr r10, [r12, #0x1c]\n\t" /* read IISFIFO_CFG to check FIFO status */
415 "and r10, r10, #0x7800000\n\t"
416 "cmp r10, #0x800000 \n\t"
417 #else
418 "ldr r10, [r12, #0x0c]\n\t" /* read IISFIFO_CFG to check FIFO status */
419 "and r10, r10, #0x3f0000\n\t"
420 "cmp r10, #0x10000 \n\t"
421 #endif
422 "bls .fifo_full \n\t" /* FIFO full, exit */
423 "ldr r10, [r9], #4 \n\t" /* load two samples */
424 "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
425 "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
426 "mov r10, r10, lsl #16\n\t" /* shift lower sample up */
427 "str r10, [r12, #0x40]\n\t" /* then write it */
428 "subs r8, r8, #4 \n\t" /* check if we have more samples */
429 "bne .fifo_loop \n\t" /* yes, continue */
430 ".more_data: \n\t"
431 "stmdb sp!, { r0-r3, r12, lr}\n\t" /* stack scratch regs and lr */
432 "mov r0, r11 \n\t" /* r0 = &p */
433 "add r1, r11, #4 \n\t" /* r1 = &p_size */
434 "str r9, [r0] \n\t" /* save internal copies of variables back */
435 "str r8, [r1] \n\t"
436 "ldr r2, =callback_for_more\n\t"
437 "ldr r2, [r2] \n\t" /* get callback address */
438 "cmp r2, #0 \n\t" /* check for null pointer */
439 "movne lr, pc \n\t" /* call callback_for_more */
440 "bxne r2 \n\t"
441 "ldmia sp!, { r0-r3, r12, lr}\n\t"
442 "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
443 "ldr r9, [r11] \n\t"
444 "cmp r8, #0 \n\t" /* did we actually get more data? */
445 "bne .loop \n\t" /* yes, continue to try feeding FIFO */
446 ".dma_stop: \n\t" /* no more data, do dma_stop() and exit */
447 "ldr r10, =pcm_playing\n\t"
448 "strb r8, [r10] \n\t" /* pcm_playing = false (r8=0, look above) */
449 "ldr r10, [r12] \n\t"
450 #if CONFIG_CPU == PP5002
451 "bic r10, r10, #0x4\n\t" /* disable playback FIFO */
452 "str r10, [r12] \n\t"
453 "ldr r10, [r12, #0x1c] \n\t"
454 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
455 "str r10, [r12, #0x1c] \n\t"
456 #else
457 "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
458 "str r10, [r12] \n\t"
459 #endif
460 "mrs r10, cpsr \n\t"
461 "orr r10, r10, #0x40 \n\t" /* disable FIQ */
462 "msr cpsr_c, r10 \n\t"
463 ".exit: \n\t"
464 "str r8, [r11, #4] \n\t"
465 "str r9, [r11] \n\t"
466 "subs pc, lr, #4 \n\t" /* FIQ specific return sequence */
467 ".fifo_full: \n\t" /* enable IRQ and exit */
468 #if CONFIG_CPU == PP5002
469 "ldr r10, [r12, #0x1c]\n\t"
470 "orr r10, r10, #0x200 \n\t" /* set interrupt */
471 "str r10, [r12, #0x1c]\n\t"
472 #else
473 "ldr r10, [r12] \n\t"
474 "orr r10, r10, #0x2 \n\t" /* set interrupt */
475 "str r10, [r12] \n\t"
476 #endif
477 "b .exit \n\t"
480 #else
481 void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ")));
482 void fiq(void)
484 /* Clear interrupt */
485 #if CONFIG_CPU == PP5020
486 IISCONFIG &= ~0x2;
487 #elif CONFIG_CPU == PP5002
488 inl(0xcf001040);
489 IISFIFO_CFG &= ~(1<<9);
490 #endif
492 do {
493 while (p_size) {
494 if (FIFO_FREE_COUNT < 2) {
495 /* Enable interrupt */
496 #if CONFIG_CPU == PP5020
497 IISCONFIG |= 0x2;
498 #elif CONFIG_CPU == PP5002
499 IISFIFO_CFG |= (1<<9);
500 #endif
501 return;
504 IISFIFO_WR = (*(p++))<<16;
505 IISFIFO_WR = (*(p++))<<16;
506 p_size-=4;
509 /* p is empty, get some more data */
510 if (callback_for_more) {
511 callback_for_more((unsigned char**)&p,&p_size);
513 } while (p_size);
515 /* No more data, so disable the FIFO/FIQ */
516 dma_stop();
518 #endif
520 void pcm_init(void)
522 pcm_playing = false;
523 pcm_paused = false;
525 /* Initialize default register values. */
526 wmcodec_init();
528 /* Power on */
529 wmcodec_enable_output(true);
531 /* Unmute the master channel (DAC should be at zero point now). */
532 wmcodec_mute(false);
534 /* Call dma_stop to initialize everything. */
535 dma_stop();
538 #elif (CONFIG_CPU == PNX0101)
540 #define DMA_BUF_SAMPLES 0x100
542 short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES];
543 short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES];
545 static int pcm_freq = 44100; /* 44.1 is default */
547 unsigned short* p IBSS_ATTR;
548 size_t p_size IBSS_ATTR;
550 static void dma_start(const void *addr, size_t size)
552 p = (unsigned short*)addr;
553 p_size = size;
555 pcm_playing = true;
558 static void dma_stop(void)
560 pcm_playing = false;
563 static inline void fill_dma_buf(int offset)
565 short *l, *r, *lend;
567 l = dma_buf_left + offset;
568 lend = l + DMA_BUF_SAMPLES / 2;
569 r = dma_buf_right + offset;
571 if (pcm_playing && !pcm_paused)
575 int count;
576 unsigned short *tmp_p;
577 count = MIN(p_size / 4, (size_t)(lend - l));
578 tmp_p = p;
579 p_size -= count * 4;
581 if ((int)l & 3)
583 *l++ = *tmp_p++;
584 *r++ = *tmp_p++;
585 count--;
587 while (count >= 4)
589 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
590 "and r4, r0, %3\n\t"
591 "orr r4, r4, r1, lsl #16\n\t"
592 "and r5, r2, %3\n\t"
593 "orr r5, r5, r3, lsl #16\n\t"
594 "stmia %1!, {r4, r5}\n\t"
595 "bic r4, r1, %3\n\t"
596 "orr r4, r4, r0, lsr #16\n\t"
597 "bic r5, r3, %3\n\t"
598 "orr r5, r5, r2, lsr #16\n\t"
599 "stmia %2!, {r4, r5}"
600 : "+r" (tmp_p), "+r" (l), "+r" (r)
601 : "r" (0xffff)
602 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
603 count -= 4;
605 while (count > 0)
607 *l++ = *tmp_p++;
608 *r++ = *tmp_p++;
609 count--;
611 p = tmp_p;
612 if (l >= lend)
613 return;
614 else if (callback_for_more)
615 callback_for_more((unsigned char**)&p,
616 &p_size);
618 while (p_size);
619 pcm_playing = false;
622 if (l < lend)
624 memset(l, 0, sizeof(short) * (lend - l));
625 memset(r, 0, sizeof(short) * (lend - l));
629 static void audio_irq(void)
631 unsigned long st = DMAINTSTAT & ~DMAINTEN;
632 int i;
633 for (i = 0; i < 2; i++)
634 if (st & (1 << i))
636 fill_dma_buf((i == 1) ? 0 : DMA_BUF_SAMPLES / 2);
637 DMAINTSTAT = 1 << i;
641 unsigned long physical_address(void *p)
643 unsigned long adr = (unsigned long)p;
644 return (MMUBLOCK((adr >> 21) & 0xf) << 21) | (adr & ((1 << 21) - 1));
647 void pcm_init(void)
649 int i;
650 callback_for_more = NULL;
651 pcm_playing = false;
652 pcm_paused = false;
654 memset(dma_buf_left, 0, sizeof(dma_buf_left));
655 memset(dma_buf_right, 0, sizeof(dma_buf_right));
657 for (i = 0; i < 8; i++)
659 DMASRC(i) = 0;
660 DMADEST(i) = 0;
661 DMALEN(i) = 0x1ffff;
662 DMAR0C(i) = 0;
663 DMAR10(i) = 0;
664 DMAR1C(i) = 0;
667 DMAINTSTAT = 0xc000ffff;
668 DMAINTEN = 0xc000ffff;
670 DMASRC(0) = physical_address(dma_buf_left);
671 DMADEST(0) = 0x80200280;
672 DMALEN(0) = 0xff;
673 DMAR1C(0) = 0;
674 DMAR0C(0) = 0x40408;
676 DMASRC(1) = physical_address(dma_buf_right);
677 DMADEST(1) = 0x80200284;
678 DMALEN(1) = 0xff;
679 DMAR1C(1) = 0;
680 DMAR0C(1) = 0x40409;
682 irq_set_int_handler(0x1b, audio_irq);
683 irq_enable_int(0x1b);
685 DMAINTSTAT = 1;
686 DMAINTSTAT = 2;
687 DMAINTEN &= ~3;
688 DMAR10(0) |= 1;
689 DMAR10(1) |= 1;
692 void pcm_set_frequency(unsigned int frequency)
694 pcm_freq=frequency;
696 size_t pcm_get_bytes_waiting(void)
698 return p_size;
700 #endif
702 void pcm_play_stop(void)
704 if (pcm_playing) {
705 dma_stop();
709 #endif
711 void pcm_play_data(void (*get_more)(unsigned char** start, size_t* size),
712 unsigned char* start, size_t size)
714 callback_for_more = get_more;
716 if (!(start && size))
718 if (get_more)
719 get_more(&start, &size);
720 else
721 return;
723 if (start && size)
725 dma_start(start, size);
726 if (pcm_paused) {
727 pcm_paused = false;
728 pcm_play_pause(false);
733 void pcm_mute(bool mute)
735 #ifdef HAVE_UDA1380
736 uda1380_mute(mute);
737 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
738 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
739 wmcodec_mute(mute);
740 #elif defined(HAVE_TLV320)
741 tlv320_mute(mute);
742 #endif
743 if (mute)
744 sleep(HZ/16);
747 void pcm_play_pause(bool play)
749 bool needs_change = pcm_paused == play;
751 /* This needs to be done ahead of the rest to prevent infinite
752 * recursion from dma_start */
753 pcm_paused = !play;
754 if (pcm_playing && needs_change) {
755 if(play) {
756 if (pcm_get_bytes_waiting()) {
757 logf("unpause");
759 #ifdef CPU_COLDFIRE
760 /* Enable the FIFO and force one write to it */
761 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq));
762 #ifdef HAVE_SPDIF_OUT
763 EBU1CONFIG = EBU_DEFPARM;
764 #endif
765 DCR0 |= DMA_EEXT | DMA_START;
766 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
767 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
768 /* Enable the FIFO and fill it */
770 enable_fiq();
772 /* Enable playback FIFO */
773 #if CONFIG_CPU == PP5020
774 IISCONFIG |= 0x20000000;
775 #elif CONFIG_CPU == PP5002
776 IISCONFIG |= 0x4;
777 #endif
779 /* Fill the FIFO - we assume there are enough bytes in the
780 pcm buffer to fill the 32-byte FIFO. */
781 while (p_size > 0) {
782 if (FIFO_FREE_COUNT < 2) {
783 /* Enable interrupt */
784 #if CONFIG_CPU == PP5020
785 IISCONFIG |= 0x2;
786 #elif CONFIG_CPU == PP5002
787 IISFIFO_CFG |= (1<<9);
788 #endif
789 return;
792 IISFIFO_WR = (*(p++))<<16;
793 IISFIFO_WR = (*(p++))<<16;
794 p_size-=4;
796 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
797 /* nothing yet */
798 #endif
799 } else {
800 #if (CONFIG_CPU != PNX0101 && CONFIG_CPU != S3C2440)
801 size_t next_size;
802 unsigned char *next_start;
803 void (*get_more)(unsigned char**, size_t*) = callback_for_more;
804 logf("unpause, no data waiting");
805 if (get_more)
806 get_more(&next_start, &next_size);
807 if (next_start && next_size)
808 dma_start(next_start, next_size);
809 else
811 dma_stop();
812 logf("unpause attempted, no data");
814 #endif
816 } else {
817 logf("pause");
819 #ifdef CPU_COLDFIRE
820 /* Disable DMA peripheral request. */
821 DCR0 &= ~DMA_EEXT;
822 SET_IIS_CONFIG(IIS_RESET | IIS_DEFPARM(pcm_freq));
823 #ifdef HAVE_SPDIF_OUT
824 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
825 #endif
826 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
827 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
828 #if CONFIG_CPU == PP5020
829 /* Disable the interrupt */
830 IISCONFIG &= ~0x2;
831 /* Disable playback FIFO */
832 IISCONFIG &= ~0x20000000;
833 #elif CONFIG_CPU == PP5002
834 /* Disable the interrupt */
835 IISFIFO_CFG &= ~(1<<9);
836 /* Disable playback FIFO */
837 IISCONFIG &= ~0x4;
838 #endif
840 disable_fiq();
841 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
842 /* nothing yet */
843 #endif
845 } /* pcm_playing && needs_change */
848 bool pcm_is_playing(void) {
849 return pcm_playing;
852 bool pcm_is_paused(void) {
853 return pcm_paused;
857 #if defined(CPU_COLDFIRE)
858 /* Peaks ahead in the DMA buffer based upon the calling period to
859 attempt to compensate for the delay. Keeps a moving average of
860 length four. */
861 void pcm_calculate_peaks(int *left, int *right)
863 unsigned long samples;
864 unsigned long *addr, *end;
865 long peak_p, peak_n;
867 static unsigned long last_peak_tick = 0;
868 static unsigned long frame_period = 0;
870 /* Throttled peak ahead based on calling period */
871 unsigned long period = current_tick - last_peak_tick;
873 /* Keep reasonable limits on period */
874 if (period < 1)
875 period = 1;
876 else if (period > HZ/5)
877 period = HZ/5;
879 frame_period = (3*frame_period + period) >> 2;
881 last_peak_tick = current_tick;
883 if (!pcm_playing || pcm_paused)
885 peak_left = peak_right = 0;
886 goto peak_done;
889 samples = (BCR0 & 0xffffff) >> 2;
890 addr = (long *)(SAR0 & ~3);
891 samples = MIN(frame_period*44100/HZ, samples);
892 end = addr + samples;
893 peak_p = peak_n = 0;
895 if (left && right)
897 if (samples > 0)
899 long peak_rp = 0, peak_rn = 0;
903 long value = *addr;
904 long ch;
906 ch = value >> 16;
907 if (ch > peak_p) peak_p = ch;
908 else if (ch < peak_n) peak_n = ch;
910 ch = (short)value;
911 if (ch > peak_rp) peak_rp = ch;
912 else if (ch < peak_rn) peak_rn = ch;
914 addr += 4;
916 while (addr < end);
918 peak_left = MAX(peak_p, -peak_n);
919 peak_right = MAX(peak_rp, -peak_rn);
922 else if (left || right)
924 if (samples > 0)
926 if (left)
928 /* Put left channel in low word */
929 addr = (long *)((short *)addr - 1);
930 end = (long *)((short *)end - 1);
935 long value = *(short *)addr;
937 if (value > peak_p) peak_p = value;
938 else if (value < peak_n) peak_n = value;
940 addr += 4;
942 while (addr < end);
944 if (left)
945 peak_left = MAX(peak_p, -peak_n);
946 else
947 peak_right = MAX(peak_p, -peak_n);
951 peak_done:
952 if (left)
953 *left = peak_left;
955 if (right)
956 *right = peak_right;
958 #else
960 * This function goes directly into the DMA buffer to calculate the left and
961 * right peak values. To avoid missing peaks it tries to look forward two full
962 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
963 * the entire period will not be visible. To reduce CPU load it only looks at
964 * every third sample, and this can be reduced even further if needed (even
965 * every tenth sample would still be pretty accurate).
968 /* Check for a peak every PEAK_STRIDE samples */
969 #define PEAK_STRIDE 3
970 /* Up to 1/50th of a second of audio for peak calculation */
971 /* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */
972 #define PEAK_SAMPLES (44100/50)
973 void pcm_calculate_peaks(int *left, int *right)
975 #if (CONFIG_CPU == S3C2440)
976 (void)left;
977 (void)right;
978 #else
979 short *addr;
980 short *end;
982 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
983 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
984 || (CONFIG_CPU == PNX0101)
985 size_t samples = p_size / 4;
986 addr = p;
987 #endif
989 if (samples > PEAK_SAMPLES)
990 samples = PEAK_SAMPLES - (PEAK_STRIDE - 1);
991 else
992 samples -= MIN(PEAK_STRIDE - 1, samples);
994 end = &addr[samples * 2];
997 if (left && right) {
998 int left_peak = 0, right_peak = 0;
1000 while (addr < end) {
1001 int value;
1002 if ((value = addr [0]) > left_peak)
1003 left_peak = value;
1004 else if (-value > left_peak)
1005 left_peak = -value;
1007 if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
1008 right_peak = value;
1009 else if (-value > right_peak)
1010 right_peak = -value;
1012 addr = &addr[PEAK_STRIDE * 2];
1015 *left = left_peak;
1016 *right = right_peak;
1018 else if (left || right) {
1019 int peak_value = 0, value;
1021 if (right)
1022 addr += (PEAK_STRIDE | 1);
1024 while (addr < end) {
1025 if ((value = addr [0]) > peak_value)
1026 peak_value = value;
1027 else if (-value > peak_value)
1028 peak_value = -value;
1030 addr += PEAK_STRIDE * 2;
1033 if (left)
1034 *left = peak_value;
1035 else
1036 *right = peak_value;
1038 #endif
1040 #endif /* CPU_COLDFIRE */