aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorMengdong Lin <mengdong.lin@intel.com>2013-09-21 20:34:45 -0400
committerTakashi Iwai <tiwai@suse.de>2013-09-26 04:22:49 -0400
commitf82d7d16aee5eb4c2315ba11a90f2f3c662d45b8 (patch)
tree545ec3a35638f3a2ebbf03b48ba0bfb379f6c793 /sound/pci
parentb26d19e44adfd10b691bf4ffd50ed411c1be9317 (diff)
ALSA : hda - not use assigned converters for all unused pins
BIOS can mark a pin as "no physical connection" if the port is used by an integrated display which is not audio capable. And audio driver will overlook such pins. On Haswell, such a disconneted pin will keep muted and connected to the 1st converter by default. But if the 1st convertor is assigned to a connected pin for audio streaming. The muted disconnected pin can make the connected pin no sound output. So this patch avoids using assigned converters for all unused pins for Haswell, including the disconected pins. Signed-off-by: Mengdong Lin <mengdong.lin@intel.com> Reviewed-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_hdmi.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 3d8cd04455a6..7ea0245fc6bd 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1149,32 +1149,43 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
1149} 1149}
1150 1150
1151static void haswell_config_cvts(struct hda_codec *codec, 1151static void haswell_config_cvts(struct hda_codec *codec,
1152 int pin_id, int mux_id) 1152 hda_nid_t pin_nid, int mux_idx)
1153{ 1153{
1154 struct hdmi_spec *spec = codec->spec; 1154 struct hdmi_spec *spec = codec->spec;
1155 struct hdmi_spec_per_pin *per_pin; 1155 hda_nid_t nid, end_nid;
1156 int pin_idx, mux_idx; 1156 int cvt_idx, curr;
1157 int curr; 1157 struct hdmi_spec_per_cvt *per_cvt;
1158 int err;
1159 1158
1160 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1159 /* configure all pins, including "no physical connection" ones */
1161 per_pin = get_pin(spec, pin_idx); 1160 end_nid = codec->start_nid + codec->num_nodes;
1161 for (nid = codec->start_nid; nid < end_nid; nid++) {
1162 unsigned int wid_caps = get_wcaps(codec, nid);
1163 unsigned int wid_type = get_wcaps_type(wid_caps);
1162 1164
1163 if (pin_idx == pin_id) 1165 if (wid_type != AC_WID_PIN)
1164 continue; 1166 continue;
1165 1167
1166 curr = snd_hda_codec_read(codec, per_pin->pin_nid, 0, 1168 if (nid == pin_nid)
1169 continue;
1170
1171 curr = snd_hda_codec_read(codec, nid, 0,
1167 AC_VERB_GET_CONNECT_SEL, 0); 1172 AC_VERB_GET_CONNECT_SEL, 0);
1173 if (curr != mux_idx)
1174 continue;
1168 1175
1169 /* Choose another unused converter */ 1176 /* choose an unassigned converter. The conveters in the
1170 if (curr == mux_id) { 1177 * connection list are in the same order as in the codec.
1171 err = hdmi_choose_cvt(codec, pin_idx, NULL, &mux_idx); 1178 */
1172 if (err < 0) 1179 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
1173 return; 1180 per_cvt = get_cvt(spec, cvt_idx);
1174 snd_printdd("HDMI: choose converter %d for pin %d\n", mux_idx, pin_idx); 1181 if (!per_cvt->assigned) {
1175 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0, 1182 snd_printdd("choose cvt %d for pin nid %d\n",
1183 cvt_idx, nid);
1184 snd_hda_codec_write_cache(codec, nid, 0,
1176 AC_VERB_SET_CONNECT_SEL, 1185 AC_VERB_SET_CONNECT_SEL,
1177 mux_idx); 1186 cvt_idx);
1187 break;
1188 }
1178 } 1189 }
1179 } 1190 }
1180} 1191}
@@ -1216,7 +1227,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1216 1227
1217 /* configure unused pins to choose other converters */ 1228 /* configure unused pins to choose other converters */
1218 if (is_haswell(codec)) 1229 if (is_haswell(codec))
1219 haswell_config_cvts(codec, pin_idx, mux_idx); 1230 haswell_config_cvts(codec, per_pin->pin_nid, mux_idx);
1220 1231
1221 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); 1232 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
1222 1233