[alsa-devel] [PATCH] ASoC: MPC5200: Support for buffer wrap around

John Bonesio bones at secretlab.ca
Sat Aug 1 01:08:55 CEST 2009

We've encountered strange behavior in the alsamixer settings using the wm9712
codec. If we unmute the headphone output and then unmute the PCM output, the
headphone output gets reset to mute in the hardware register. At this point
the hardware register does not match the value in the register cache.

I've spent some time debugging this, and the headphone setting is set outside
of any code path that would call the ac97_write() routine. As best as I can
tell, there is something strange going on in hardware.

I've provided this patch that works around the problem.

Have any of you seen this before? Is this patch the right approach?

- John

The code in psc_dma_bcom_enqueue_tx() didn't account for the fact that
s->runtime->control->appl_ptr can wrap around to the beginning of the
buffer. This change fixes this problem.

Signed-off-by: John Bonesio <bones at secretlab.ca>

 sound/soc/fsl/mpc5200_dma.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index cfe0ea4..2551c58 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -70,6 +70,23 @@ static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
 static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s)
+	if (s->appl_ptr > s->runtime->control->appl_ptr) {
+		/*
+		 * In this case s->runtime->control->appl_ptr has wrapped around.
+		 * Play the data to the end of the boundary, then wrap our own
+		 * appl_ptr back around.
+		 */
+		while (s->appl_ptr < s->runtime->boundary) {
+			if (bcom_queue_full(s->bcom_task))
+				return;
+			s->appl_ptr += s->period_size;
+			psc_dma_bcom_enqueue_next_buffer(s);
+		}
+		s->appl_ptr -= s->runtime->boundary;
+	}
 	while (s->appl_ptr < s->runtime->control->appl_ptr) {
 		if (bcom_queue_full(s->bcom_task))

More information about the Alsa-devel mailing list