[alsa-devel] [PATCH] ASoC: MPC5200: Support for buffer wrap around
Jon Smirl
jonsmirl at gmail.com
Sat Aug 1 15:47:36 CEST 2009
On Fri, Jul 31, 2009 at 7:08 PM, John Bonesio<bones at secretlab.ca> wrote:
> 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.
This could be something wrong in the mpc5200 code that writes the AC97
registers too. Maybe a register write command is getting generated
when it wasn't supposed to.
You can set the mpc5200 to generate an interrupt everything it
finishes writing a AC97 register. If you get more interrupts than you
expected the problem is in the driver.
> 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))
>
>
--
Jon Smirl
jonsmirl at gmail.com
More information about the Alsa-devel
mailing list