On Tue, Jun 18, 2013 at 09:03:05AM +0000, Wang, Xingchao wrote:
Hi Takashi/Daniel,
This patch could be used to replace below two: http://lists.freedesktop.org/archives/intel-gfx/2013-June/029076.html http://lists.freedesktop.org/archives/intel-gfx/2013-June/029077.html
It could avoid lots of changes in gfx side. I test the patch and it could fix the same routing issues.
If this is acceptable for the alsa guys (and still works ofc) I'd very much prefer this over the older patch to disable audio on the gfx ports as the previous patch has done.
Cheers, Daniel
thanks --xingchao
-----Original Message----- From: Wang Xingchao [mailto:xingchao.wang@linux.intel.com] Sent: Tuesday, June 18, 2013 4:32 PM To: tiwai@suse.de Cc: daniel.vetter@ffwll.ch; alsa-devel@alsa-project.org; intel-gfx@lists.freedesktop.org; Wang, Xingchao; Wang Xingchao Subject: [PATCH] ALSA: hda - Avoid choose same converter for unused pins
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@linux.intel.com
sound/pci/hda/patch_hdmi.c | 89 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 14 deletions(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8983747..e887584 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,10
+1136,77 @@ 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 = -1;
- 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_printk("HDMI: choose converter %d for pin %d\n", mux_idx,
pin_idx);
- snd_hda_codec_write(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;
@@ -1158,6 +1214,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, snd_hda_codec_write(codec, per_pin->pin_nid, 0, AC_VERB_SET_CONNECT_SEL, mux_idx);
/* configure unused pins to choose other converters */
if (codec->vendor_id == 0x80862807)
haswell_config_cvts(codec, pin_idx, mux_idx);
snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
/* Initially set the converter's capabilities */
-- 1.7.9.5
-- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch