diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 92 |
1 files changed, 50 insertions, 42 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 81e4b1d957c5..ee59df7a41f8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -990,25 +990,46 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
990 | alc_fix_pll(codec); | 990 | alc_fix_pll(codec); |
991 | } | 991 | } |
992 | 992 | ||
993 | static void alc_automute_pin(struct hda_codec *codec) | 993 | static void alc_automute_speaker(struct hda_codec *codec, int pinctl) |
994 | { | 994 | { |
995 | struct alc_spec *spec = codec->spec; | 995 | struct alc_spec *spec = codec->spec; |
996 | unsigned int nid = spec->autocfg.hp_pins[0]; | 996 | unsigned int mute; |
997 | hda_nid_t nid; | ||
997 | int i; | 998 | int i; |
998 | 999 | ||
999 | if (!nid) | 1000 | spec->jack_present = 0; |
1000 | return; | 1001 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { |
1001 | spec->jack_present = snd_hda_jack_detect(codec, nid); | 1002 | nid = spec->autocfg.hp_pins[i]; |
1003 | if (!nid) | ||
1004 | break; | ||
1005 | if (snd_hda_jack_detect(codec, nid)) { | ||
1006 | spec->jack_present = 1; | ||
1007 | break; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | ||
1012 | /* Toggle internal speakers muting */ | ||
1002 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | 1013 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { |
1003 | nid = spec->autocfg.speaker_pins[i]; | 1014 | nid = spec->autocfg.speaker_pins[i]; |
1004 | if (!nid) | 1015 | if (!nid) |
1005 | break; | 1016 | break; |
1006 | snd_hda_codec_write(codec, nid, 0, | 1017 | if (pinctl) { |
1018 | snd_hda_codec_write(codec, nid, 0, | ||
1007 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1019 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1008 | spec->jack_present ? 0 : PIN_OUT); | 1020 | spec->jack_present ? 0 : PIN_OUT); |
1021 | } else { | ||
1022 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
1023 | HDA_AMP_MUTE, mute); | ||
1024 | } | ||
1009 | } | 1025 | } |
1010 | } | 1026 | } |
1011 | 1027 | ||
1028 | static void alc_automute_pin(struct hda_codec *codec) | ||
1029 | { | ||
1030 | alc_automute_speaker(codec, 1); | ||
1031 | } | ||
1032 | |||
1012 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | 1033 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
1013 | hda_nid_t nid) | 1034 | hda_nid_t nid) |
1014 | { | 1035 | { |
@@ -1236,24 +1257,35 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1236 | static void alc_init_auto_hp(struct hda_codec *codec) | 1257 | static void alc_init_auto_hp(struct hda_codec *codec) |
1237 | { | 1258 | { |
1238 | struct alc_spec *spec = codec->spec; | 1259 | struct alc_spec *spec = codec->spec; |
1260 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
1261 | int i; | ||
1239 | 1262 | ||
1240 | if (!spec->autocfg.hp_pins[0]) | 1263 | if (!cfg->hp_pins[0]) { |
1241 | return; | 1264 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
1265 | return; | ||
1266 | } | ||
1242 | 1267 | ||
1243 | if (!spec->autocfg.speaker_pins[0]) { | 1268 | if (!cfg->speaker_pins[0]) { |
1244 | if (spec->autocfg.line_out_pins[0] && | 1269 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) |
1245 | spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
1246 | spec->autocfg.speaker_pins[0] = | ||
1247 | spec->autocfg.line_out_pins[0]; | ||
1248 | else | ||
1249 | return; | 1270 | return; |
1271 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
1272 | sizeof(cfg->speaker_pins)); | ||
1273 | cfg->speaker_outs = cfg->line_outs; | ||
1274 | } | ||
1275 | |||
1276 | if (!cfg->hp_pins[0]) { | ||
1277 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
1278 | sizeof(cfg->hp_pins)); | ||
1279 | cfg->hp_outs = cfg->line_outs; | ||
1250 | } | 1280 | } |
1251 | 1281 | ||
1252 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | 1282 | for (i = 0; i < cfg->hp_outs; i++) { |
1253 | spec->autocfg.hp_pins[0]); | 1283 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", |
1254 | snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, | 1284 | cfg->hp_pins[i]); |
1285 | snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, | ||
1255 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1286 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1256 | AC_USRSP_EN | ALC880_HP_EVENT); | 1287 | AC_USRSP_EN | ALC880_HP_EVENT); |
1288 | } | ||
1257 | spec->unsol_event = alc_sku_unsol_event; | 1289 | spec->unsol_event = alc_sku_unsol_event; |
1258 | } | 1290 | } |
1259 | 1291 | ||
@@ -1711,31 +1743,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1711 | 1743 | ||
1712 | static void alc_automute_amp(struct hda_codec *codec) | 1744 | static void alc_automute_amp(struct hda_codec *codec) |
1713 | { | 1745 | { |
1714 | struct alc_spec *spec = codec->spec; | 1746 | alc_automute_speaker(codec, 0); |
1715 | unsigned int mute; | ||
1716 | hda_nid_t nid; | ||
1717 | int i; | ||
1718 | |||
1719 | spec->jack_present = 0; | ||
1720 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { | ||
1721 | nid = spec->autocfg.hp_pins[i]; | ||
1722 | if (!nid) | ||
1723 | break; | ||
1724 | if (snd_hda_jack_detect(codec, nid)) { | ||
1725 | spec->jack_present = 1; | ||
1726 | break; | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1730 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | ||
1731 | /* Toggle internal speakers muting */ | ||
1732 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | ||
1733 | nid = spec->autocfg.speaker_pins[i]; | ||
1734 | if (!nid) | ||
1735 | break; | ||
1736 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
1737 | HDA_AMP_MUTE, mute); | ||
1738 | } | ||
1739 | } | 1747 | } |
1740 | 1748 | ||
1741 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, | 1749 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, |