SSI and AC97 isn't working on imx6 and Linux 3.0.35

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SSI and AC97 isn't working on imx6 and Linux 3.0.35

1,458 Views
andreaszeiler
Contributor III

Hi,

i try to get audio playing on a board with imx6 and a wm9715 codec with ac97. On boot-up linux probes the driver and everything is fine.

But i can't hear a sound when i play a file. It seems to me that the codec is not ready or muted by default.

I checked reset signals with an oszilloscope. And also clock and data signals. I get 12,288 MHz and a FrameSync of 48Khz.

Also, when i play audio i see the audio samples in slot 3 and 4. But when i want to unmute the codec or set volume with alsamixer, i don't see any toggling of the "address" or "data" slot of AC97.

And in Slot 0 the corresponding valid bits of address and data stay invalid. Since i get good clock and frame sync signals i think that the ssi interface is configured well.

I've made printk's in the imx_ssi_ac97_write-function of imx-ssi.c in sound/soc/imx. With writel i can write to the address like SSI_SACADD or SSI_SACDAT and also read back with readl, but i can't see anything on the bus.

Does anyone know whats wrong here? Do I have to configure something or is there a known bug or something?

With kind regards

Andi

Labels (3)
0 Kudos
2 Replies

449 Views
andreaszeiler
Contributor III

Hello,

the problem was that the codec was in power down mode. The wake up of the codec from ac97_codec.c (snd_ac97_mixer) in sound/soc/codec has been skipped because of an goto statement. now i get a output signals. the only problem is that the sound is played with a doubled rate.

andi

0 Kudos

449 Views
andreaszeiler
Contributor III

Hello,

here are the changes to get right buffering from AC97 codec on IMX6.

diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c

index a616252..3435d49 100644

--- a/sound/soc/imx/imx-ssi.c

+++ b/sound/soc/imx/imx-ssi.c

@@ -685,26 +684,29 @@ static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)

     writel(0x0, base + SSI_STCR);

     writel(0x0, base + SSI_SRCR);

-    writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);

+    writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_TCH_EN, base + SSI_SCR);

     writel(SSI_SFCSR_RFWM0(imx_ssi->dma_params_rx.burstsize) |

         SSI_SFCSR_TFWM0(imx_ssi->dma_params_tx.burstsize) |

         SSI_SFCSR_RFWM1(imx_ssi->dma_params_rx.burstsize) |

         SSI_SFCSR_TFWM1(imx_ssi->dma_params_tx.burstsize), base + SSI_SFCSR);

       

     writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);

     writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);

-

-    writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);

+    writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN | SSI_SCR_TCH_EN, base + SSI_SCR);

     writel(SSI_SOR_WAIT(3), base + SSI_SOR);

     writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |

-            SSI_SCR_TE | SSI_SCR_RE,

+            SSI_SCR_TE | SSI_SCR_RE | SSI_SCR_TCH_EN,

             base + SSI_SCR);

     writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);

     writel(0xff, base + SSI_SACCDIS);

     writel(0x300, base + SSI_SACCEN);

+   

+    udelay(100);

+   

   

}

static struct imx_ssi *ac97_ssi;

@@ -724,12 +726,14 @@ static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,

     lreg = reg <<  12;

     writel(lreg, base + SSI_SACADD);

     lval = val << 4;

     writel(lval , base + SSI_SACDAT);

     writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);

+

     udelay(100);

+

}

static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,

@@ -737,18 +741,15 @@ static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,

{

     struct imx_ssi *imx_ssi = ac97_ssi;

     void __iomem *base = imx_ssi->base;

     unsigned short val = -1;

     unsigned int lreg;

     lreg = (reg & 0x7f) <<  12 ;

     writel(lreg, base + SSI_SACADD);

     writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);

     udelay(100);

     val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;

     pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);

     return val;

@@ -837,7 +838,10 @@ static int imx_ssi_probe(struct platform_device *pdev)

         dai = &imx_ac97_dai;

     } else

         dai = &imx_ssi_dai;

-

+       

+    writel(SSI_SIER_TFE0_EN|SSI_SISR_TFE1|

+    SSI_SISR_TDE0|SSI_SISR_TDE1, ssi->base + SSI_SIER);

+       

     writel(0x0, ssi->base + SSI_SIER);

     ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;

@@ -890,7 +894,6 @@ static int imx_ssi_probe(struct platform_device *pdev)

         dev_err(&pdev->dev, "failed to add platform device\n");

         goto failed_pdev_add;

     }

-

     return 0;

failed_pdev_add:

0 Kudos