1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #if defined(HAVE_WM8975)
25 #elif defined(HAVE_WM8758)
27 #elif defined(HAVE_WM8731) || defined(HAVE_WM8721)
29 #elif CONFIG_CPU == PNX0101
35 * APIs implemented in the target-specific portion:
38 * pcm_get_bytes_waiting
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 **/
64 #if (CONFIG_CPU == S3C2440)
66 /* TODO: Implement for Gigabeat
67 For now, just implement some dummy functions.
73 void pcm_play_dma_start(const void *addr
, size_t 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
)
96 size_t pcm_get_bytes_waiting(void)
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 */
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
;
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
137 /* setup I2S interrupt for FIQ */
138 outl(inl(0xcf00102c) | DMA_OUT_MASK
, 0xcf00102c);
139 outl(DMA_OUT_MASK
, 0xcf001024);
142 /* Clear the FIQ disable bit in cpsr_c */
145 /* Enable playback FIFO */
146 #if CONFIG_CPU == PP5020
147 IISCONFIG
|= 0x20000000;
148 #elif CONFIG_CPU == PP5002
152 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
153 fill the 32-byte FIFO. */
155 if (FIFO_FREE_COUNT
< 2) {
156 /* Enable interrupt */
157 #if CONFIG_CPU == PP5020
159 #elif CONFIG_CPU == PP5002
160 IISFIFO_CFG
|= (1<<9);
165 IISFIFO_WR
= (*(p
++))<<16;
166 IISFIFO_WR
= (*(p
++))<<16;
171 /* Stops the DMA transfer and interrupt */
172 void pcm_play_dma_stop(void)
176 #if CONFIG_CPU == PP5020
178 /* Disable playback FIFO */
179 IISCONFIG
&= ~0x20000000;
181 /* Disable the interrupt */
184 #elif CONFIG_CPU == PP5002
186 /* Disable playback FIFO */
189 /* Disable the interrupt */
190 IISFIFO_CFG
&= ~(1<<9);
196 void pcm_play_pause_pause(void)
198 #if CONFIG_CPU == PP5020
199 /* Disable the interrupt */
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 */
212 void pcm_play_pause_unpause(void)
214 /* Enable the FIFO and fill it */
218 /* Enable playback FIFO */
219 #if CONFIG_CPU == PP5020
220 IISCONFIG
|= 0x20000000;
221 #elif CONFIG_CPU == PP5002
225 /* Fill the FIFO - we assume there are enough bytes in the
226 pcm buffer to fill the 32-byte FIFO. */
228 if (FIFO_FREE_COUNT
< 2) {
229 /* Enable interrupt */
230 #if CONFIG_CPU == PP5020
232 #elif CONFIG_CPU == PP5002
233 IISFIFO_CFG
|= (1<<9);
238 IISFIFO_WR
= (*(p
++))<<16;
239 IISFIFO_WR
= (*(p
++))<<16;
244 void pcm_set_frequency(unsigned int frequency
)
247 pcm_freq
= HW_SAMPR_DEFAULT
;
250 size_t pcm_get_bytes_waiting(void)
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
));
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.
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"
280 "ldr r10, [r12] \n\t"
281 "bic r10, r10, #0x2 \n\t" /* clear interrupt */
282 "str r10, [r12] \n\t"
284 "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
285 "ldr r9, [r11] \n\t" /* r9 = p */
287 "cmp r8, #0 \n\t" /* is p_size 0? */
288 "beq .more_data \n\t" /* if so, ask pcmbuf for more data */
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"
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"
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 */
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 */
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 */
318 "ldmia sp!, { r0-r3, r12, lr}\n\t"
319 "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
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"
334 "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
335 "str r10, [r12] \n\t"
338 "orr r10, r10, #0x40 \n\t" /* disable FIQ */
339 "msr cpsr_c, r10 \n\t"
341 "str r8, [r11, #4] \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"
350 "ldr r10, [r12] \n\t"
351 "orr r10, r10, #0x2 \n\t" /* set interrupt */
352 "str r10, [r12] \n\t"
357 #else /* !(CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002) */
358 void fiq(void) ICODE_ATTR
__attribute__ ((interrupt ("FIQ")));
361 /* Clear interrupt */
362 #if CONFIG_CPU == PP5020
364 #elif CONFIG_CPU == PP5002
366 IISFIFO_CFG
&= ~(1<<9);
371 if (FIFO_FREE_COUNT
< 2) {
372 /* Enable interrupt */
373 #if CONFIG_CPU == PP5020
375 #elif CONFIG_CPU == PP5002
376 IISFIFO_CFG
|= (1<<9);
381 IISFIFO_WR
= (*(p
++))<<16;
382 IISFIFO_WR
= (*(p
++))<<16;
386 /* p is empty, get some more data */
387 if (pcm_callback_for_more
) {
388 pcm_callback_for_more((unsigned char**)&p
,&p_size
);
392 /* No more data, so disable the FIFO/FIQ */
395 #endif /* CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 */
397 #ifdef HAVE_PP5024_CODEC
406 pcm_callback_for_more
= NULL
;
408 /* Initialize default register values. */
412 wmcodec_enable_output(true);
414 /* Unmute the master channel (DAC should be at zero point now). */
417 /* Call pcm_play_dma_stop to initialize everything. */
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
;
441 void pcm_play_dma_stop(void)
446 void pcm_play_pause_pause(void)
450 void pcm_play_pause_unpause(void)
454 static inline void fill_dma_buf(int offset
)
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
)
467 unsigned short *tmp_p
;
468 count
= MIN(p_size
/ 4, (size_t)(lend
- l
));
480 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
482 "orr r4, r4, r1, lsl #16\n\t"
484 "orr r5, r5, r3, lsl #16\n\t"
485 "stmia %1!, {r4, r5}\n\t"
487 "orr r4, r4, r0, lsr #16\n\t"
489 "orr r5, r5, r2, lsr #16\n\t"
490 "stmia %2!, {r4, r5}"
491 : "+r" (tmp_p
), "+r" (l
), "+r" (r
)
493 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
505 else if (pcm_callback_for_more
)
506 pcm_callback_for_more((unsigned char**)&p
,
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
;
524 for (i
= 0; i
< 2; i
++)
527 fill_dma_buf((i
== 1) ? 0 : DMA_BUF_SAMPLES
/ 2);
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));
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
++)
559 DMAINTSTAT
= 0xc000ffff;
560 DMAINTEN
= 0xc000ffff;
562 DMASRC(0) = physical_address(dma_buf_left
);
563 DMADEST(0) = 0x80200280;
568 DMASRC(1) = physical_address(dma_buf_right
);
569 DMADEST(1) = 0x80200284;
574 irq_set_int_handler(0x1b, audio_irq
);
575 irq_enable_int(0x1b);
584 void pcm_set_frequency(unsigned int frequency
)
587 pcm_freq
= HW_SAMPR_DEFAULT
;
589 size_t pcm_get_bytes_waiting(void)
593 #endif /* CONFIG_CPU == */
595 /* dummy functions for those not actually supporting all this yet */
596 void pcm_apply_settings(bool reset
)
602 void pcm_mute(bool mute
)
604 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
605 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
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)
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;
642 if (samples
> PEAK_SAMPLES
)
643 samples
= PEAK_SAMPLES
- (PEAK_STRIDE
- 1);
645 samples
-= MIN(PEAK_STRIDE
- 1, samples
);
647 end
= &addr
[samples
* 2];
651 int left_peak
= 0, right_peak
= 0;
655 if ((value
= addr
[0]) > left_peak
)
657 else if (-value
> left_peak
)
660 if ((value
= addr
[PEAK_STRIDE
| 1]) > right_peak
)
662 else if (-value
> right_peak
)
665 addr
= &addr
[PEAK_STRIDE
* 2];
671 else if (left
|| right
) {
672 int peak_value
= 0, value
;
675 addr
+= (PEAK_STRIDE
| 1);
678 if ((value
= addr
[0]) > peak_value
)
680 else if (-value
> peak_value
)
683 addr
+= PEAK_STRIDE
* 2;
694 #endif /* CPU_COLDFIRE */
696 /****************************************************************************
697 * Functions that do not require targeted implementation but only a targeted
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
))
710 get_more(&start
, &size
);
715 pcm_play_dma_start(start
, size
);
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
)
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 */
742 if (pcm_playing
&& needs_change
)
746 if (pcm_get_bytes_waiting())
749 pcm_play_pause_unpause();
753 logf("unpause, no data waiting");
754 if (!pcm_play_data_start(pcm_callback_for_more
, NULL
, 0))
757 logf("unpause attempted, no data");
764 pcm_play_pause_pause();
766 } /* pcm_playing && needs_change */
769 void pcm_play_stop(void)
775 bool pcm_is_playing(void)
780 bool pcm_is_paused(void)