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 static void dma_start(const void *addr
, size_t size
)
77 void pcm_set_frequency(unsigned int frequency
)
82 void pcm_play_stop(void)
86 size_t pcm_get_bytes_waiting(void)
94 #define EBU_DEFPARM ((7 << 12) | (3 << 8) | (1 << 5) | (5 << 2))
96 #define IIS_DEFPARM(freq) ((freq << 12) | 0x300 | 4 << 2)
97 #define IIS_RESET 0x800
100 #define SET_IIS_CONFIG(x) IIS1CONFIG = (x);
102 #define SET_IIS_CONFIG(x) IIS2CONFIG = (x);
105 static int pcm_freq
= 0x6; /* 44.1 is default */
107 int peak_left
= 0, peak_right
= 0;
109 /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
110 static void dma_start(const void *addr
, size_t size
)
114 addr
= (void *)((unsigned long)addr
& ~3); /* Align data */
115 size
&= ~3; /* Size must be multiple of 4 */
117 /* Reset the audio FIFO */
118 #ifdef HAVE_SPDIF_OUT
119 EBU1CONFIG
= IIS_RESET
| EBU_DEFPARM
;
122 /* Set up DMA transfer */
123 SAR0
= (unsigned long)addr
; /* Source address */
124 DAR0
= (unsigned long)&PDOR3
; /* Destination address */
125 BCR0
= size
; /* Bytes to transfer */
127 /* Enable the FIFO and force one write to it */
128 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq
));
129 /* Also send the audio to S/PDIF */
130 #ifdef HAVE_SPDIF_OUT
131 EBU1CONFIG
= EBU_DEFPARM
;
133 DCR0
= DMA_INT
| DMA_EEXT
| DMA_CS
| DMA_AA
| DMA_SINC
| (3 << 20) | DMA_START
;
136 /* Stops the DMA transfer and interrupt */
137 static void dma_stop(void)
144 SET_IIS_CONFIG(IIS_RESET
| IIS_DEFPARM(pcm_freq
));
145 #ifdef HAVE_SPDIF_OUT
146 EBU1CONFIG
= IIS_RESET
| EBU_DEFPARM
;
150 /* sets frequency of input to DAC */
151 void pcm_set_frequency(unsigned int frequency
)
158 uda1380_set_nsorder(3);
164 uda1380_set_nsorder(3);
171 uda1380_set_nsorder(5);
177 size_t pcm_get_bytes_waiting(void)
179 return (BCR0
& 0xffffff);
182 /* DMA0 Interrupt is called when the DMA has finished transfering a chunk */
183 void DMA0(void) __attribute__ ((interrupt_handler
, section(".icode")));
188 DSR0
= 1; /* Clear interrupt */
195 logf("DMA Error:0x%04x", res
);
200 unsigned char *next_start
;
202 void (*get_more
)(unsigned char**, size_t*) = callback_for_more
;
204 get_more(&next_start
, &next_size
);
213 SAR0
= (unsigned long)next_start
; /* Source address */
214 BCR0
= next_size
; /* Bytes to transfer */
219 /* Finished playing */
221 logf("DMA No Data:0x%04x", res
);
225 IPR
|= (1<<14); /* Clear pending interrupt request */
233 MPARK
= 0x81; /* PARK[1,0]=10 + BCR24BIT */
234 DIVR0
= 54; /* DMA0 is mapped into vector 54 in system.c */
235 DMAROUTE
= (DMAROUTE
& 0xffffff00) | DMA0_REQ_AUDIO_1
;
236 DMACONFIG
= 1; /* DMA0Req = PDOR3 */
238 /* Reset the audio FIFO */
239 SET_IIS_CONFIG(IIS_RESET
);
241 /* Enable interrupt at level 7, priority 0 */
243 IMR
&= ~(1<<14); /* bit 14 is DMA0 */
245 pcm_set_frequency(44100);
247 /* Prevent pops (resets DAC to zero point) */
248 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq
) | IIS_RESET
);
250 #if defined(HAVE_UDA1380)
251 /* Initialize default register values. */
254 /* Sleep a while so the power can stabilize (especially a long
255 delay is needed for the line out connector). */
258 /* Power on FSDAC and HP amp. */
259 uda1380_enable_output(true);
261 /* Unmute the master channel (DAC should be at zero point now). */
264 #elif defined(HAVE_TLV320)
270 /* Call dma_stop to initialize everything. */
274 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
275 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
277 /* We need to unify this code with the uda1380 code as much as possible, but
278 we will keep it separate during early development.
281 #if CONFIG_CPU == PP5020
282 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16)
283 #elif CONFIG_CPU == PP5002
284 #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
285 #elif CONFIG_CPU == PP5024
286 #define FIFO_FREE_COUNT 4 /* TODO: make this sensible */
289 static int pcm_freq
= 44100; /* 44.1 is default */
291 /* NOTE: The order of these two variables is important if you use the iPod
292 assembler optimised fiq handler, so don't change it. */
293 unsigned short* p IBSS_ATTR
;
294 size_t p_size IBSS_ATTR
;
296 static void dma_start(const void *addr
, size_t size
)
298 p
=(unsigned short*)addr
;
303 #if CONFIG_CPU == PP5020
304 /* setup I2S interrupt for FIQ */
305 outl(inl(0x6000402c) | I2S_MASK
, 0x6000402c);
306 outl(I2S_MASK
, 0x60004024);
307 #elif CONFIG_CPU == PP5024
309 /* setup I2S interrupt for FIQ */
310 outl(inl(0xcf00102c) | DMA_OUT_MASK
, 0xcf00102c);
311 outl(DMA_OUT_MASK
, 0xcf001024);
314 /* Clear the FIQ disable bit in cpsr_c */
317 /* Enable playback FIFO */
318 #if CONFIG_CPU == PP5020
319 IISCONFIG
|= 0x20000000;
320 #elif CONFIG_CPU == PP5002
324 /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to
325 fill the 32-byte FIFO. */
327 if (FIFO_FREE_COUNT
< 2) {
328 /* Enable interrupt */
329 #if CONFIG_CPU == PP5020
331 #elif CONFIG_CPU == PP5002
332 IISFIFO_CFG
|= (1<<9);
337 IISFIFO_WR
= (*(p
++))<<16;
338 IISFIFO_WR
= (*(p
++))<<16;
343 /* Stops the DMA transfer and interrupt */
344 static void dma_stop(void)
348 #if CONFIG_CPU == PP5020
350 /* Disable playback FIFO */
351 IISCONFIG
&= ~0x20000000;
353 /* Disable the interrupt */
356 #elif CONFIG_CPU == PP5002
358 /* Disable playback FIFO */
361 /* Disable the interrupt */
362 IISFIFO_CFG
&= ~(1<<9);
368 void pcm_set_frequency(unsigned int frequency
)
373 size_t pcm_get_bytes_waiting(void)
378 /* ASM optimised FIQ handler. GCC fails to make use of the fact that FIQ mode
379 has registers r8-r14 banked, and so does not need to be saved. This routine
380 uses only these registers, and so will never touch the stack unless it
381 actually needs to do so when calling callback_for_more. C version is still
382 included below for reference.
384 #if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
385 void fiq(void) ICODE_ATTR
__attribute__((naked
));
388 /* r12 contains IISCONFIG address (set in crt0.S to minimise code in actual
389 * FIQ handler. r11 contains address of p (also set in crt0.S). Most other
390 * addresses we need are generated by using offsets with these two.
391 * r12 + 0x40 is IISFIFO_WR, and r12 + 0x0c is IISFIFO_CFG.
392 * r8 and r9 contains local copies of p_size and p respectively.
393 * r10 is a working register.
396 #if CONFIG_CPU == PP5002
397 "ldr r10, =0xcf001040 \n\t" /* Some magic from iPodLinux */
398 "ldr r10, [r10] \n\t"
399 "ldr r10, [r12, #0x1c]\n\t"
400 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
401 "str r10, [r12, #0x1c]\n\t"
403 "ldr r10, [r12] \n\t"
404 "bic r10, r10, #0x2 \n\t" /* clear interrupt */
405 "str r10, [r12] \n\t"
407 "ldr r8, [r11, #4] \n\t" /* r8 = p_size */
408 "ldr r9, [r11] \n\t" /* r9 = p */
410 "cmp r8, #0 \n\t" /* is p_size 0? */
411 "beq .more_data \n\t" /* if so, ask pcmbuf for more data */
413 #if CONFIG_CPU == PP5002
414 "ldr r10, [r12, #0x1c]\n\t" /* read IISFIFO_CFG to check FIFO status */
415 "and r10, r10, #0x7800000\n\t"
416 "cmp r10, #0x800000 \n\t"
418 "ldr r10, [r12, #0x0c]\n\t" /* read IISFIFO_CFG to check FIFO status */
419 "and r10, r10, #0x3f0000\n\t"
420 "cmp r10, #0x10000 \n\t"
422 "bls .fifo_full \n\t" /* FIFO full, exit */
423 "ldr r10, [r9], #4 \n\t" /* load two samples */
424 "mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
425 "str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
426 "mov r10, r10, lsl #16\n\t" /* shift lower sample up */
427 "str r10, [r12, #0x40]\n\t" /* then write it */
428 "subs r8, r8, #4 \n\t" /* check if we have more samples */
429 "bne .fifo_loop \n\t" /* yes, continue */
431 "stmdb sp!, { r0-r3, r12, lr}\n\t" /* stack scratch regs and lr */
432 "mov r0, r11 \n\t" /* r0 = &p */
433 "add r1, r11, #4 \n\t" /* r1 = &p_size */
434 "str r9, [r0] \n\t" /* save internal copies of variables back */
436 "ldr r2, =callback_for_more\n\t"
437 "ldr r2, [r2] \n\t" /* get callback address */
438 "cmp r2, #0 \n\t" /* check for null pointer */
439 "movne lr, pc \n\t" /* call callback_for_more */
441 "ldmia sp!, { r0-r3, r12, lr}\n\t"
442 "ldr r8, [r11, #4] \n\t" /* reload p_size and p */
444 "cmp r8, #0 \n\t" /* did we actually get more data? */
445 "bne .loop \n\t" /* yes, continue to try feeding FIFO */
446 ".dma_stop: \n\t" /* no more data, do dma_stop() and exit */
447 "ldr r10, =pcm_playing\n\t"
448 "strb r8, [r10] \n\t" /* pcm_playing = false (r8=0, look above) */
449 "ldr r10, [r12] \n\t"
450 #if CONFIG_CPU == PP5002
451 "bic r10, r10, #0x4\n\t" /* disable playback FIFO */
452 "str r10, [r12] \n\t"
453 "ldr r10, [r12, #0x1c] \n\t"
454 "bic r10, r10, #0x200 \n\t" /* clear interrupt */
455 "str r10, [r12, #0x1c] \n\t"
457 "bic r10, r10, #0x20000002\n\t" /* disable playback FIFO and IRQ */
458 "str r10, [r12] \n\t"
461 "orr r10, r10, #0x40 \n\t" /* disable FIQ */
462 "msr cpsr_c, r10 \n\t"
464 "str r8, [r11, #4] \n\t"
466 "subs pc, lr, #4 \n\t" /* FIQ specific return sequence */
467 ".fifo_full: \n\t" /* enable IRQ and exit */
468 #if CONFIG_CPU == PP5002
469 "ldr r10, [r12, #0x1c]\n\t"
470 "orr r10, r10, #0x200 \n\t" /* set interrupt */
471 "str r10, [r12, #0x1c]\n\t"
473 "ldr r10, [r12] \n\t"
474 "orr r10, r10, #0x2 \n\t" /* set interrupt */
475 "str r10, [r12] \n\t"
481 void fiq(void) ICODE_ATTR
__attribute__ ((interrupt ("FIQ")));
484 /* Clear interrupt */
485 #if CONFIG_CPU == PP5020
487 #elif CONFIG_CPU == PP5002
489 IISFIFO_CFG
&= ~(1<<9);
494 if (FIFO_FREE_COUNT
< 2) {
495 /* Enable interrupt */
496 #if CONFIG_CPU == PP5020
498 #elif CONFIG_CPU == PP5002
499 IISFIFO_CFG
|= (1<<9);
504 IISFIFO_WR
= (*(p
++))<<16;
505 IISFIFO_WR
= (*(p
++))<<16;
509 /* p is empty, get some more data */
510 if (callback_for_more
) {
511 callback_for_more((unsigned char**)&p
,&p_size
);
515 /* No more data, so disable the FIFO/FIQ */
525 /* Initialize default register values. */
529 wmcodec_enable_output(true);
531 /* Unmute the master channel (DAC should be at zero point now). */
534 /* Call dma_stop to initialize everything. */
538 #elif (CONFIG_CPU == PNX0101)
540 #define DMA_BUF_SAMPLES 0x100
542 short __attribute__((section(".dmabuf"))) dma_buf_left
[DMA_BUF_SAMPLES
];
543 short __attribute__((section(".dmabuf"))) dma_buf_right
[DMA_BUF_SAMPLES
];
545 static int pcm_freq
= 44100; /* 44.1 is default */
547 unsigned short* p IBSS_ATTR
;
548 size_t p_size IBSS_ATTR
;
550 static void dma_start(const void *addr
, size_t size
)
552 p
= (unsigned short*)addr
;
558 static void dma_stop(void)
563 static inline void fill_dma_buf(int offset
)
567 l
= dma_buf_left
+ offset
;
568 lend
= l
+ DMA_BUF_SAMPLES
/ 2;
569 r
= dma_buf_right
+ offset
;
571 if (pcm_playing
&& !pcm_paused
)
576 unsigned short *tmp_p
;
577 count
= MIN(p_size
/ 4, (size_t)(lend
- l
));
589 asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
591 "orr r4, r4, r1, lsl #16\n\t"
593 "orr r5, r5, r3, lsl #16\n\t"
594 "stmia %1!, {r4, r5}\n\t"
596 "orr r4, r4, r0, lsr #16\n\t"
598 "orr r5, r5, r2, lsr #16\n\t"
599 "stmia %2!, {r4, r5}"
600 : "+r" (tmp_p
), "+r" (l
), "+r" (r
)
602 : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
614 else if (callback_for_more
)
615 callback_for_more((unsigned char**)&p
,
624 memset(l
, 0, sizeof(short) * (lend
- l
));
625 memset(r
, 0, sizeof(short) * (lend
- l
));
629 static void audio_irq(void)
631 unsigned long st
= DMAINTSTAT
& ~DMAINTEN
;
633 for (i
= 0; i
< 2; i
++)
636 fill_dma_buf((i
== 1) ? 0 : DMA_BUF_SAMPLES
/ 2);
641 unsigned long physical_address(void *p
)
643 unsigned long adr
= (unsigned long)p
;
644 return (MMUBLOCK((adr
>> 21) & 0xf) << 21) | (adr
& ((1 << 21) - 1));
650 callback_for_more
= NULL
;
654 memset(dma_buf_left
, 0, sizeof(dma_buf_left
));
655 memset(dma_buf_right
, 0, sizeof(dma_buf_right
));
657 for (i
= 0; i
< 8; i
++)
667 DMAINTSTAT
= 0xc000ffff;
668 DMAINTEN
= 0xc000ffff;
670 DMASRC(0) = physical_address(dma_buf_left
);
671 DMADEST(0) = 0x80200280;
676 DMASRC(1) = physical_address(dma_buf_right
);
677 DMADEST(1) = 0x80200284;
682 irq_set_int_handler(0x1b, audio_irq
);
683 irq_enable_int(0x1b);
692 void pcm_set_frequency(unsigned int frequency
)
696 size_t pcm_get_bytes_waiting(void)
702 void pcm_play_stop(void)
711 void pcm_play_data(void (*get_more
)(unsigned char** start
, size_t* size
),
712 unsigned char* start
, size_t size
)
714 callback_for_more
= get_more
;
716 if (!(start
&& size
))
719 get_more(&start
, &size
);
725 dma_start(start
, size
);
728 pcm_play_pause(false);
733 void pcm_mute(bool mute
)
737 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
738 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
740 #elif defined(HAVE_TLV320)
747 void pcm_play_pause(bool play
)
749 bool needs_change
= pcm_paused
== play
;
751 /* This needs to be done ahead of the rest to prevent infinite
752 * recursion from dma_start */
754 if (pcm_playing
&& needs_change
) {
756 if (pcm_get_bytes_waiting()) {
760 /* Enable the FIFO and force one write to it */
761 SET_IIS_CONFIG(IIS_DEFPARM(pcm_freq
));
762 #ifdef HAVE_SPDIF_OUT
763 EBU1CONFIG
= EBU_DEFPARM
;
765 DCR0
|= DMA_EEXT
| DMA_START
;
766 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
767 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
768 /* Enable the FIFO and fill it */
772 /* Enable playback FIFO */
773 #if CONFIG_CPU == PP5020
774 IISCONFIG
|= 0x20000000;
775 #elif CONFIG_CPU == PP5002
779 /* Fill the FIFO - we assume there are enough bytes in the
780 pcm buffer to fill the 32-byte FIFO. */
782 if (FIFO_FREE_COUNT
< 2) {
783 /* Enable interrupt */
784 #if CONFIG_CPU == PP5020
786 #elif CONFIG_CPU == PP5002
787 IISFIFO_CFG
|= (1<<9);
792 IISFIFO_WR
= (*(p
++))<<16;
793 IISFIFO_WR
= (*(p
++))<<16;
796 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
800 #if (CONFIG_CPU != PNX0101 && CONFIG_CPU != S3C2440)
802 unsigned char *next_start
;
803 void (*get_more
)(unsigned char**, size_t*) = callback_for_more
;
804 logf("unpause, no data waiting");
806 get_more(&next_start
, &next_size
);
807 if (next_start
&& next_size
)
808 dma_start(next_start
, next_size
);
812 logf("unpause attempted, no data");
820 /* Disable DMA peripheral request. */
822 SET_IIS_CONFIG(IIS_RESET
| IIS_DEFPARM(pcm_freq
));
823 #ifdef HAVE_SPDIF_OUT
824 EBU1CONFIG
= IIS_RESET
| EBU_DEFPARM
;
826 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) \
827 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
828 #if CONFIG_CPU == PP5020
829 /* Disable the interrupt */
831 /* Disable playback FIFO */
832 IISCONFIG
&= ~0x20000000;
833 #elif CONFIG_CPU == PP5002
834 /* Disable the interrupt */
835 IISFIFO_CFG
&= ~(1<<9);
836 /* Disable playback FIFO */
841 #elif (CONFIG_CPU == PNX0101 || CONFIG_CPU == S3C2440) /* End wmcodecs */
845 } /* pcm_playing && needs_change */
848 bool pcm_is_playing(void) {
852 bool pcm_is_paused(void) {
857 #if defined(CPU_COLDFIRE)
858 /* Peaks ahead in the DMA buffer based upon the calling period to
859 attempt to compensate for the delay. Keeps a moving average of
861 void pcm_calculate_peaks(int *left
, int *right
)
863 unsigned long samples
;
864 unsigned long *addr
, *end
;
867 static unsigned long last_peak_tick
= 0;
868 static unsigned long frame_period
= 0;
870 /* Throttled peak ahead based on calling period */
871 unsigned long period
= current_tick
- last_peak_tick
;
873 /* Keep reasonable limits on period */
876 else if (period
> HZ
/5)
879 frame_period
= (3*frame_period
+ period
) >> 2;
881 last_peak_tick
= current_tick
;
883 if (!pcm_playing
|| pcm_paused
)
885 peak_left
= peak_right
= 0;
889 samples
= (BCR0
& 0xffffff) >> 2;
890 addr
= (long *)(SAR0
& ~3);
891 samples
= MIN(frame_period
*44100/HZ
, samples
);
892 end
= addr
+ samples
;
899 long peak_rp
= 0, peak_rn
= 0;
907 if (ch
> peak_p
) peak_p
= ch
;
908 else if (ch
< peak_n
) peak_n
= ch
;
911 if (ch
> peak_rp
) peak_rp
= ch
;
912 else if (ch
< peak_rn
) peak_rn
= ch
;
918 peak_left
= MAX(peak_p
, -peak_n
);
919 peak_right
= MAX(peak_rp
, -peak_rn
);
922 else if (left
|| right
)
928 /* Put left channel in low word */
929 addr
= (long *)((short *)addr
- 1);
930 end
= (long *)((short *)end
- 1);
935 long value
= *(short *)addr
;
937 if (value
> peak_p
) peak_p
= value
;
938 else if (value
< peak_n
) peak_n
= value
;
945 peak_left
= MAX(peak_p
, -peak_n
);
947 peak_right
= MAX(peak_p
, -peak_n
);
960 * This function goes directly into the DMA buffer to calculate the left and
961 * right peak values. To avoid missing peaks it tries to look forward two full
962 * peek periods (2/HZ sec, 100% overlap), although it's always possible that
963 * the entire period will not be visible. To reduce CPU load it only looks at
964 * every third sample, and this can be reduced even further if needed (even
965 * every tenth sample would still be pretty accurate).
968 /* Check for a peak every PEAK_STRIDE samples */
969 #define PEAK_STRIDE 3
970 /* Up to 1/50th of a second of audio for peak calculation */
971 /* This should use NATIVE_FREQUENCY, or eventually an adjustable freq. value */
972 #define PEAK_SAMPLES (44100/50)
973 void pcm_calculate_peaks(int *left
, int *right
)
975 #if (CONFIG_CPU == S3C2440)
982 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
983 || defined(HAVE_WM8731) || defined(HAVE_WM8721) \
984 || (CONFIG_CPU == PNX0101)
985 size_t samples
= p_size
/ 4;
989 if (samples
> PEAK_SAMPLES
)
990 samples
= PEAK_SAMPLES
- (PEAK_STRIDE
- 1);
992 samples
-= MIN(PEAK_STRIDE
- 1, samples
);
994 end
= &addr
[samples
* 2];
998 int left_peak
= 0, right_peak
= 0;
1000 while (addr
< end
) {
1002 if ((value
= addr
[0]) > left_peak
)
1004 else if (-value
> left_peak
)
1007 if ((value
= addr
[PEAK_STRIDE
| 1]) > right_peak
)
1009 else if (-value
> right_peak
)
1010 right_peak
= -value
;
1012 addr
= &addr
[PEAK_STRIDE
* 2];
1016 *right
= right_peak
;
1018 else if (left
|| right
) {
1019 int peak_value
= 0, value
;
1022 addr
+= (PEAK_STRIDE
| 1);
1024 while (addr
< end
) {
1025 if ((value
= addr
[0]) > peak_value
)
1027 else if (-value
> peak_value
)
1028 peak_value
= -value
;
1030 addr
+= PEAK_STRIDE
* 2;
1036 *right
= peak_value
;
1040 #endif /* CPU_COLDFIRE */