summaryrefslogtreecommitdiff
path: root/firmware/pcm_playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/pcm_playback.c')
-rw-r--r--firmware/pcm_playback.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index a9d9ecd9e6..af642e4d43 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -31,7 +31,7 @@
31#include "wm8758.h" 31#include "wm8758.h"
32#elif defined(HAVE_TLV320) 32#elif defined(HAVE_TLV320)
33#include "tlv320.h" 33#include "tlv320.h"
34#elif defined(HAVE_WM8731L) 34#elif defined(HAVE_WM8731)
35#include "wm8731l.h" 35#include "wm8731l.h"
36#endif 36#endif
37#include "system.h" 37#include "system.h"
@@ -314,13 +314,17 @@ void pcm_init(void)
314 dma_stop(); 314 dma_stop();
315} 315}
316 316
317#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) 317#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731)
318 318
319/* We need to unify this code with the uda1380 code as much as possible, but 319/* We need to unify this code with the uda1380 code as much as possible, but
320 we will keep it separate during early development. 320 we will keep it separate during early development.
321*/ 321*/
322 322
323#if CONFIG_CPU == PP5020
323#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16) 324#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16)
325#elif CONFIG_CPU == PP5002
326#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
327#endif
324 328
325static bool pcm_playing; 329static bool pcm_playing;
326static bool pcm_paused; 330static bool pcm_paused;
@@ -329,6 +333,8 @@ static int pcm_freq = 0x6; /* 44.1 is default */
329unsigned short* p IBSS_ATTR; 333unsigned short* p IBSS_ATTR;
330long p_size IBSS_ATTR; 334long p_size IBSS_ATTR;
331 335
336#define PP5002_DMA_OUT_MASK (1 << DMA_OUT_IRQ)
337
332static void dma_start(const void *addr, size_t size) 338static void dma_start(const void *addr, size_t size)
333{ 339{
334 p=(unsigned short*)addr; 340 p=(unsigned short*)addr;
@@ -336,22 +342,36 @@ static void dma_start(const void *addr, size_t size)
336 342
337 pcm_playing = true; 343 pcm_playing = true;
338 344
345#if CONFIG_CPU == PP5020
339 /* setup I2S interrupt for FIQ */ 346 /* setup I2S interrupt for FIQ */
340 outl(inl(0x6000402c) | I2S_MASK, 0x6000402c); 347 outl(inl(0x6000402c) | I2S_MASK, 0x6000402c);
341 outl(I2S_MASK, 0x60004024); 348 outl(I2S_MASK, 0x60004024);
349#else
350 /* setup I2S interrupt for FIQ */
351 outl(inl(0xcf00103c) | PP5002_DMA_OUT_MASK, 0xcf00103c);
352 outl(PP5002_DMA_OUT_MASK, 0xcf001034);
353#endif
342 354
343 /* Clear the FIQ disable bit in cpsr_c */ 355 /* Clear the FIQ disable bit in cpsr_c */
344 enable_fiq(); 356 enable_fiq();
345 357
346 /* Enable playback FIFO */ 358 /* Enable playback FIFO */
359#if CONFIG_CPU == PP5020
347 IISCONFIG |= 0x20000000; 360 IISCONFIG |= 0x20000000;
361#elif CONFIG_CPU == PP5002
362 IISCONFIG |= 0x4;
363#endif
348 364
349 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to 365 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
350 fill the 32-byte FIFO. */ 366 fill the 32-byte FIFO. */
351 while (p_size > 0) { 367 while (p_size > 0) {
352 if (FIFO_FREE_COUNT < 2) { 368 if (FIFO_FREE_COUNT < 2) {
353 /* Enable interrupt */ 369 /* Enable interrupt */
370#if CONFIG_CPU == PP5020
354 IISCONFIG |= 0x2; 371 IISCONFIG |= 0x2;
372#elif CONFIG_CPU == PP5002
373 IISFIFO_CFG &= ~(1<<9);
374#endif
355 return; 375 return;
356 } 376 }
357 377
@@ -366,12 +386,23 @@ static void dma_stop(void)
366{ 386{
367 pcm_playing = false; 387 pcm_playing = false;
368 388
389#if CONFIG_CPU == PP5020
390
369 /* Disable playback FIFO */ 391 /* Disable playback FIFO */
370 IISCONFIG &= ~0x20000000; 392 IISCONFIG &= ~0x20000000;
371 393
372 /* Disable the interrupt */ 394 /* Disable the interrupt */
373 IISCONFIG &= ~0x2; 395 IISCONFIG &= ~0x2;
374 396
397#elif CONFIG_CPU == PP5002
398
399 /* Disable playback FIFO */
400 IISCONFIG &= ~0x4;
401
402 /* Disable the interrupt */
403 IISFIFO_CFG &= ~(1<<9);
404#endif
405
375 disable_fiq(); 406 disable_fiq();
376 407
377 pcm_paused = false; 408 pcm_paused = false;
@@ -438,14 +469,22 @@ void pcm_play_pause(bool play)
438 enable_fiq(); 469 enable_fiq();
439 470
440 /* Enable playback FIFO */ 471 /* Enable playback FIFO */
472#if CONFIG_CPU == PP5020
441 IISCONFIG |= 0x20000000; 473 IISCONFIG |= 0x20000000;
474#elif CONFIG_CPU == PP5002
475 IISCONFIG |= 0x4;
476#endif
442 477
443 /* Fill the FIFO - we assume there are enough bytes in the 478 /* Fill the FIFO - we assume there are enough bytes in the
444 pcm buffer to fill the 32-byte FIFO. */ 479 pcm buffer to fill the 32-byte FIFO. */
445 while (p_size > 0) { 480 while (p_size > 0) {
446 if (FIFO_FREE_COUNT < 2) { 481 if (FIFO_FREE_COUNT < 2) {
447 /* Enable interrupt */ 482 /* Enable interrupt */
483#if CONFIG_CPU == PP5020
448 IISCONFIG |= 0x2; 484 IISCONFIG |= 0x2;
485#elif CONFIG_CPU == PP5002
486 IISFIFO_CFG &= ~(1<<9);
487#endif
449 return; 488 return;
450 } 489 }
451 490
@@ -473,12 +512,23 @@ void pcm_play_pause(bool play)
473 { 512 {
474 logf("pause"); 513 logf("pause");
475 514
515#if CONFIG_CPU == PP5020
516
476 /* Disable the interrupt */ 517 /* Disable the interrupt */
477 IISCONFIG &= ~0x2; 518 IISCONFIG &= ~0x2;
478 519
479 /* Disable playback FIFO */ 520 /* Disable playback FIFO */
480 IISCONFIG &= ~0x20000000; 521 IISCONFIG &= ~0x20000000;
481 522
523#elif CONFIG_CPU == PP5002
524
525 /* Disable the interrupt */
526 IISFIFO_CFG &= ~(1<<9);
527
528 /* Disable playback FIFO */
529 IISCONFIG &= ~0x4;
530#endif
531
482 disable_fiq(); 532 disable_fiq();
483 } 533 }
484 pcm_paused = !play; 534 pcm_paused = !play;
@@ -500,7 +550,7 @@ bool pcm_is_playing(void)
500 actually needs to do so when calling callback_for_more. C version is still 550 actually needs to do so when calling callback_for_more. C version is still
501 included below for reference. 551 included below for reference.
502 */ 552 */
503#if 1 553#if CONFIG_CPU == PP5020
504void fiq(void) ICODE_ATTR __attribute__((naked)); 554void fiq(void) ICODE_ATTR __attribute__((naked));
505void fiq(void) 555void fiq(void)
506{ 556{
@@ -579,13 +629,22 @@ void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ")));
579void fiq(void) 629void fiq(void)
580{ 630{
581 /* Clear interrupt */ 631 /* Clear interrupt */
632#if CONFIG_CPU == PP5020
582 IISCONFIG &= ~0x2; 633 IISCONFIG &= ~0x2;
634#elif CONFIG_CPU == PP5002
635 inl(0xcf001040);
636 IISFIFO_CFG &= ~(1<<9);
637#endif
583 638
584 do { 639 do {
585 while (p_size) { 640 while (p_size) {
586 if (FIFO_FREE_COUNT < 2) { 641 if (FIFO_FREE_COUNT < 2) {
587 /* Enable interrupt */ 642 /* Enable interrupt */
643#if CONFIG_CPU == PP5020
588 IISCONFIG |= 0x2; 644 IISCONFIG |= 0x2;
645#elif CONFIG_CPU == PP5002
646 IISFIFO_CFG &= ~(1<<9);
647#endif
589 return; 648 return;
590 } 649 }
591 650
@@ -625,9 +684,9 @@ void pcm_init(void)
625 dma_stop(); 684 dma_stop();
626} 685}
627 686
628#elif (CONFIG_CPU == PNX0101) || (CONFIG_CPU == PP5002) 687#elif (CONFIG_CPU == PNX0101)
629 688
630/* TODO: Implement for iFP7xx and iPod 3G 689/* TODO: Implement for iFP7xx
631 For now, just implement some dummy functions. 690 For now, just implement some dummy functions.
632*/ 691*/
633 692
@@ -686,7 +745,7 @@ size_t pcm_get_bytes_waiting(void)
686 745
687#endif 746#endif
688 747
689#if (CONFIG_CPU != PNX0101) && (CONFIG_CPU != PP5002) 748#if (CONFIG_CPU != PNX0101)
690/* 749/*
691 * This function goes directly into the DMA buffer to calculate the left and 750 * This function goes directly into the DMA buffer to calculate the left and
692 * right peak values. To avoid missing peaks it tries to look forward two full 751 * right peak values. To avoid missing peaks it tries to look forward two full
@@ -704,12 +763,9 @@ void pcm_calculate_peaks(int *left, int *right)
704#ifdef HAVE_UDA1380 763#ifdef HAVE_UDA1380
705 long samples = (BCR0 & 0xffffff) / 4; 764 long samples = (BCR0 & 0xffffff) / 4;
706 short *addr = (short *) (SAR0 & ~3); 765 short *addr = (short *) (SAR0 & ~3);
707#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) 766#elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731)
708 long samples = p_size / 4; 767 long samples = p_size / 4;
709 short *addr = p; 768 short *addr = p;
710#elif defined(HAVE_WM8731L)
711 long samples = next_size / 4;
712 short *addr = (short *)next_start;
713#elif defined(HAVE_TLV320) 769#elif defined(HAVE_TLV320)
714 long samples = 4; /* TODO X5 */ 770 long samples = 4; /* TODO X5 */
715 short *addr = NULL; 771 short *addr = NULL;