<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Index: firmware/pcm_playback.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/pcm_playback.c,v
retrieving revision 1.105
diff -u -r1.105 pcm_playback.c
--- firmware/pcm_playback.c	10 Mar 2006 13:47:12 -0000	1.105
+++ firmware/pcm_playback.c	10 Apr 2006 18:11:55 -0000
@@ -33,6 +33,8 @@
 #include "tlv320.h"
 #elif defined(HAVE_WM8731)
 #include "wm8731l.h"
+#elif CONFIG_CPU == PNX0101
+#include "pnx0101.h"
 #endif
 #include "system.h"
 #include "logf.h"
@@ -682,13 +684,146 @@
 
 #elif (CONFIG_CPU == PNX0101)
 
-/* TODO: Implement for iFP7xx
-   For now, just implement some dummy functions.
-*/
+static struct {
+    unsigned short* p;
+    long p_size;
+    bool pcm_playing;
+    bool pcm_paused;
+    void (*callback_for_more)(unsigned char**, size_t*);
+} pcm_state;
+
+
+#define DMA_BUF_SAMPLES 0x100
+
+short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES];
+short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES];
+
+static inline void fill_dma_buf(int offset)
+{
+    short *l, *r, *lend;
+
+    l = dma_buf_left + offset;
+    lend = l + DMA_BUF_SAMPLES / 2;
+    r = dma_buf_right + offset;
+
+    if (pcm_state.pcm_playing &amp;&amp; !pcm_state.pcm_paused)
+    {
+        do
+        {
+            int count;
+            unsigned short *tmp_p;
+            count = MIN(pcm_state.p_size / 4, lend - l);
+            tmp_p = pcm_state.p;
+            pcm_state.p_size -= count * 4;
+
+            if ((int)l &amp; 3)
+            {
+                *l++ = *tmp_p++;
+                *r++ = *tmp_p++;
+                count--;
+            }
+            while (count &gt;= 4)
+            {
+                asm("ldmia %0!, {r0, r1, r2, r3}\n\t"
+                    "and   r4, r0, %3\n\t"
+                    "orr   r4, r4, r1, lsl #16\n\t"
+                    "and   r5, r2, %3\n\t"
+                    "orr   r5, r5, r3, lsl #16\n\t"
+                    "stmia %1!, {r4, r5}\n\t"
+                    "bic   r4, r1, %3\n\t"
+                    "orr   r4, r4, r0, lsr #16\n\t"
+                    "bic   r5, r3, %3\n\t"
+                    "orr   r5, r5, r2, lsr #16\n\t"
+                    "stmia %2!, {r4, r5}"
+                    : "+r" (tmp_p), "+r" (l), "+r" (r)
+                    : "r" (0xffff)
+                    : "r0", "r1", "r2", "r3", "r4", "r5", "memory");
+                count -= 4;
+            }
+            while (count &gt; 0)
+            {
+                *l++ = *tmp_p++;
+                *r++ = *tmp_p++;
+                count--;
+            }
+            pcm_state.p = tmp_p;
+            if (l &gt;= lend)
+                return;
+            else if (pcm_state.callback_for_more)
+                pcm_state.callback_for_more((unsigned char**)&amp;pcm_state.p,
+                                            &amp;pcm_state.p_size);
+        }
+        while (pcm_state.p_size);
+        pcm_state.pcm_playing = false;
+    }
+
+    if (l &lt; lend)
+    {
+        memset(l, 0, sizeof(short) * (lend - l));
+        memset(r, 0, sizeof(short) * (lend - l));
+    }
+}
+
+static void audio_irq(void)
+{
+    unsigned long st = DMAINTSTAT &amp; ~DMAINTEN;
+    int i;
+    for (i = 0; i &lt; 2; i++)
+        if (st &amp; (1 &lt;&lt; i)) {
+            fill_dma_buf((i == 1) ? 0 : DMA_BUF_SAMPLES / 2);
+            DMAINTSTAT = 1 &lt;&lt; i;
+        }
+}
+
+unsigned long physical_address(void *p)
+{
+    unsigned long adr = (unsigned long)p;
+    return (MMUBLOCK((adr &gt;&gt; 21) &amp; 0xf) &lt;&lt; 21) | (adr &amp; ((1 &lt;&lt; 21) - 1));
+}
 
 void pcm_init(void)
 {
+    int i;
+    pcm_state.callback_for_more = NULL;
+    pcm_state.pcm_playing = false;
+    pcm_state.pcm_paused = false;
+
+    memset(dma_buf_left, 0, sizeof(dma_buf_left));
+    memset(dma_buf_right, 0, sizeof(dma_buf_right));
 
+    for (i = 0; i &lt; 8; i++)
+    {
+        DMASRC(i) = 0;
+        DMADEST(i) = 0;
+        DMALEN(i) = 0x1ffff;
+        DMAR0C(i) = 0;
+        DMAR10(i) = 0;
+        DMAR1C(i) = 0;
+    }
+
+    DMAINTSTAT = 0xc000ffff;
+    DMAINTEN = 0xc000ffff;
+    
+    DMASRC(0) = physical_address(dma_buf_left);
+    DMADEST(0) = 0x80200280;
+    DMALEN(0) = 0xff;
+    DMAR1C(0) = 0;
+    DMAR0C(0) = 0x40408;
+
+    DMASRC(1) = physical_address(dma_buf_right);
+    DMADEST(1) = 0x80200284;
+    DMALEN(1) = 0xff;
+    DMAR1C(1) = 0;
+    DMAR0C(1) = 0x40409;
+
+    irq_set_int_handler(0x1b, audio_irq);
+    irq_enable_int(0x1b);
+
+    DMAINTSTAT = 1;
+    DMAINTSTAT = 2;
+    DMAINTEN &amp;= ~3;
+    DMAR10(0) |= 1;
+    DMAR10(1) |= 1;
 }
 
 void pcm_set_frequency(unsigned int frequency)
