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
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
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: