ALSA: HDA: Remove unconnected PCM devices for Intel HDMI
Some newer chips have more than one HDMI output, but usually not
all of them are exposed as physical jacks. Removing the unused
PCM devices (as indicated by BIOS in the pin config default) will
reduce user confusion as they currently have to choose between
several HDMI devices, some of them not working anyway.
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8f07719..d1b1b57 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -904,23 +904,28 @@
spec->pin[spec->num_pins] = pin_nid;
spec->num_pins++;
- /*
- * It is assumed that converter nodes come first in the node list and
- * hence have been registered and usable now.
- */
return hdmi_read_pin_conn(codec, pin_nid);
}
static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
{
+ int i, found_pin = 0;
struct hdmi_spec *spec = codec->spec;
- if (spec->num_cvts >= MAX_HDMI_CVTS) {
- snd_printk(KERN_WARNING
- "HDMI: no space for converter %d\n", nid);
- return -E2BIG;
+ for (i = 0; i < spec->num_pins; i++)
+ if (nid == spec->pin_cvt[i]) {
+ found_pin = 1;
+ break;
+ }
+
+ if (!found_pin) {
+ snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
+ return -EINVAL;
}
+ if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
+ return -E2BIG;
+
spec->cvt[spec->num_cvts] = nid;
spec->num_cvts++;
@@ -931,6 +936,8 @@
{
hda_nid_t nid;
int i, nodes;
+ int num_tmp_cvts = 0;
+ hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
if (!nid || nodes < 0) {
@@ -941,6 +948,7 @@
for (i = 0; i < nodes; i++, nid++) {
unsigned int caps;
unsigned int type;
+ unsigned int config;
caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
type = get_wcaps_type(caps);
@@ -950,17 +958,32 @@
switch (type) {
case AC_WID_AUD_OUT:
- hdmi_add_cvt(codec, nid);
+ if (num_tmp_cvts >= MAX_HDMI_CVTS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for converter %d\n", nid);
+ continue;
+ }
+ tmp_cvt[num_tmp_cvts] = nid;
+ num_tmp_cvts++;
break;
case AC_WID_PIN:
caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
continue;
+
+ config = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_CONFIG_DEFAULT, 0);
+ if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
+ continue;
+
hdmi_add_pin(codec, nid);
break;
}
}
+ for (i = 0; i < num_tmp_cvts; i++)
+ hdmi_add_cvt(codec, tmp_cvt[i]);
+
/*
* G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
* can be lost and presence sense verb will become inaccurate if the