On Fri, Jul 31, 2009 at 7:08 PM, John Bonesio<bones@xxxxxxxxxxxx> 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@xxxxxxxxxxxx> > --- > > 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@xxxxxxxxx _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel