Steve,

Along with this mail, I am sending following 2 patches:

tx_swap.patch: This patch fixes the channel swap issue on the TX side (play).
rx_swap.patch: This patch fixes the channel swap issue on RX side (record).

In both the patches, the frame sync pins are being configured as GPIO and the 
first frame sync is being ignored. Only after the first frame sync, the pins 
are being configured as Audio pins.

Please note that, this patch is for Linux 2.6.10 MV Kernel.

Regards, Sudhakar
________________________________
From: [email protected] 
[[email protected]] On Behalf Of Stephen 
Berry [[email protected]]
Sent: Wednesday, February 11, 2009 2:16 AM
To: [email protected]
Subject: stereo audio from aic33 (ASP help)


I'm having trouble getting stereo data from the AIC33 - well to be more 
correct, the codec seems to be supplying stereo data, but the ASP seems to be 
generating mono audio.  And just to top it off, it looks like the channel that 
is active seems to swap randomly.

MVL 2.6.10 - custom hardware (using ASP0 not 1)

Here is what I've seen so far:

    The ASP setup seems to be looking for two phases of data per frame - but 
the bit that enables phases wasn't set. Setting this didn't help.
    The second channel of audio is generally midline (0).
    DMA seems to be setup to grab a 32bit word from the interface (DRR register 
for received data)
    With the codec in master mode I've observed on the scope that there is 
truly stereo data being fed to the AIC33
    The encoder demo uses a nice averaging trick that hides the channel swap 
beautifully.

I'm unsure of the logic the ASP uses to determine when to tell the DMA engine 
it is ready with data. I also don't know what happens with more than one 
"phase" of data. Are there two DMA transfers or one packed 32 bit word?

Any help from some ASP experts would be appreciated.

Thanks,

    Steve Berry

Index: Linux/include/asm-arm/arch-davinci/mcbsp.h
===================================================================
--- Linux.orig/include/asm-arm/arch-davinci/mcbsp.h
+++ Linux/include/asm-arm/arch-davinci/mcbsp.h
@@ -40,6 +40,9 @@
 #define DAVINCI_McBSP1RX IRQ_MBRINT
 #define DAVINCI_McBSP1TX IRQ_MBXINT
 
+/* Define to set the CODEC as the master w.r.t McBSP */
+#define CODEC_MASTER
+
 #define DRR1   0x00
 #define DRR2   0x02
 #define DXR1   0x04
@@ -72,6 +75,10 @@
 #define RCERH  0x3a
 #define XCERG  0x3c
 #define XCERH  0x3e
+               /*32 bit register definitions*/
+#define PCR                    __REG(0x01E02024)
+#define SPCR                   __REG(0x01E02008)
+
 
 #define DAVINCI_MAX_MCBSP_COUNT 1
 
@@ -115,6 +122,17 @@
 #define XIOEN          0x2000
 #define IDLE_EN                0x4000
 
+
+
+               /*32 Rx bit definitions*/
+#define FSRPOLARITY    0x00000004
+#define FSRMODE         0x00000400
+#define RIOENABLE       0x00001000
+#define RRESET          0x00000001
+#define RIORESET        0x00001004
+#define CLKRPOLARITY    0x00000001
+
+
 /********************** McBSP RCR1 bit definitions ************************/
 #define RWDLEN1(value)         ((value)<<5)    /* Bits 5:7 */
 #define RFRLEN1(value)         ((value)<<8)    /* Bits 8:14 */
@@ -239,7 +257,7 @@ void davinci_mcbsp_config(unsigned int i
 int davinci_mcbsp_request(unsigned int id);
 void davinci_mcbsp_free(unsigned int id);
 void davinci_mcbsp_start_tx(unsigned int id);
-void davinci_mcbsp_start_rx(unsigned int id);
+void davinci_mcbsp_start_rx(unsigned int id, int lch);
 void davinci_mcbsp_stop_tx(unsigned int id);
 void davinci_mcbsp_stop_rx(unsigned int id);
 void davinci_mcbsp_xmit_word(unsigned int id, u32 word);
Index: Linux/sound/oss/davinci-audio-dma-intfc.c
===================================================================
--- Linux.orig/sound/oss/davinci-audio-dma-intfc.c
+++ Linux/sound/oss/davinci-audio-dma-intfc.c
@@ -818,8 +818,7 @@ static int audio_start_dma_chain(audio_s
                davinci_get_dma_params(channel, &temp);
                davinci_set_dma_params(s->master_ch, &temp);
                s->started = 1;
-
-               if (!s->dma_started) {
+               if (!s->dma_started && s->input_or_output == FMODE_WRITE) {
                        davinci_start_dma(s->master_ch);
                        s->dma_started = 1;
                }
@@ -830,8 +829,9 @@ static int audio_start_dma_chain(audio_s
                                davinci_mcbsp_start_tx(0);
                                s->mcbsp_tx_started = 1;
                        } else {
-                               davinci_mcbsp_start_rx(0);
+                               davinci_mcbsp_start_rx(0, s->master_ch);
                                s->mcbsp_rx_started = 1;
+                               s->dma_started = 1;
                        }
                        local_irq_restore(flags);
                } else
Index: Linux/arch/arm/mach-davinci/mcbsp.c
===================================================================
--- Linux.orig/arch/arm/mach-davinci/mcbsp.c
+++ Linux/arch/arm/mach-davinci/mcbsp.c
@@ -299,10 +299,16 @@ void davinci_mcbsp_start_tx(unsigned int
  * Here we start the McBSP receiver, by enabling the sample
  * generator, both transmitter and receivers, and the frame sync.
  */
-void davinci_mcbsp_start_rx(unsigned int id)
+void davinci_mcbsp_start_rx(unsigned int id , int lch)
 {
        u32 io_base;
        u16 w;
+       u32 pcrtemp;
+               /*Lock to disable the irqs*/
+               /*while resetting the reciever*/
+       spinlock_t rrstlock;
+       unsigned long flags;
+       int i;
 
        if (davinci_mcbsp_check(id) < 0)
                return;
@@ -313,23 +319,60 @@ void davinci_mcbsp_start_rx(unsigned int
            ((DAVINCI_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
 
        udelay(100);
+       davinci_start_dma(lch);
+#ifdef CODEC_MASTER
+       spin_lock_init(&rrstlock);
+       spin_lock_irqsave(&rrstlock, flags);
+               /*PCR register to restore the value*/
+       pcrtemp = PCR;
+               /*Enable the transmitters pins as GPIO*/
+       PCR  =  PCR | RIOENABLE;
+               /*Wait for the first frame sync*/
+               /*Loop count assumes CPU clock is around 300MHZ*/
+
+
+       for (i = 0; (i < 5000) && (PCR&FSRPOLARITY); i++);
+
+
+       for (i = 0; (i < 5000) && (!(PCR&FSRPOLARITY)); i++);
+               /*Disabe the transmitter pins as GPIO*/
+       PCR  =  PCR & ~RIOENABLE;
+               /*Restore the PCR initial value*/
+
+       PCR  =  pcrtemp;
+               /*Enable the transmitter */
+       if (i < 5000) {
+               SPCR =  SPCR | RRESET;
        
+               /*Restore the PCR initial value*/
+       } else {
+               printk(KERN_INFO "frame sync not detected\n");
+               spin_unlock_irqrestore(&rrstlock, flags);
+               return -1;
+       }
+
+       spin_unlock_irqrestore(&rrstlock, flags);
+
+       udelay(100);
+
+
+#else
                /* Start the sample generator */
        w = DAVINCI_MCBSP_READ(io_base, SPCR2);
        DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
 
        udelay(100);
-       
+
                /* Enable receiver */
        w = DAVINCI_MCBSP_READ(io_base, SPCR1);
-       DAVINCI_MCBSP_WRITE(io_base, SPCR1, w | 1);
+       DAVINCI_MCBSP_WRITE(io_base, SPCR1, w | RRST);
 
        udelay(100);
 
        /* Start frame sync */
        w = DAVINCI_MCBSP_READ(io_base, SPCR2);
        DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
-
+#endif
        return;
 }
 
Index: Linux/arch/arm/mach-davinci/mcbsp.c
===================================================================
--- Linux.orig/arch/arm/mach-davinci/mcbsp.c
+++ Linux/arch/arm/mach-davinci/mcbsp.c
@@ -31,6 +31,8 @@
 #include <asm/arch/irqs.h>
 #include <asm/arch/mcbsp.h>
 #include <asm/hardware/clock.h>
+#include <asm/hardware.h>
+
 
 struct clk *mbspclk = NULL;
 
@@ -241,11 +243,14 @@ void davinci_mcbsp_free(unsigned int id)
  * Here we start the McBSP transmitter, by enabling the sample
  * generator, both transmitter and receivers, and the frame sync.
  */
-void davinci_mcbsp_start_tx(unsigned int id)
+
+void davinci_mcbsp_start_tx(unsigned int id,int lch)
 {
        u32 io_base;
        u16 w;
-
+       u32 pcrtemp;
+       spinlock_t xrstlock;
+       unsigned long flags;
        if (davinci_mcbsp_check(id) < 0)
                return;
 
@@ -269,29 +274,29 @@ void davinci_mcbsp_start_tx(unsigned int
        DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | XRST);
        udelay(100);
        DAVINCI_MCBSP_WRITE(io_base, SPCR2, w & ~XRST);
-       
+
                /* step 7: guaranteed by start EDMA first*/     
+       davinci_start_dma(lch);
        
        udelay(100);
-       
-               /* step 8: Enable transmitter */
-       w = DAVINCI_MCBSP_READ(io_base, SPCR2);
-       DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | XRST);
-       
-       udelay(100);
+       spin_lock_init(&xrstlock);
+       spin_lock_irqsave(&xrstlock, flags);            
+               /* Read the PCR register to restore the value*/                 
      
+       pcrtemp=PCR;
+               /*Enable the transmitters pins as GPIO*/
+       PCR  =  PCR | XIOENABLE;
+               /*Wait for the first frame sync*/
+       while (!(PCR&FSXPOLARITY));
+       while (PCR&FSXPOLARITY);
+               /*Disabe the transmitter pins as GPIO*/
+       PCR  =  PCR & ~XIOENABLE;
+               /*Restore the PCR initial value*/
+       PCR  =  pcrtemp;
+               /*Enable the transmitter*/
+       SPCR =  SPCR | XRESET;
+       spin_unlock_irqrestore(&xrstlock, flags);               
 
-               /* step 9: FSGM has been set, need do step 10 & 11 */
-       
-               /* step 10: if XEMPTY = 1, write one data to DXR to clear the 
XEMPTY*/
-       w = DAVINCI_MCBSP_READ(io_base, SPCR2);
-       if (!(w & XEMPTY))
-           DAVINCI_MCBSP_WRITE(io_base, DXR1, 0x0);
-       
-               /* step 11: wait 7 to 8 CLKG before set FRST */
        udelay(100);
-       w = DAVINCI_MCBSP_READ(io_base, SPCR2);
-       DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | FRST);
-
        return;
 }
 
@@ -313,7 +318,7 @@ void davinci_mcbsp_start_rx(unsigned int
            ((DAVINCI_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
 
        udelay(100);
-       
+
                /* Start the sample generator */
        w = DAVINCI_MCBSP_READ(io_base, SPCR2);
        DAVINCI_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
Index: Linux/include/asm-arm/arch-davinci/mcbsp.h
===================================================================
--- Linux.orig/include/asm-arm/arch-davinci/mcbsp.h
+++ Linux/include/asm-arm/arch-davinci/mcbsp.h
@@ -72,6 +72,10 @@
 #define RCERH  0x3a
 #define XCERG  0x3c
 #define XCERH  0x3e
+               /*32 bit register definitions*/         
+#define PCR                    __REG(0x01E02024)
+#define SPCR                   __REG(0x01E02008)
+                               
 
 #define DAVINCI_MAX_MCBSP_COUNT 1
 
@@ -114,6 +118,13 @@
 #define RIOEN          0x1000
 #define XIOEN          0x2000
 #define IDLE_EN                0x4000
+               /*32 bit definitions*/
+#define FSXPOLARITY    0x00000008
+#define FSXMODE         0x00000800
+#define XIOENABLE       0x00002000
+#define XRESET          0x00010000
+#define XIORESET        0x00002008
+#define CLKXPOLARITY    0x00000002
 
 /********************** McBSP RCR1 bit definitions ************************/
 #define RWDLEN1(value)         ((value)<<5)    /* Bits 5:7 */
@@ -238,7 +249,7 @@ void davinci_mcbsp_config(unsigned int i
                          const struct davinci_mcbsp_reg_cfg *config);
 int davinci_mcbsp_request(unsigned int id);
 void davinci_mcbsp_free(unsigned int id);
-void davinci_mcbsp_start_tx(unsigned int id);
+void davinci_mcbsp_start_tx(unsigned int id,int lch);
 void davinci_mcbsp_start_rx(unsigned int id);
 void davinci_mcbsp_stop_tx(unsigned int id);
 void davinci_mcbsp_stop_rx(unsigned int id);
Index: Linux/sound/oss/davinci-audio-dma-intfc.c
===================================================================
--- Linux.orig/sound/oss/davinci-audio-dma-intfc.c
+++ Linux/sound/oss/davinci-audio-dma-intfc.c
@@ -819,7 +819,7 @@ static int audio_start_dma_chain(audio_s
                davinci_set_dma_params(s->master_ch, &temp);
                s->started = 1;
 
-               if (!s->dma_started) {
+               if (!s->dma_started&&s->input_or_output == FMODE_READ) {
                        davinci_start_dma(s->master_ch);
                        s->dma_started = 1;
                }
@@ -827,7 +827,8 @@ static int audio_start_dma_chain(audio_s
                if(!s->mcbsp_tx_started || !s->mcbsp_rx_started) {
                        local_irq_restore(flags);
                        if (s->input_or_output == FMODE_WRITE) {
-                               davinci_mcbsp_start_tx(0);
+                               davinci_mcbsp_start_tx(0,s->master_ch);
+                               s->dma_started = 1;
                                s->mcbsp_tx_started = 1;
                        } else {
                                davinci_mcbsp_start_rx(0);
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to