[Intel-gfx] [PATCH V1] ALSA: hda - Avoid choose same converter for unused pins
Wang, Xingchao
xingchao.wang at intel.com
Tue Jun 18 16:16:56 CEST 2013
> -----Original Message-----
> From: Takashi Iwai [mailto:tiwai at suse.de]
> Sent: Tuesday, June 18, 2013 10:14 PM
> To: Wang Xingchao
> Cc: daniel.vetter at ffwll.ch; alsa-devel at alsa-project.org;
> intel-gfx at lists.freedesktop.org; Wang, Xingchao
> Subject: Re: [PATCH V1] ALSA: hda - Avoid choose same converter for unused
> pins
>
> At Tue, 18 Jun 2013 21:42:14 +0800,
> Wang Xingchao wrote:
> >
> > For Intel Haswell HDMI codecs, the pins choose converter 0 by default.
> > This would cause conflict when playing audio on unused pins,the pin
> > with physical device connected would get audio data too.
> > i.e. Pin 0/1/2 default choose converter 0, pin 1 has HDMI monitor connected.
> > when play audio on Pin 0 or pin 2, pin 1 could get audio data too.
> >
> > This patch configure unused pins to choose different converter.
> >
> > Signed-off-by: Wang Xingchao <xingchao.wang at linux.intel.com>
> > ---
> > sound/pci/hda/patch_hdmi.c | 91
> ++++++++++++++++++++++++++++++++++++--------
> > 1 file changed, 76 insertions(+), 15 deletions(-)
> >
> > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > index 8983747..43f8b76 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -1110,26 +1110,15 @@ static int hdmi_setup_stream(struct hda_codec
> *codec, hda_nid_t cvt_nid,
> > return 0;
> > }
> >
> > -/*
> > - * HDA PCM callbacks
> > - */
> > -static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
> > - struct hda_codec *codec,
> > - struct snd_pcm_substream *substream)
> > +static int hdmi_choose_cvt(struct hda_codec *codec,
> > + int pin_idx, int *cvt_id, int *mux_id)
> > {
> > struct hdmi_spec *spec = codec->spec;
> > - struct snd_pcm_runtime *runtime = substream->runtime;
> > - int pin_idx, cvt_idx, mux_idx = 0;
> > struct hdmi_spec_per_pin *per_pin;
> > - struct hdmi_eld *eld;
> > struct hdmi_spec_per_cvt *per_cvt = NULL;
> > + int cvt_idx, mux_idx = 0;
> >
> > - /* Validate hinfo */
> > - pin_idx = hinfo_to_pin_index(spec, hinfo);
> > - if (snd_BUG_ON(pin_idx < 0))
> > - return -EINVAL;
> > per_pin = get_pin(spec, pin_idx);
> > - eld = &per_pin->sink_eld;
> >
> > /* Dynamically assign converter to stream */
> > for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { @@ -1147,17
> > +1136,89 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
> > continue;
> > break;
> > }
> > +
> > /* No free converters */
> > if (cvt_idx == spec->num_cvts)
> > return -ENODEV;
> >
> > + if (cvt_id)
> > + *cvt_id = cvt_idx;
> > + if (mux_id)
> > + *mux_id = mux_idx;
> > +
> > + return 0;
> > +}
> > +
> > +static void haswell_config_cvts(struct hda_codec *codec,
> > + int pin_id, int mux_id)
> > +{
> > + struct hdmi_spec *spec = codec->spec;
> > + struct hdmi_spec_per_pin *per_pin;
> > + int pin_idx, mux_idx;
> > + int curr;
> > + int err;
> > +
> > + for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
> > + per_pin = get_pin(spec, pin_idx);
> > +
> > + if (pin_idx == pin_id)
> > + continue;
> > +
> > + curr = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
> > + AC_VERB_GET_CONNECT_SEL, 0);
> > +
> > + /* Choose another unused converter */
> > + if (curr == mux_id) {
> > + err = hdmi_choose_cvt(codec, pin_idx, NULL, &mux_idx);
> > + if (err < 0)
> > + return;
> > + snd_printdd("HDMI: choose converter %d for pin %d\n",
> mux_idx, pin_idx);
> > + snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
> > + AC_VERB_SET_CONNECT_SEL,
> > + mux_idx);
> > + }
> > + }
> > +}
> > +
> > +/*
> > + * HDA PCM callbacks
> > + */
> > +static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
> > + struct hda_codec *codec,
> > + struct snd_pcm_substream *substream) {
> > + struct hdmi_spec *spec = codec->spec;
> > + struct snd_pcm_runtime *runtime = substream->runtime;
> > + int pin_idx, cvt_idx, mux_idx = 0;
> > + struct hdmi_spec_per_pin *per_pin;
> > + struct hdmi_eld *eld;
> > + struct hdmi_spec_per_cvt *per_cvt = NULL;
> > + int err;
> > +
> > + /* Validate hinfo */
> > + pin_idx = hinfo_to_pin_index(spec, hinfo);
> > + if (snd_BUG_ON(pin_idx < 0))
> > + return -EINVAL;
> > + per_pin = get_pin(spec, pin_idx);
> > + eld = &per_pin->sink_eld;
> > +
> > + err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);
> > + if (err < 0)
> > + return err;
> > +
> > + per_cvt = get_cvt(spec, cvt_idx);
> > /* Claim converter */
> > per_cvt->assigned = 1;
> > hinfo->nid = per_cvt->cvt_nid;
> >
> > - snd_hda_codec_write(codec, per_pin->pin_nid, 0,
> > + snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
> > AC_VERB_SET_CONNECT_SEL,
> > mux_idx);
>
> You shouldn't mix this fix into your patch.
> This change should be applied as a separate patch and go to stable kernel.
>
> I'll cook up your patch to remove that chunk and apply the rest as is.
>
Okay, thanks a lot. :)
Thanks
--xingchao
>
> thanks,
>
> Takashi
More information about the Intel-gfx
mailing list