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 ****************************************************************************/
26 #if defined(HAVE_UDA1380)
28 #elif defined(HAVE_WM8975)
30 #elif defined(HAVE_WM8758)
32 #elif defined(HAVE_TLV320)
34 #elif defined(HAVE_WM8731) || defined(HAVE_WM8721)
36 #elif CONFIG_CPU == PNX0101
45 #include "pcm_playback.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.
71 void pcm_set_frequency(unsigned int frequency
)
76 void pcm_play_stop(void)
80 size_t pcm_get_bytes_waiting(void)
88 #define EBU_DEFPARM ((7 << 12) | (3 << 8) | (1 << 5) | (5 << 2))
90 #define IIS_DEFPARM(freq) ((freq << 12) | 0x300 | 4 << 2)
91 #define IIS_RESET 0x800
94 #define SET_IIS_CONFIG(x) IIS1CONFIG = (x);
96 #define SET_IIS_CONFIG(x) IIS2CONFIG = (x);
99 static int pcm_freq
= 0x6; /* 44.1 is default */
101 int peak_left
= 0, peak_right
= 0;
103 /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
104 static void dma_start(const void *addr
, size_t size
)
108 addr
= (void *)((unsigned long)addr
& ~3); /* Align data */
109 size
&= ~3; /* Size must be multiple of 4 */
111 /* Reset the audio FIFO */
112 #ifdef HAVE_SPDIF_OUT
113 EBU1CONFIG
= IIS_RESET
| EBU_DEFPARM
;
116 /* Set up DMA transfer */
117 SAR0
= (unsigned long)addr
; /* Source address */
118 DAR0
= (unsigned long)&PDOR3
; /* Destination address */
119 BCR0
= size
; /* Bytes to transfer */
121 /* Enable the FIFO and force one write to it */
122 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq
));
123 /* Also send the audio to S/PDIF */
124 #ifdef HAVE_SPDIF_OUT
125 EBU1CONFIG
= EBU_DEFPARM
;
127 DCR0
= DMA_INT
| DMA_EEXT
| DMA_CS
| DMA_AA
| DMA_SINC
| (3 << 20) | DMA_START
;
130 /* Stops the DMA transfer and interrupt */
131 static void dma_stop(void)
138 SET_IIS_CONFIG(IIS_RESET
| IIS_DEFPARM(pcm_freq
));
139 #ifdef HAVE_SPDIF_OUT
140 EBU1CONFIG
= IIS_RESET
| EBU_DEFPARM
;
144 /* sets frequency of input to DAC */
145 void pcm_set_frequency(unsigned int frequency
)
152 uda1380_set_nsorder(3);
158 uda1380_set_nsorder(3);
165 uda1380_set_nsorder(5);
171 size_t pcm_get_bytes_waiting(void)
173 return (BCR0
& 0xffffff);
176 /* DMA0 Interrupt is called when the DMA has finished transfering a chunk */
177 void DMA0(void) __attribute__ ((interrupt_handler
, section(".icode")));
182 DSR0
= 1; /* Clear interrupt */
189 logf("DMA Error:0x%04x", res
);
194 unsigned char *next_start
;
196 void (*get_more
)(unsigned char**, size_t*) = callback_for_more
;
198 get_more(&next_start
, &next_size
);
207 SAR0
= (unsigned long)next_start
; /* Source address */
208 BCR0
= next_size
; /* Bytes to transfer */
213 /* Finished playing */
215 logf("DMA No Data:0x%04x", res
);
219 IPR
|= (1<<14); /* Clear pending interrupt request */
227 MPARK
= 0x81; /* PARK[1,0]=10 + BCR24BIT */
228 DIVR0
= 54; /* DMA0 is mapped into vector 54 in system.c */
229 DMAROUTE
= (DMAROUTE
& 0xffffff00) | DMA0_REQ_AUDIO_1
;
230 DMACONFIG
= 1; /* DMA0Req = PDOR3 */
232 /* Reset the audio FIFO */
233 SET_IIS_CONFIG(IIS_RESET
);
235 /* Enable interrupt at level 7, priority 0 */
237 IMR
&= ~(1<<14); /* bit 14 is DMA0 */
239 pcm_set_frequency(44100);
241 /* Prevent pops (resets DAC to zero point) */
242 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq
) | IIS_RESET
);
244 #if defined(HAVE_UDA1380)
245 /* Initialize default register values. */
248 /* Sleep a while so the power can stabilize (especially a long
249 delay is needed for the line out connector). */
252 /* Power on FSDAC and HP amp. */
253 uda1380_enable_output(true);
255 /* Unmute the master channel (DAC should be at zero point now). */
258 #elif defined(HAVE_TLV320)
264 /* Call dma_stop to initialize everything. */
268 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
269 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
271 /* We need to unify this code with the uda1380 code as much as possible, but
272 we will keep it separate during early development.
275 #if CONFIG_CPU == PP5020
276 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16)
277 #elif CONFIG_CPU == PP5002
278 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
279 #elif CONFIG_CPU == PP5024
280 #define FIFO_FREE_COUNT 4 /* TODO: make this sensible */
283 static int pcm_freq
= 44100; /* 44.1 is default */
285 /* NOTE: The order of these two variables is important if you use the iPod
286 assembler optimised fiq handler, so don't change it. */
287 unsigned short* p IBSS_ATTR
;
288 size_t p_size IBSS_ATTR
;
290 static void dma_start(const void *addr
, size_t size
)
292 p
=(unsigned short*)addr
;
297 #if CONFIG_CPU == PP5020
298 /* setup I2S interrupt for FIQ */
299 outl(inl(0x6000402c) | I2S_MASK
, 0x6000402c);
300 outl(I2S_MASK
, 0x60004024);
301 #elif CONFIG_CPU == PP5024
303 /* setup I2S interrupt for FIQ */
304 outl(inl(0xcf00102c) | DMA_OUT_MASK
, 0xcf00102c);
305 outl(DMA_OUT_MASK
, 0xcf001024);
308 /* Clear the FIQ disable bit in cpsr_c */
311 /* Enable playback FIFO */
312 #if CONFIG_CPU == PP5020
313 IISCONFIG
|= 0x20000000;
314 #elif CONFIG_CPU == PP5002
318 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
319 fill the 32-byte FIFO. */
321 if (FIFO_FREE_COUNT
< 2) {
322 /* Enable interrupt */
323 #if CONFIG_CPU == PP5020
325 #elif CONFIG_CPU == PP5002
326 IISFIFO_CFG
|= (1<<9);
331 IISFIFO_WR
= (*(p
++))<<16;
332 IISFIFO_WR
= (*(p
++))<<16;
337 /* Stops the DMA transfer and interrupt */
338 static void dma_stop(void)
342 #if CONFIG_CPU == PP5020
344 /* Disable playback FIFO */
345 IISCONFIG
&= ~0x20000000;
347 /* Disable the interrupt */
350 #elif CONFIG_CPU == PP5002
352 /* Disable playback FIFO */
355 /* Disable the interrupt */
356 IISFIFO_CFG
&= ~(1<<9);
362 void pcm_set_frequency(unsigned int frequency
)
367 size_t pcm_get_bytes_waiting(void)
372 /* ASM optimised FIQ handler. GCC fails to make use of the fact that FIQ mode
373 has registers r8-r14 banked, and so does not need to be saved. This routine
374 uses only these registers, and so will never touch the stack unless it
375 actually needs to do so when calling callback_for_more. C version is still
376 included below for reference.
378 #if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
379 void fiq(void) ICODE_ATTR
__attribute__((naked
));
382 /* r12 contains IISCONFIG address (set in crt0.S to minimise code in actual
383 * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
384 * addresses we need are generated by using offsets with these two.
385 * r12 + 0x40 is IISFIFO_WR, and r12 + 0x0c is IISFIFO_CFG.
386 * r8 and r9 contains local copies of p_size and p respectively.
387 * r10 is a working register.
390 #if CONFIG_CPU == PP5002
391 "ldr r10, =0xcf001040 \n\t" /* Some magic from iPodLinux */
392 "ldr r10, [r10] \n\t"
393 "ldr r10, [r12, #0x1c]\n\t"
394 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
395 "str r10, [r12, #0x1c]\n\t"
397 "ldr r10, [r12] \n\t"
398 "bic r10, r10, #0x2 \n\t" /* clear interrupt */
399 "str r10, [r12] \n\t"
401 "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
402 "ldr r9, [r11] \n\t" /* r9 = p */
404 "cmp r8, #0 \n\t" /* is p_size 0? */
405 "beq .more_data \n\t" /* if so, ask pcmbuf for more data */
407 #if CONFIG_CPU == PP5002
408 "ldr r10, [r12, #0x1c]\n\t" /* read IISFIFO_CFG to check FIFO status */
409 "and r10, r10, #0x7800000\n\t"
410 "cmp r10, #0x800000 \n\t"
412 "ldr r10, [r12, #0x0c]\n\t" /* read IISFIFO_CFG to check FIFO status */
413 "and r10, r10, #0x3f0000\n\t"
414 "cmp r10, #0x10000 \n\t"
416 "bls .fifo_full \n\t" /* FIFO full, exit */
417 "ldr r10, [r9], #4 \n\t" /* load two samples */
418 "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
419 "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
420 "mov r10, r10, lsl #16\n\t" /* shift lower sample up */
421 "str r10, [r12, #0x40]\n\t" /* then write it */
422 "subs r8, r8, #4 \n\t" /* check if we have more samples */
423 "bne .fifo_loop \n\t" /* yes, continue */
425 "stmdb sp!, { r0-r3, r12, lr}\n\t" /* stack scratch regs and lr */
426 "mov r0, r11 \n\t" /* r0 = &p */
427 "add r1, r11, #4 \n\t" /* r1 = &p_size */
428 "str r9, [r0] \n\t" /* save internal copies of variables back */
430 "ldr r2, =callback_for_more\n\t"
431 "ldr r2, [r2] \n\t" /* get callback address */
432 "cmp r2, #0 \n\t" /* check for null pointer */
433 "movne lr, pc \n\t" /* call callback_for_more */
435 "ldmia sp!, { r0-r3, r12, lr}\n\t"
436 "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
438 "cmp r8, #0 \n\t" /* did we actually get more data? */
439 "bne .loop \n\t" /* yes, continue to try feeding FIFO */
440 ".dma_stop: \n\t" /* no more data, do dma_stop() and exit */
441 "ldr r10, =pcm_playing\n\t"
442 "strb r8, [r10] \n\t" /* pcm_playing = false (r8=0, look above) */
443 "ldr r10, [r12] \n\t"
444 #if CONFIG_CPU == PP5002
445 "bic r10, r10, #0x4\n\t" /* disable playback FIFO */
446 "str r10, [r12] \n\t"
447 "ldr r10, [r12, #0x1c] \n\t"
448 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
449 "str r10, [r12, #0x1c] \n\t"
451 "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
452 "str r10, [r12] \n\t"
455 "orr r10, r10, #0x40 \n\t" /* disable FIQ */
456 "msr cpsr_c, r10 \n\t"
458 "str r8, [r11, #4] \n\t"
460 "subs pc, lr, #4 \n\t" /* FIQ specific return sequence */
461 ".fifo_full: \n\t" /* enable IRQ and exit */
462 #if CONFIG_CPU == PP5002
463 "ldr r10, [r12, #0x1c]\n\t"
464 "orr r10, r10, #0x200 \n\t" /* set interrupt */
465 "str r10, [r12, #0x1c]\n\t"
467 "ldr r10, [r12] \n\t"
468 "orr r10, r10, #0x2 \n\t" /* set interrupt */
469 "str r10, [r12] \n\t"
475 void fiq(void) ICODE_ATTR
__attribute__ ((interrupt ("FIQ")));
478 /* Clear interrupt */
479 #if CONFIG_CPU == PP5020
481 #elif CONFIG_CPU == PP5002
483 IISFIFO_CFG
&= ~(1<<9);
488 if (FIFO_FREE_COUNT
< 2) {
489 /* Enable interrupt */
490 #if CONFIG_CPU == PP5020
492 #elif CONFIG_CPU == PP5002
493 IISFIFO_CFG
|= (1<<9);
498 IISFIFO_WR
= (*(p
++))<<16;
499 IISFIFO_WR
= (*(p
++))<<16;
503 /* p is empty, get some more data */
504 if (callback_for_more
) {
505 callback_for_more((unsigned char**)&p
,&p_size
);
509 /* No more data, so disable the FIFO/FIQ */
519 /* Initialize default register values. */
523 wmcodec_enable_output(true);
525 /* Unmute the master channel (DAC should be at zero point now). */
528 /* Call dma_stop to initialize everything. */
532 #elif (CONFIG_CPU == PNX0101)
534 #define DMA_BUF_SAMPLES 0x100
536 short __attribute__((section(".dmabuf"))) dma_buf_left
[DMA_BUF_SAMPLES
];
537 short __attribute__((section(".dmabuf"))) dma_buf_right
[DMA_BUF_SAMPLES
];
539 static int pcm_freq
= 44100; /* 44.1 is default */
541 unsigned short* p IBSS_ATTR
;
542 size_t p_size IBSS_ATTR
;
544 static void dma_start(const void *addr
, size_t size
)
546 p
= (unsigned short*)addr
;
552 static void dma_stop(void)
557 static inline void fill_dma_buf(int offset
)
561 l
= dma_buf_left
+ offset
;
562 lend
= l
+ DMA_BUF_SAMPLES
/ 2;
563 r
= dma_buf_right
+ offset
;
565 if (pcm_playing
&& !pcm_paused
)
570 unsigned short *tmp_p
;
571 count
= MIN(p_size
/ 4, (size_t)(lend
- l
));
583 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
585 "orr r4, r4, r1, lsl #16\n\t"
587 "orr r5, r5, r3, lsl #16\n\t"
588 "stmia %1!, {r4, r5}\n\t"
590 "orr r4, r4, r0, lsr #16\n\t"
592 "orr r5, r5, r2, lsr #16\n\t"
593 "stmia %2!, {r4, r5}"
594 : "+r" (tmp_p
), "+r" (l
), "+r" (r
)
596 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
608 else if (callback_for_more
)
609 callback_for_more((unsigned char**)&p
,
618 memset(l
, 0, sizeof(short) * (lend
- l
));
619 memset(r
, 0, sizeof(short) * (lend
- l
));
623 static void audio_irq(void)
625 unsigned long st
= DMAINTSTAT
& ~DMAINTEN
;
627 for (i
= 0; i
< 2; i
++)
630 fill_dma_buf((i
== 1) ? 0 : DMA_BUF_SAMPLES
/ 2);
635 unsigned long physical_address(void *p
)
637 unsigned long adr
= (unsigned long)p
;
638 return (MMUBLOCK((adr
>> 21) & 0xf) << 21) | (adr
& ((1 << 21) - 1));
644 callback_for_more
= NULL
;
648 memset(dma_buf_left
, 0, sizeof(dma_buf_left
));
649 memset(dma_buf_right
, 0, sizeof(dma_buf_right
));
651 for (i
= 0; i
< 8; i
++)
661 DMAINTSTAT
= 0xc000ffff;
662 DMAINTEN
= 0xc000ffff;
664 DMASRC(0) = physical_address(dma_buf_left
);
665 DMADEST(0) = 0x80200280;
670 DMASRC(1) = physical_address(dma_buf_right
);
671 DMADEST(1) = 0x80200284;
676 irq_set_int_handler(0x1b, audio_irq
);
677 irq_enable_int(0x1b);
686 void pcm_set_frequency(unsigned int frequency
)
690 size_t pcm_get_bytes_waiting(void)
696 void pcm_play_stop(void)
705 void pcm_play_data(void (*get_more
)(unsigned char** start
, size_t* size
),
706 unsigned char* start
, size_t size
)
708 callback_for_more
= get_more
;
710 if (!(start
&& size
))
713 get_more(&start
, &size
);
719 dma_start(start
, size
);
722 pcm_play_pause(false);
727 void pcm_mute(bool mute
)
731 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
732 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
734 #elif defined(HAVE_TLV320)
741 void pcm_play_pause(bool play
)
743 bool needs_change
= pcm_paused
== play
;
745 /* This needs to be done ahead of the rest to prevent infinite
746 * recursion from dma_start */
748 if (pcm_playing
&& needs_change
) {
750 if (pcm_get_bytes_waiting()) {
754 /* Enable the FIFO and force one write to it */
755 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq
));
756 #ifdef HAVE_SPDIF_OUT
757 EBU1CONFIG
= EBU_DEFPARM
;
759 DCR0
|= DMA_EEXT
| DMA_START
;
760 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
761 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
762 /* Enable the FIFO and fill it */
766 /* Enable playback FIFO */
767 #if CONFIG_CPU == PP5020
768 IISCONFIG
|= 0x20000000;
769 #elif CONFIG_CPU == PP5002
773 /* Fill the FIFO - we assume there are enough bytes in the
774 pcm buffer to fill the 32-byte FIFO. */
776 if (FIFO_FREE_COUNT
< 2) {
777 /* Enable interrupt */
778 #if CONFIG_CPU == PP5020
780 #elif CONFIG_CPU == PP5002
781 IISFIFO_CFG
|= (1<<9);
786 IISFIFO_WR
= (*(p
++))<<16;
787 IISFIFO_WR
= (*(p
++))<<16;
790 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
794 #if (CONFIG_CPU != PNX0101 && CONFIG_CPU != S3C2440)
796 unsigned char *next_start
;
797 void (*get_more
)(unsigned char**, size_t*) = callback_for_more
;
798 logf("unpause, no data waiting");
800 get_more(&next_start
, &next_size
);
801 if (next_start
&& next_size
)
802 dma_start(next_start
, next_size
);
806 logf("unpause attempted, no data");
814 /* Disable DMA peripheral request. */
816 SET_IIS_CONFIG(IIS_RESET
| IIS_DEFPARM(pcm_freq
));
817 #ifdef HAVE_SPDIF_OUT
818 EBU1CONFIG
= IIS_RESET
| EBU_DEFPARM
;
820 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
821 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
822 #if CONFIG_CPU == PP5020
823 /* Disable the interrupt */
825 /* Disable playback FIFO */
826 IISCONFIG
&= ~0x20000000;
827 #elif CONFIG_CPU == PP5002
828 /* Disable the interrupt */
829 IISFIFO_CFG
&= ~(1<<9);
830 /* Disable playback FIFO */
835 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
839 } /* pcm_playing && needs_change */
842 bool pcm_is_playing(void) {
846 bool pcm_is_paused(void) {
851 #if defined(CPU_COLDFIRE)
852 /* Peaks ahead in the DMA buffer based upon the calling period to
853 attempt to compensate for the delay. Keeps a moving average of
855 void pcm_calculate_peaks(int *left
, int *right
)
857 unsigned long samples
;
858 unsigned long *addr
, *end
;
861 static unsigned long last_peak_tick
= 0;
862 static unsigned long frame_period
= 0;
864 /* Throttled peak ahead based on calling period */
865 unsigned long period
= current_tick
- last_peak_tick
;
867 /* Keep reasonable limits on period */
870 else if (period
> HZ
/5)
873 frame_period
= (3*frame_period
+ period
) >> 2;
875 last_peak_tick
= current_tick
;
877 if (!pcm_playing
|| pcm_paused
)
879 peak_left
= peak_right
= 0;
883 samples
= (BCR0
& 0xffffff) >> 2;
884 addr
= (long *)(SAR0
& ~3);
885 samples
= MIN(frame_period
*44100/HZ
, samples
);
886 end
= addr
+ samples
;
893 long peak_rp
= 0, peak_rn
= 0;
901 if (ch
> peak_p
) peak_p
= ch
;
902 else if (ch
< peak_n
) peak_n
= ch
;
905 if (ch
> peak_rp
) peak_rp
= ch
;
906 else if (ch
< peak_rn
) peak_rn
= ch
;
912 peak_left
= MAX(peak_p
, -peak_n
);
913 peak_right
= MAX(peak_rp
, -peak_rn
);
916 else if (left
|| right
)
922 /* Put left channel in low word */
923 addr
= (long *)((short *)addr
- 1);
924 end
= (long *)((short *)end
- 1);
929 long value
= *(short *)addr
;
931 if (value
> peak_p
) peak_p
= value
;
932 else if (value
< peak_n
) peak_n
= value
;
939 peak_left
= MAX(peak_p
, -peak_n
);
941 peak_right
= MAX(peak_p
, -peak_n
);
954 * This function goes directly into the DMA buffer to calculate the left and
955 * right peak values. To avoid missing peaks it tries to look forward two full
956 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
957 * the entire period will not be visible. To reduce CPU load it only looks at
958 * every third sample, and this can be reduced even further if needed (even
959 * every tenth sample would still be pretty accurate).
962 /* Check for a peak every PEAK_STRIDE samples */
963 #define PEAK_STRIDE 3
964 /* Up to 1/50th of a second of audio for peak calculation */
965 /* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */
966 #define PEAK_SAMPLES (44100/50)
967 void pcm_calculate_peaks(int *left
, int *right
)
969 #if (CONFIG_CPU == S3C2440)
976 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
977 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
978 || (CONFIG_CPU == PNX0101)
979 size_t samples
= p_size
/ 4;
983 if (samples
> PEAK_SAMPLES
)
984 samples
= PEAK_SAMPLES
- (PEAK_STRIDE
- 1);
986 samples
-= MIN(PEAK_STRIDE
- 1, samples
);
988 end
= &addr
[samples
* 2];
992 int left_peak
= 0, right_peak
= 0;
996 if ((value
= addr
[0]) > left_peak
)
998 else if (-value
> left_peak
)
1001 if ((value
= addr
[PEAK_STRIDE
| 1]) > right_peak
)
1003 else if (-value
> right_peak
)
1004 right_peak
= -value
;
1006 addr
= &addr
[PEAK_STRIDE
* 2];
1010 *right
= right_peak
;
1012 else if (left
|| right
) {
1013 int peak_value
= 0, value
;
1016 addr
+= (PEAK_STRIDE
| 1);
1018 while (addr
< end
) {
1019 if ((value
= addr
[0]) > peak_value
)
1021 else if (-value
> peak_value
)
1022 peak_value
= -value
;
1024 addr
+= PEAK_STRIDE
* 2;
1030 *right
= peak_value
;
1034 #endif /* CPU_COLDFIRE */