diff mbox

[20/20] ASoC: Always syncronize audio transfers on frames

Message ID 1248958183-15015-21-git-send-email-eduardo.valentin@nokia.com (mailing list archive)
State Awaiting Upstream, archived
Headers show

Commit Message

Eduardo Valentin July 30, 2009, 12:49 p.m. UTC
From: Eero Nurkkala <ext-eero.nurkkala@nokia.com>

All these steps are required for ASoC to behave correctly.
This is, no RFIG or XFIG (Not defined in 34xx), correct
initiliazation of rccr and xccr. They are format dependent,
for example TDM audio has different values than I2S or
DSP_A. Also the omap_mcbsp_xmit_enable and/or
omap_mcbsp_recv_enable must be called right after the
DMA has started. This provides no longer L and R channels
switching at random.

Signed-off-by: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
---
 sound/soc/omap/omap-mcbsp.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

Comments

Jarkko Nikula July 30, 2009, 6:57 p.m. UTC | #1
On Thu, 30 Jul 2009 15:49:43 +0300
Eduardo Valentin <eduardo.valentin@nokia.com> wrote:

> @@ -321,8 +326,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct
> snd_soc_dai *cpu_dai, /* Generic McBSP register settings */
>  	regs->spcr2	|= XINTM(3) | FREE;
>  	regs->spcr1	|= RINTM(3);
> -	regs->rcr2	|= RFIG;
> -	regs->xcr2	|= XFIG;
> +	/* RFIG and XFIG are not defined in 34xx */
> +	if (!cpu_is_omap34xx()) {
> +		regs->rcr2	|= RFIG;
> +		regs->xcr2	|= XFIG;
> +	}

This is true. These bits are marked as reserved read only bits in 34xx.
I'm fine if you do change here in this patch but I can add immediate
acked-by if you want to post this as a separate change for 2.6.32
(setting them for 34xx is null-op at the moment AFAIK).

If you find generic fix for channel switching problem found also from
older OMAP's like 2420 then I give you a deep bow and acked-by for
2.6.31!
diff mbox

Patch

diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index a5d46a7..0272d3f 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -191,6 +191,11 @@  static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		if (!mcbsp_data->active++)
 			omap_mcbsp_start(mcbsp_data->bus_id);
+		/* Make sure data transfer is frame synchronized */
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			omap_mcbsp_xmit_enable(mcbsp_data->bus_id, 1);
+		else
+			omap_mcbsp_recv_enable(mcbsp_data->bus_id, 1);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -321,8 +326,11 @@  static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 	/* Generic McBSP register settings */
 	regs->spcr2	|= XINTM(3) | FREE;
 	regs->spcr1	|= RINTM(3);
-	regs->rcr2	|= RFIG;
-	regs->xcr2	|= XFIG;
+	/* RFIG and XFIG are not defined in 34xx */
+	if (!cpu_is_omap34xx()) {
+		regs->rcr2	|= RFIG;
+		regs->xcr2	|= XFIG;
+	}
 	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 		regs->xccr = DXENDLY(1) | XDMAEN;
 		regs->rccr = RFULL_CYCLE | RDMAEN;
@@ -333,11 +341,15 @@  static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		/* 1-bit data delay */
 		regs->rcr2	|= RDATDLY(1);
 		regs->xcr2	|= XDATDLY(1);
+		regs->rccr	|= RFULL_CYCLE | RDMAEN | RDISABLE;
+		regs->xccr	|= (DXENDLY(1) | XDMAEN | XDISABLE);
 		break;
 	case SND_SOC_DAIFMT_DSP_A:
 		/* 1-bit data delay */
 		regs->rcr2      |= RDATDLY(1);
 		regs->xcr2      |= XDATDLY(1);
+		regs->rccr	|= RFULL_CYCLE | RDMAEN | RDISABLE;
+		regs->xccr	|= (DXENDLY(1) | XDMAEN | XDISABLE);
 		/* Invert FS polarity configuration */
 		temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
 		break;