A few minor fixes (typos, accuracy in the Ondio manual).
[kugel-rb.git] / firmware / pcm_playback.c
blob99a495ca105605834f5b83e01c98a38ed653fea6
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 "system.h"
20 #include "kernel.h"
21 #include "logf.h"
22 #include "audio.h"
23 #if defined(HAVE_WM8975)
24 #include "wm8975.h"
25 #elif defined(HAVE_WM8758)
26 #include "wm8758.h"
27 #elif defined(HAVE_WM8731) || defined(HAVE_WM8721)
28 #include "wm8731l.h"
29 #elif CONFIG_CPU == PNX0101
30 #include "string.h"
31 #include "pnx0101.h"
32 #endif
34 /**
35 * APIs implemented in the target-specific portion:
36 * Public -
37 * pcm_init
38 * pcm_get_bytes_waiting
39 * pcm_calculate_peaks
40 * Semi-private -
41 * pcm_play_dma_start
42 * pcm_play_dma_stop
43 * pcm_play_pause_pause
44 * pcm_play_pause_unpause
47 /** These items may be implemented target specifically or need to
48 be shared semi-privately **/
50 /* the registered callback function to ask for more mp3 data */
51 volatile pcm_more_callback_type pcm_callback_for_more = NULL;
52 volatile bool pcm_playing = false;
53 volatile bool pcm_paused = false;
55 void pcm_play_dma_start(const void *addr, size_t size);
56 void pcm_play_dma_stop(void);
57 void pcm_play_pause_pause(void);
58 void pcm_play_pause_unpause(void);
60 /** Functions that require targeted implementation **/
62 #ifndef CPU_COLDFIRE
64 #if (CONFIG_CPU == S3C2440)
66 /* TODO: Implement for Gigabeat
67 For now, just implement some dummy functions.
69 void pcm_init(void)
73 void pcm_play_dma_start(const void *addr, size_t size)
75 (void)addr;
76 (void)size;
79 void pcm_play_dma_stop(void)
83 void pcm_play_pause_pause(void)
87 void pcm_play_pause_unpause(void)
91 void pcm_set_frequency(unsigned int frequency)
93 (void)frequency;
96 size_t pcm_get_bytes_waiting(void)
98 return 0;
101 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
102 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
103 || defined(HAVE_PP5024_CODEC)
105 /* We need to unify this code with the uda1380 code as much as possible, but
106 we will keep it separate during early development.
109 #if CONFIG_CPU == PP5020
110 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16)
111 #elif CONFIG_CPU == PP5002
112 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
113 #elif CONFIG_CPU == PP5024
114 #define FIFO_FREE_COUNT 4 /* TODO: make this sensible */
115 #endif
117 static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */
119 /* NOTE: The order of these two variables is important if you use the iPod
120 assembler optimised fiq handler, so don't change it. */
121 unsigned short* p IBSS_ATTR;
122 size_t p_size IBSS_ATTR;
124 void pcm_play_dma_start(const void *addr, size_t size)
126 p=(unsigned short*)addr;
127 p_size=size;
129 pcm_playing = true;
131 #if CONFIG_CPU == PP5020
132 /* setup I2S interrupt for FIQ */
133 outl(inl(0x6000402c) | I2S_MASK, 0x6000402c);
134 outl(I2S_MASK, 0x60004024);
135 #elif CONFIG_CPU == PP5024
136 #else
137 /* setup I2S interrupt for FIQ */
138 outl(inl(0xcf00102c) | DMA_OUT_MASK, 0xcf00102c);
139 outl(DMA_OUT_MASK, 0xcf001024);
140 #endif
142 /* Clear the FIQ disable bit in cpsr_c */
143 enable_fiq();
145 /* Enable playback FIFO */
146 #if CONFIG_CPU == PP5020
147 IISCONFIG |= 0x20000000;
148 #elif CONFIG_CPU == PP5002
149 IISCONFIG |= 0x4;
150 #endif
152 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
153 fill the 32-byte FIFO. */
154 while (p_size > 0) {
155 if (FIFO_FREE_COUNT < 2) {
156 /* Enable interrupt */
157 #if CONFIG_CPU == PP5020
158 IISCONFIG |= 0x2;
159 #elif CONFIG_CPU == PP5002
160 IISFIFO_CFG |= (1<<9);
161 #endif
162 return;
165 IISFIFO_WR = (*(p++))<<16;
166 IISFIFO_WR = (*(p++))<<16;
167 p_size-=4;
171 /* Stops the DMA transfer and interrupt */
172 void pcm_play_dma_stop(void)
174 pcm_playing = false;
176 #if CONFIG_CPU == PP5020
178 /* Disable playback FIFO */
179 IISCONFIG &= ~0x20000000;
181 /* Disable the interrupt */
182 IISCONFIG &= ~0x2;
184 #elif CONFIG_CPU == PP5002
186 /* Disable playback FIFO */
187 IISCONFIG &= ~0x4;
189 /* Disable the interrupt */
190 IISFIFO_CFG &= ~(1<<9);
191 #endif
193 disable_fiq();
196 void pcm_play_pause_pause(void)
198 #if CONFIG_CPU == PP5020
199 /* Disable the interrupt */
200 IISCONFIG &= ~0x2;
201 /* Disable playback FIFO */
202 IISCONFIG &= ~0x20000000;
203 #elif CONFIG_CPU == PP5002
204 /* Disable the interrupt */
205 IISFIFO_CFG &= ~(1<<9);
206 /* Disable playback FIFO */
207 IISCONFIG &= ~0x4;
208 #endif
209 disable_fiq();
212 void pcm_play_pause_unpause(void)
214 /* Enable the FIFO and fill it */
216 enable_fiq();
218 /* Enable playback FIFO */
219 #if CONFIG_CPU == PP5020
220 IISCONFIG |= 0x20000000;
221 #elif CONFIG_CPU == PP5002
222 IISCONFIG |= 0x4;
223 #endif
225 /* Fill the FIFO - we assume there are enough bytes in the
226 pcm buffer to fill the 32-byte FIFO. */
227 while (p_size > 0) {
228 if (FIFO_FREE_COUNT < 2) {
229 /* Enable interrupt */
230 #if CONFIG_CPU == PP5020
231 IISCONFIG |= 0x2;
232 #elif CONFIG_CPU == PP5002
233 IISFIFO_CFG |= (1<<9);
234 #endif
235 return;
238 IISFIFO_WR = (*(p++))<<16;
239 IISFIFO_WR = (*(p++))<<16;
240 p_size-=4;
244 void pcm_set_frequency(unsigned int frequency)
246 (void)frequency;
247 pcm_freq = HW_SAMPR_DEFAULT;
250 size_t pcm_get_bytes_waiting(void)
252 return p_size;
255 /* ASM optimised FIQ handler. GCC fails to make use of the fact that FIQ mode
256 has registers r8-r14 banked, and so does not need to be saved. This routine
257 uses only these registers, and so will never touch the stack unless it
258 actually needs to do so when calling pcm_callback_for_more. C version is
259 still included below for reference.
261 #if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
262 void fiq(void) ICODE_ATTR __attribute__((naked));
263 void fiq(void)
265 /* r12 contains IISCONFIG address (set in crt0.S to minimise code in actual
266 * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
267 * addresses we need are generated by using offsets with these two.
268 * r12 + 0x40 is IISFIFO_WR, and r12 + 0x0c is IISFIFO_CFG.
269 * r8 and r9 contains local copies of p_size and p respectively.
270 * r10 is a working register.
272 asm volatile (
273 #if CONFIG_CPU == PP5002
274 "ldr r10, =0xcf001040 \n\t" /* Some magic from iPodLinux */
275 "ldr r10, [r10] \n\t"
276 "ldr r10, [r12, #0x1c]\n\t"
277 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
278 "str r10, [r12, #0x1c]\n\t"
279 #else
280 "ldr r10, [r12] \n\t"
281 "bic r10, r10, #0x2 \n\t" /* clear interrupt */
282 "str r10, [r12] \n\t"
283 #endif
284 "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
285 "ldr r9, [r11] \n\t" /* r9 = p */
286 ".loop: \n\t"
287 "cmp r8, #0 \n\t" /* is p_size 0? */
288 "beq .more_data \n\t" /* if so, ask pcmbuf for more data */
289 ".fifo_loop: \n\t"
290 #if CONFIG_CPU == PP5002
291 "ldr r10, [r12, #0x1c]\n\t" /* read IISFIFO_CFG to check FIFO status */
292 "and r10, r10, #0x7800000\n\t"
293 "cmp r10, #0x800000 \n\t"
294 #else
295 "ldr r10, [r12, #0x0c]\n\t" /* read IISFIFO_CFG to check FIFO status */
296 "and r10, r10, #0x3f0000\n\t"
297 "cmp r10, #0x10000 \n\t"
298 #endif
299 "bls .fifo_full \n\t" /* FIFO full, exit */
300 "ldr r10, [r9], #4 \n\t" /* load two samples */
301 "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
302 "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
303 "mov r10, r10, lsl #16\n\t" /* shift lower sample up */
304 "str r10, [r12, #0x40]\n\t" /* then write it */
305 "subs r8, r8, #4 \n\t" /* check if we have more samples */
306 "bne .fifo_loop \n\t" /* yes, continue */
307 ".more_data: \n\t"
308 "stmdb sp!, { r0-r3, r12, lr}\n\t" /* stack scratch regs and lr */
309 "mov r0, r11 \n\t" /* r0 = &p */
310 "add r1, r11, #4 \n\t" /* r1 = &p_size */
311 "str r9, [r0] \n\t" /* save internal copies of variables back */
312 "str r8, [r1] \n\t"
313 "ldr r2, =pcm_callback_for_more\n\t"
314 "ldr r2, [r2] \n\t" /* get callback address */
315 "cmp r2, #0 \n\t" /* check for null pointer */
316 "movne lr, pc \n\t" /* call pcm_callback_for_more */
317 "bxne r2 \n\t"
318 "ldmia sp!, { r0-r3, r12, lr}\n\t"
319 "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
320 "ldr r9, [r11] \n\t"
321 "cmp r8, #0 \n\t" /* did we actually get more data? */
322 "bne .loop \n\t" /* yes, continue to try feeding FIFO */
323 ".dma_stop: \n\t" /* no more data, do dma_stop() and exit */
324 "ldr r10, =pcm_playing\n\t"
325 "strb r8, [r10] \n\t" /* pcm_playing = false (r8=0, look above) */
326 "ldr r10, [r12] \n\t"
327 #if CONFIG_CPU == PP5002
328 "bic r10, r10, #0x4\n\t" /* disable playback FIFO */
329 "str r10, [r12] \n\t"
330 "ldr r10, [r12, #0x1c] \n\t"
331 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
332 "str r10, [r12, #0x1c] \n\t"
333 #else
334 "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
335 "str r10, [r12] \n\t"
336 #endif
337 "mrs r10, cpsr \n\t"
338 "orr r10, r10, #0x40 \n\t" /* disable FIQ */
339 "msr cpsr_c, r10 \n\t"
340 ".exit: \n\t"
341 "str r8, [r11, #4] \n\t"
342 "str r9, [r11] \n\t"
343 "subs pc, lr, #4 \n\t" /* FIQ specific return sequence */
344 ".fifo_full: \n\t" /* enable IRQ and exit */
345 #if CONFIG_CPU == PP5002
346 "ldr r10, [r12, #0x1c]\n\t"
347 "orr r10, r10, #0x200 \n\t" /* set interrupt */
348 "str r10, [r12, #0x1c]\n\t"
349 #else
350 "ldr r10, [r12] \n\t"
351 "orr r10, r10, #0x2 \n\t" /* set interrupt */
352 "str r10, [r12] \n\t"
353 #endif
354 "b .exit \n\t"
357 #else /* !(CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002) */
358 void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ")));
359 void fiq(void)
361 /* Clear interrupt */
362 #if CONFIG_CPU == PP5020
363 IISCONFIG &= ~0x2;
364 #elif CONFIG_CPU == PP5002
365 inl(0xcf001040);
366 IISFIFO_CFG &= ~(1<<9);
367 #endif
369 do {
370 while (p_size) {
371 if (FIFO_FREE_COUNT < 2) {
372 /* Enable interrupt */
373 #if CONFIG_CPU == PP5020
374 IISCONFIG |= 0x2;
375 #elif CONFIG_CPU == PP5002
376 IISFIFO_CFG |= (1<<9);
377 #endif
378 return;
381 IISFIFO_WR = (*(p++))<<16;
382 IISFIFO_WR = (*(p++))<<16;
383 p_size-=4;
386 /* p is empty, get some more data */
387 if (pcm_callback_for_more) {
388 pcm_callback_for_more((unsigned char**)&p,&p_size);
390 } while (p_size);
392 /* No more data, so disable the FIFO/FIQ */
393 pcm_play_dma_stop();
395 #endif /* CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 */
397 #ifdef HAVE_PP5024_CODEC
398 void pcm_init(void)
401 #else
402 void pcm_init(void)
404 pcm_playing = false;
405 pcm_paused = false;
406 pcm_callback_for_more = NULL;
408 /* Initialize default register values. */
409 wmcodec_init();
411 /* Power on */
412 wmcodec_enable_output(true);
414 /* Unmute the master channel (DAC should be at zero point now). */
415 wmcodec_mute(false);
417 /* Call pcm_play_dma_stop to initialize everything. */
418 pcm_play_dma_stop();
420 #endif /* HAVE_PP5024_CODEC */
421 #elif (CONFIG_CPU == PNX0101)
423 #define DMA_BUF_SAMPLES 0x100
425 short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES];
426 short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES];
428 static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */
430 unsigned short* p IBSS_ATTR;
431 size_t p_size IBSS_ATTR;
433 void pcm_play_dma_start(const void *addr, size_t size)
435 p = (unsigned short*)addr;
436 p_size = size;
438 pcm_playing = true;
441 void pcm_play_dma_stop(void)
443 pcm_playing = false;
446 void pcm_play_pause_pause(void)
450 void pcm_play_pause_unpause(void)
454 static inline void fill_dma_buf(int offset)
456 short *l, *r, *lend;
458 l = dma_buf_left + offset;
459 lend = l + DMA_BUF_SAMPLES / 2;
460 r = dma_buf_right + offset;
462 if (pcm_playing && !pcm_paused)
466 int count;
467 unsigned short *tmp_p;
468 count = MIN(p_size / 4, (size_t)(lend - l));
469 tmp_p = p;
470 p_size -= count * 4;
472 if ((int)l & 3)
474 *l++ = *tmp_p++;
475 *r++ = *tmp_p++;
476 count--;
478 while (count >= 4)
480 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
481 "and r4, r0, %3\n\t"
482 "orr r4, r4, r1, lsl #16\n\t"
483 "and r5, r2, %3\n\t"
484 "orr r5, r5, r3, lsl #16\n\t"
485 "stmia %1!, {r4, r5}\n\t"
486 "bic r4, r1, %3\n\t"
487 "orr r4, r4, r0, lsr #16\n\t"
488 "bic r5, r3, %3\n\t"
489 "orr r5, r5, r2, lsr #16\n\t"
490 "stmia %2!, {r4, r5}"
491 : "+r" (tmp_p), "+r" (l), "+r" (r)
492 : "r" (0xffff)
493 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
494 count -= 4;
496 while (count > 0)
498 *l++ = *tmp_p++;
499 *r++ = *tmp_p++;
500 count--;
502 p = tmp_p;
503 if (l >= lend)
504 return;
505 else if (pcm_callback_for_more)
506 pcm_callback_for_more((unsigned char**)&p,
507 &p_size);
509 while (p_size);
510 pcm_playing = false;
513 if (l < lend)
515 memset(l, 0, sizeof(short) * (lend - l));
516 memset(r, 0, sizeof(short) * (lend - l));
520 static void audio_irq(void)
522 unsigned long st = DMAINTSTAT & ~DMAINTEN;
523 int i;
524 for (i = 0; i < 2; i++)
525 if (st & (1 << i))
527 fill_dma_buf((i == 1) ? 0 : DMA_BUF_SAMPLES / 2);
528 DMAINTSTAT = 1 << i;
532 unsigned long physical_address(void *p)
534 unsigned long adr = (unsigned long)p;
535 return (MMUBLOCK((adr >> 21) & 0xf) << 21) | (adr & ((1 << 21) - 1));
538 void pcm_init(void)
540 int i;
542 pcm_playing = false;
543 pcm_paused = false;
544 pcm_callback_for_more = NULL;
546 memset(dma_buf_left, 0, sizeof(dma_buf_left));
547 memset(dma_buf_right, 0, sizeof(dma_buf_right));
549 for (i = 0; i < 8; i++)
551 DMASRC(i) = 0;
552 DMADEST(i) = 0;
553 DMALEN(i) = 0x1ffff;
554 DMAR0C(i) = 0;
555 DMAR10(i) = 0;
556 DMAR1C(i) = 0;
559 DMAINTSTAT = 0xc000ffff;
560 DMAINTEN = 0xc000ffff;
562 DMASRC(0) = physical_address(dma_buf_left);
563 DMADEST(0) = 0x80200280;
564 DMALEN(0) = 0xff;
565 DMAR1C(0) = 0;
566 DMAR0C(0) = 0x40408;
568 DMASRC(1) = physical_address(dma_buf_right);
569 DMADEST(1) = 0x80200284;
570 DMALEN(1) = 0xff;
571 DMAR1C(1) = 0;
572 DMAR0C(1) = 0x40409;
574 irq_set_int_handler(0x1b, audio_irq);
575 irq_enable_int(0x1b);
577 DMAINTSTAT = 1;
578 DMAINTSTAT = 2;
579 DMAINTEN &= ~3;
580 DMAR10(0) |= 1;
581 DMAR10(1) |= 1;
584 void pcm_set_frequency(unsigned int frequency)
586 (void)frequency;
587 pcm_freq = HW_SAMPR_DEFAULT;
589 size_t pcm_get_bytes_waiting(void)
591 return p_size;
593 #endif /* CONFIG_CPU == */
595 /* dummy functions for those not actually supporting all this yet */
596 void pcm_apply_settings(bool reset)
598 (void)reset;
600 /** **/
602 void pcm_mute(bool mute)
604 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
605 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
606 wmcodec_mute(mute);
607 #endif
608 if (mute)
609 sleep(HZ/16);
613 * This function goes directly into the DMA buffer to calculate the left and
614 * right peak values. To avoid missing peaks it tries to look forward two full
615 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
616 * the entire period will not be visible. To reduce CPU load it only looks at
617 * every third sample, and this can be reduced even further if needed (even
618 * every tenth sample would still be pretty accurate).
621 /* Check for a peak every PEAK_STRIDE samples */
622 #define PEAK_STRIDE 3
623 /* Up to 1/50th of a second of audio for peak calculation */
624 /* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */
625 #define PEAK_SAMPLES (44100/50)
626 void pcm_calculate_peaks(int *left, int *right)
628 #if (CONFIG_CPU == S3C2440)
629 (void)left;
630 (void)right;
631 #else
632 short *addr;
633 short *end;
635 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
636 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
637 || (CONFIG_CPU == PNX0101) || defined(HAVE_PP5024_CODEC)
638 size_t samples = p_size / 4;
639 addr = p;
640 #endif
642 if (samples > PEAK_SAMPLES)
643 samples = PEAK_SAMPLES - (PEAK_STRIDE - 1);
644 else
645 samples -= MIN(PEAK_STRIDE - 1, samples);
647 end = &addr[samples * 2];
650 if (left && right) {
651 int left_peak = 0, right_peak = 0;
653 while (addr < end) {
654 int value;
655 if ((value = addr [0]) > left_peak)
656 left_peak = value;
657 else if (-value > left_peak)
658 left_peak = -value;
660 if ((value = addr [PEAK_STRIDE | 1]) > right_peak)
661 right_peak = value;
662 else if (-value > right_peak)
663 right_peak = -value;
665 addr = &addr[PEAK_STRIDE * 2];
668 *left = left_peak;
669 *right = right_peak;
671 else if (left || right) {
672 int peak_value = 0, value;
674 if (right)
675 addr += (PEAK_STRIDE | 1);
677 while (addr < end) {
678 if ((value = addr [0]) > peak_value)
679 peak_value = value;
680 else if (-value > peak_value)
681 peak_value = -value;
683 addr += PEAK_STRIDE * 2;
686 if (left)
687 *left = peak_value;
688 else
689 *right = peak_value;
691 #endif
694 #endif /* CPU_COLDFIRE */
696 /****************************************************************************
697 * Functions that do not require targeted implementation but only a targeted
698 * interface
701 /* Common code to pcm_play_data and pcm_play_pause
702 Returns true if DMA playback was started, else false. */
703 bool pcm_play_data_start(pcm_more_callback_type get_more,
704 unsigned char *start, size_t size)
706 if (!(start && size))
708 size = 0;
709 if (get_more)
710 get_more(&start, &size);
713 if (start && size)
715 pcm_play_dma_start(start, size);
716 return true;
719 return false;
722 void pcm_play_data(pcm_more_callback_type get_more,
723 unsigned char *start, size_t size)
725 pcm_callback_for_more = get_more;
727 if (pcm_play_data_start(get_more, start, size) && pcm_paused)
729 pcm_paused = false;
730 pcm_play_pause(false);
734 void pcm_play_pause(bool play)
736 bool needs_change = pcm_paused == play;
738 /* This needs to be done ahead of the rest to prevent infinite
739 recursion from pcm_play_data */
740 pcm_paused = !play;
742 if (pcm_playing && needs_change)
744 if (play)
746 if (pcm_get_bytes_waiting())
748 logf("unpause");
749 pcm_play_pause_unpause();
751 else
753 logf("unpause, no data waiting");
754 if (!pcm_play_data_start(pcm_callback_for_more, NULL, 0))
756 pcm_play_dma_stop();
757 logf("unpause attempted, no data");
761 else
763 logf("pause");
764 pcm_play_pause_pause();
766 } /* pcm_playing && needs_change */
769 void pcm_play_stop(void)
771 if (pcm_playing)
772 pcm_play_dma_stop();
775 bool pcm_is_playing(void)
777 return pcm_playing;
780 bool pcm_is_paused(void)
782 return pcm_paused;