@@ -699,13 +834,15 @@
 void pcm_play_data(void (*get_more)(unsigned char** start, size_t* size),
         unsigned char* start, size_t size)
 {
-    (void)get_more;
-    (void)start;
-    (void)size;
+    pcm_state.callback_for_more = get_more;
+    pcm_state.p = (unsigned short *)start;
+    pcm_state.p_size = size;
+    pcm_state.pcm_playing = true;
 }
 
 void pcm_play_stop(void)
 {
+    pcm_state.pcm_playing = false;
 }
 
 void pcm_mute(bool mute)
@@ -715,33 +852,28 @@
 
 void pcm_play_pause(bool play)
 {
-    (void)play;
+    if (!pcm_state.pcm_playing)
+        return;
+    pcm_state.pcm_paused = !play;
 }
 
 bool pcm_is_paused(void)
 {
-    return false;
+    return pcm_state.pcm_paused;
 }
 
 bool pcm_is_playing(void)
 {
-    return false;
-}
-
-void pcm_calculate_peaks(int *left, int *right)
-{
-    (void)left;
-    (void)right;
+    return pcm_state.pcm_playing;
 }
 
 size_t pcm_get_bytes_waiting(void)
 {
-    return 0;
+    return pcm_state.p_size;
 }
 
 #endif
 
-#if (CONFIG_CPU != PNX0101)
 /*
  * This function goes directly into the DMA buffer to calculate the left and
  * right peak values. To avoid missing peaks it tries to look forward two full
@@ -771,6 +903,9 @@
 #elif defined(HAVE_TLV320)
         size_t samples = 4;  /* TODO X5 */
         addr = NULL;
+#elif CONFIG_CPU == PNX0101
+        size_t samples = pcm_state.p_size / 4;
+        addr = pcm_state.p;
 #endif
 
         if (samples &gt; PEAK_SAMPLES)
@@ -823,5 +958,3 @@
             *right = peak_value;
     }
 }
-
-#endif
Index: firmware/sound.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/sound.c,v
retrieving revision 1.29
diff -u -r1.29 sound.c
--- firmware/sound.c	28 Feb 2006 00:58:17 -0000	1.29
+++ firmware/sound.c	10 Apr 2006 18:11:55 -0000
@@ -34,6 +34,8 @@
 #include "wm8731l.h"
 #elif defined(HAVE_TLV320)
 #include "tlv320.h"
+#elif CONFIG_CPU == PNX0101
+#include "pnx0101.h"
 #endif
 #include "dac.h"
 #include "system.h"
@@ -557,8 +559,10 @@
     current_volume = value * 10;     /* tenth of dB */
     set_prescaled_volume();                          
 #elif CONFIG_CPU == PNX0101
-    /* TODO: implement for iFP */
-    (void)value;
+    int tmp = 0xff - (value + 78);
+    if (tmp &lt; 0x10) tmp = 0x10;
+    if (tmp &gt; 0xfc) tmp = 0xfc;
+    CODECVOL = tmp | (tmp &lt;&lt; 8);
 #endif
 }
 
Index: firmware/export/pnx0101.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/pnx0101.h,v
retrieving revision 1.1
diff -u -r1.1 pnx0101.h
--- firmware/export/pnx0101.h	12 Jan 2006 00:35:50 -0000	1.1
+++ firmware/export/pnx0101.h	10 Apr 2006 18:11:56 -0000
@@ -64,3 +64,16 @@
 #define ADCR24   (*(volatile unsigned long *)0x80002424)
 #define ADCR28   (*(volatile unsigned long *)0x80002428)
 
+#define DMAINTSTAT   (*(volatile unsigned long *)0x80104c04)
+#define DMAINTEN     (*(volatile unsigned long *)0x80104c08)
+
+#define DMASRC(n)    (*(volatile unsigned long *)(0x80104800 + (n) * 0x20))
+#define DMADEST(n)   (*(volatile unsigned long *)(0x80104804 + (n) * 0x20))
+#define DMALEN(n)    (*(volatile unsigned long *)(0x80104808 + (n) * 0x20))
+#define DMAR0C(n)    (*(volatile unsigned long *)(0x8010480c + (n) * 0x20))
+#define DMAR10(n)    (*(volatile unsigned long *)(0x80104810 + (n) * 0x20))
+#define DMAR1C(n)    (*(volatile unsigned long *)(0x8010481c + (n) * 0x20))
+
+#define MMUBLOCK(n)  (*(volatile unsigned long *)(0x80105018 + (n) * 4))
+
+#define CODECVOL     (*(volatile unsigned long *)0x80200398)
</pre></body></html>