diff options
author | Dave Chapman <dave@dchapman.com> | 2006-02-26 15:59:46 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2006-02-26 15:59:46 +0000 |
commit | 2f76763d73c7be641cd55c30ff15f6ff9dda5fe0 (patch) | |
tree | 29179e6843bf4de0bdedf9ed40e07cfb520bdad8 /firmware/pcm_playback.c | |
parent | 4b9fbd168713e572f9a73a7bacaa850e8c961994 (diff) | |
download | rockbox-2f76763d73c7be641cd55c30ff15f6ff9dda5fe0.tar.gz rockbox-2f76763d73c7be641cd55c30ff15f6ff9dda5fe0.zip |
iPod 3G - initial (completely untested) attempt at audio support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8847 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/pcm_playback.c')
-rw-r--r-- | firmware/pcm_playback.c | 76 |
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 | ||
325 | static bool pcm_playing; | 329 | static bool pcm_playing; |
326 | static bool pcm_paused; | 330 | static bool pcm_paused; |
@@ -329,6 +333,8 @@ static int pcm_freq = 0x6; /* 44.1 is default */ | |||
329 | unsigned short* p IBSS_ATTR; | 333 | unsigned short* p IBSS_ATTR; |
330 | long p_size IBSS_ATTR; | 334 | long p_size IBSS_ATTR; |
331 | 335 | ||
336 | #define PP5002_DMA_OUT_MASK (1 << DMA_OUT_IRQ) | ||
337 | |||
332 | static void dma_start(const void *addr, size_t size) | 338 | static 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 |
504 | void fiq(void) ICODE_ATTR __attribute__((naked)); | 554 | void fiq(void) ICODE_ATTR __attribute__((naked)); |
505 | void fiq(void) | 555 | void fiq(void) |
506 | { | 556 | { |
@@ -579,13 +629,22 @@ void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ"))); | |||
579 | void fiq(void) | 629 | void 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; |