diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-04-28 09:46:07 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-04-28 09:46:07 -0400 |
commit | e9427969f560f664d78b2512fd8ebf44863b5072 (patch) | |
tree | cc1106381b47f4c2bdd0741f2e221484e8520a70 /sound | |
parent | e6a5e1b7094bdd5cc9ae969aff7f75fbc53517fc (diff) |
ALSA: hda - Consolidate auto-mute with master-switch for Realtek
Yet another consolidation of auto-mute functions for the devices
controlling the output muts together with the master mixer switch,
typically found for ALC262 machines.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 323 |
1 files changed, 99 insertions, 224 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 222abba98168..a97e46027412 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -393,7 +393,7 @@ struct alc_spec { | |||
393 | unsigned int sense_updated: 1; | 393 | unsigned int sense_updated: 1; |
394 | unsigned int jack_present: 1; | 394 | unsigned int jack_present: 1; |
395 | unsigned int line_jack_present:1; | 395 | unsigned int line_jack_present:1; |
396 | unsigned int master_sw: 1; | 396 | unsigned int master_mute:1; |
397 | unsigned int auto_mic:1; | 397 | unsigned int auto_mic:1; |
398 | unsigned int automute:1; /* HP automute enabled */ | 398 | unsigned int automute:1; /* HP automute enabled */ |
399 | unsigned int detect_line:1; /* Line-out detection enabled */ | 399 | unsigned int detect_line:1; /* Line-out detection enabled */ |
@@ -1092,11 +1092,11 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | |||
1092 | } | 1092 | } |
1093 | 1093 | ||
1094 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | 1094 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, |
1095 | bool mute) | 1095 | bool mute, bool hp_out) |
1096 | { | 1096 | { |
1097 | struct alc_spec *spec = codec->spec; | 1097 | struct alc_spec *spec = codec->spec; |
1098 | unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; | 1098 | unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; |
1099 | unsigned int pin_bits = mute ? 0 : PIN_OUT; | 1099 | unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); |
1100 | int i; | 1100 | int i; |
1101 | 1101 | ||
1102 | for (i = 0; i < num_pins; i++) { | 1102 | for (i = 0; i < num_pins; i++) { |
@@ -1133,14 +1133,15 @@ static void update_speakers(struct hda_codec *codec) | |||
1133 | 1133 | ||
1134 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), | 1134 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), |
1135 | spec->autocfg.speaker_pins, | 1135 | spec->autocfg.speaker_pins, |
1136 | spec->jack_present | spec->line_jack_present); | 1136 | spec->jack_present | spec->line_jack_present | |
1137 | spec->master_mute, false); | ||
1137 | 1138 | ||
1138 | /* toggle line-out mutes if needed, too */ | 1139 | /* toggle line-out mutes if needed, too */ |
1139 | if (!spec->automute_lines) | 1140 | if (!spec->automute_lines) |
1140 | return; | 1141 | return; |
1141 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | 1142 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), |
1142 | spec->autocfg.line_out_pins, | 1143 | spec->autocfg.line_out_pins, |
1143 | spec->jack_present); | 1144 | spec->jack_present | spec->master_mute, false); |
1144 | } | 1145 | } |
1145 | 1146 | ||
1146 | static void alc_hp_automute(struct hda_codec *codec) | 1147 | static void alc_hp_automute(struct hda_codec *codec) |
@@ -6010,21 +6011,14 @@ static struct snd_kcontrol_new alc260_input_mixer[] = { | |||
6010 | }; | 6011 | }; |
6011 | 6012 | ||
6012 | /* update HP, line and mono out pins according to the master switch */ | 6013 | /* update HP, line and mono out pins according to the master switch */ |
6013 | static void alc260_hp_master_update(struct hda_codec *codec, | 6014 | static void alc260_hp_master_update(struct hda_codec *codec) |
6014 | hda_nid_t hp, hda_nid_t line, | ||
6015 | hda_nid_t mono) | ||
6016 | { | 6015 | { |
6017 | struct alc_spec *spec = codec->spec; | 6016 | struct alc_spec *spec = codec->spec; |
6018 | unsigned int val = spec->master_sw ? PIN_HP : 0; | 6017 | |
6019 | /* change HP and line-out pins */ | 6018 | /* change HP pins */ |
6020 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 6019 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
6021 | val); | 6020 | spec->autocfg.hp_pins, spec->master_mute, true); |
6022 | snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 6021 | update_speakers(codec); |
6023 | val); | ||
6024 | /* mono (speaker) depending on the HP jack sense */ | ||
6025 | val = (val && !spec->jack_present) ? PIN_OUT : 0; | ||
6026 | snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6027 | val); | ||
6028 | } | 6022 | } |
6029 | 6023 | ||
6030 | static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, | 6024 | static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, |
@@ -6032,7 +6026,7 @@ static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, | |||
6032 | { | 6026 | { |
6033 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 6027 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
6034 | struct alc_spec *spec = codec->spec; | 6028 | struct alc_spec *spec = codec->spec; |
6035 | *ucontrol->value.integer.value = spec->master_sw; | 6029 | *ucontrol->value.integer.value = !spec->master_mute; |
6036 | return 0; | 6030 | return 0; |
6037 | } | 6031 | } |
6038 | 6032 | ||
@@ -6041,16 +6035,12 @@ static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
6041 | { | 6035 | { |
6042 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 6036 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
6043 | struct alc_spec *spec = codec->spec; | 6037 | struct alc_spec *spec = codec->spec; |
6044 | int val = !!*ucontrol->value.integer.value; | 6038 | int val = !*ucontrol->value.integer.value; |
6045 | hda_nid_t hp, line, mono; | ||
6046 | 6039 | ||
6047 | if (val == spec->master_sw) | 6040 | if (val == spec->master_mute) |
6048 | return 0; | 6041 | return 0; |
6049 | spec->master_sw = val; | 6042 | spec->master_mute = val; |
6050 | hp = (kcontrol->private_value >> 16) & 0xff; | 6043 | alc260_hp_master_update(codec); |
6051 | line = (kcontrol->private_value >> 8) & 0xff; | ||
6052 | mono = kcontrol->private_value & 0xff; | ||
6053 | alc260_hp_master_update(codec, hp, line, mono); | ||
6054 | return 1; | 6044 | return 1; |
6055 | } | 6045 | } |
6056 | 6046 | ||
@@ -6062,7 +6052,6 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { | |||
6062 | .info = snd_ctl_boolean_mono_info, | 6052 | .info = snd_ctl_boolean_mono_info, |
6063 | .get = alc260_hp_master_sw_get, | 6053 | .get = alc260_hp_master_sw_get, |
6064 | .put = alc260_hp_master_sw_put, | 6054 | .put = alc260_hp_master_sw_put, |
6065 | .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 | ||
6066 | }, | 6055 | }, |
6067 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6056 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
6068 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 6057 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
@@ -6079,18 +6068,15 @@ static struct hda_verb alc260_hp_unsol_verbs[] = { | |||
6079 | {}, | 6068 | {}, |
6080 | }; | 6069 | }; |
6081 | 6070 | ||
6082 | static void alc260_hp_automute(struct hda_codec *codec) | 6071 | static void alc260_hp_setup(struct hda_codec *codec) |
6083 | { | 6072 | { |
6084 | struct alc_spec *spec = codec->spec; | 6073 | struct alc_spec *spec = codec->spec; |
6085 | 6074 | ||
6086 | spec->jack_present = snd_hda_jack_detect(codec, 0x10); | 6075 | spec->autocfg.hp_pins[0] = 0x0f; |
6087 | alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); | 6076 | spec->autocfg.speaker_pins[0] = 0x10; |
6088 | } | 6077 | spec->autocfg.speaker_pins[1] = 0x11; |
6089 | 6078 | spec->automute = 1; | |
6090 | static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) | 6079 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
6091 | { | ||
6092 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6093 | alc260_hp_automute(codec); | ||
6094 | } | 6080 | } |
6095 | 6081 | ||
6096 | static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | 6082 | static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { |
@@ -6101,7 +6087,6 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | |||
6101 | .info = snd_ctl_boolean_mono_info, | 6087 | .info = snd_ctl_boolean_mono_info, |
6102 | .get = alc260_hp_master_sw_get, | 6088 | .get = alc260_hp_master_sw_get, |
6103 | .put = alc260_hp_master_sw_put, | 6089 | .put = alc260_hp_master_sw_put, |
6104 | .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 | ||
6105 | }, | 6090 | }, |
6106 | HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 6091 | HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
6107 | HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), | 6092 | HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), |
@@ -6114,6 +6099,17 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | |||
6114 | { } /* end */ | 6099 | { } /* end */ |
6115 | }; | 6100 | }; |
6116 | 6101 | ||
6102 | static void alc260_hp_3013_setup(struct hda_codec *codec) | ||
6103 | { | ||
6104 | struct alc_spec *spec = codec->spec; | ||
6105 | |||
6106 | spec->autocfg.hp_pins[0] = 0x15; | ||
6107 | spec->autocfg.speaker_pins[0] = 0x10; | ||
6108 | spec->autocfg.speaker_pins[1] = 0x11; | ||
6109 | spec->automute = 1; | ||
6110 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
6111 | } | ||
6112 | |||
6117 | static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { | 6113 | static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { |
6118 | .ops = &snd_hda_bind_vol, | 6114 | .ops = &snd_hda_bind_vol, |
6119 | .values = { | 6115 | .values = { |
@@ -6146,38 +6142,16 @@ static struct hda_verb alc260_hp_3013_unsol_verbs[] = { | |||
6146 | {}, | 6142 | {}, |
6147 | }; | 6143 | }; |
6148 | 6144 | ||
6149 | static void alc260_hp_3013_automute(struct hda_codec *codec) | 6145 | static void alc260_hp_3012_setup(struct hda_codec *codec) |
6150 | { | 6146 | { |
6151 | struct alc_spec *spec = codec->spec; | 6147 | struct alc_spec *spec = codec->spec; |
6152 | 6148 | ||
6153 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); | 6149 | spec->autocfg.hp_pins[0] = 0x10; |
6154 | alc260_hp_master_update(codec, 0x15, 0x10, 0x11); | 6150 | spec->autocfg.speaker_pins[0] = 0x0f; |
6155 | } | 6151 | spec->autocfg.speaker_pins[1] = 0x11; |
6156 | 6152 | spec->autocfg.speaker_pins[2] = 0x15; | |
6157 | static void alc260_hp_3013_unsol_event(struct hda_codec *codec, | 6153 | spec->automute = 1; |
6158 | unsigned int res) | 6154 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
6159 | { | ||
6160 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6161 | alc260_hp_3013_automute(codec); | ||
6162 | } | ||
6163 | |||
6164 | static void alc260_hp_3012_automute(struct hda_codec *codec) | ||
6165 | { | ||
6166 | unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; | ||
6167 | |||
6168 | snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6169 | bits); | ||
6170 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6171 | bits); | ||
6172 | snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6173 | bits); | ||
6174 | } | ||
6175 | |||
6176 | static void alc260_hp_3012_unsol_event(struct hda_codec *codec, | ||
6177 | unsigned int res) | ||
6178 | { | ||
6179 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6180 | alc260_hp_3012_automute(codec); | ||
6181 | } | 6155 | } |
6182 | 6156 | ||
6183 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, | 6157 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, |
@@ -7302,8 +7276,9 @@ static struct alc_config_preset alc260_presets[] = { | |||
7302 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 7276 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
7303 | .channel_mode = alc260_modes, | 7277 | .channel_mode = alc260_modes, |
7304 | .input_mux = &alc260_capture_source, | 7278 | .input_mux = &alc260_capture_source, |
7305 | .unsol_event = alc260_hp_unsol_event, | 7279 | .unsol_event = alc_sku_unsol_event, |
7306 | .init_hook = alc260_hp_automute, | 7280 | .setup = alc260_hp_setup, |
7281 | .init_hook = alc_inithook, | ||
7307 | }, | 7282 | }, |
7308 | [ALC260_HP_DC7600] = { | 7283 | [ALC260_HP_DC7600] = { |
7309 | .mixers = { alc260_hp_dc7600_mixer, | 7284 | .mixers = { alc260_hp_dc7600_mixer, |
@@ -7317,8 +7292,9 @@ static struct alc_config_preset alc260_presets[] = { | |||
7317 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 7292 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
7318 | .channel_mode = alc260_modes, | 7293 | .channel_mode = alc260_modes, |
7319 | .input_mux = &alc260_capture_source, | 7294 | .input_mux = &alc260_capture_source, |
7320 | .unsol_event = alc260_hp_3012_unsol_event, | 7295 | .unsol_event = alc_sku_unsol_event, |
7321 | .init_hook = alc260_hp_3012_automute, | 7296 | .setup = alc260_hp_3012_setup, |
7297 | .init_hook = alc_inithook, | ||
7322 | }, | 7298 | }, |
7323 | [ALC260_HP_3013] = { | 7299 | [ALC260_HP_3013] = { |
7324 | .mixers = { alc260_hp_3013_mixer, | 7300 | .mixers = { alc260_hp_3013_mixer, |
@@ -7332,8 +7308,9 @@ static struct alc_config_preset alc260_presets[] = { | |||
7332 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 7308 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
7333 | .channel_mode = alc260_modes, | 7309 | .channel_mode = alc260_modes, |
7334 | .input_mux = &alc260_capture_source, | 7310 | .input_mux = &alc260_capture_source, |
7335 | .unsol_event = alc260_hp_3013_unsol_event, | 7311 | .unsol_event = alc_sku_unsol_event, |
7336 | .init_hook = alc260_hp_3013_automute, | 7312 | .setup = alc260_hp_3013_setup, |
7313 | .init_hook = alc_inithook, | ||
7337 | }, | 7314 | }, |
7338 | [ALC260_FUJITSU_S702X] = { | 7315 | [ALC260_FUJITSU_S702X] = { |
7339 | .mixers = { alc260_fujitsu_mixer }, | 7316 | .mixers = { alc260_fujitsu_mixer }, |
@@ -11291,71 +11268,30 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
11291 | }; | 11268 | }; |
11292 | 11269 | ||
11293 | /* update HP, line and mono-out pins according to the master switch */ | 11270 | /* update HP, line and mono-out pins according to the master switch */ |
11294 | static void alc262_hp_master_update(struct hda_codec *codec) | 11271 | #define alc262_hp_master_update alc260_hp_master_update |
11295 | { | ||
11296 | struct alc_spec *spec = codec->spec; | ||
11297 | int val = spec->master_sw; | ||
11298 | |||
11299 | /* HP & line-out */ | ||
11300 | snd_hda_codec_write_cache(codec, 0x1b, 0, | ||
11301 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11302 | val ? PIN_HP : 0); | ||
11303 | snd_hda_codec_write_cache(codec, 0x15, 0, | ||
11304 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11305 | val ? PIN_HP : 0); | ||
11306 | /* mono (speaker) depending on the HP jack sense */ | ||
11307 | val = val && !spec->jack_present; | ||
11308 | snd_hda_codec_write_cache(codec, 0x16, 0, | ||
11309 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11310 | val ? PIN_OUT : 0); | ||
11311 | } | ||
11312 | 11272 | ||
11313 | static void alc262_hp_bpc_automute(struct hda_codec *codec) | 11273 | static void alc262_hp_bpc_setup(struct hda_codec *codec) |
11314 | { | 11274 | { |
11315 | struct alc_spec *spec = codec->spec; | 11275 | struct alc_spec *spec = codec->spec; |
11316 | 11276 | ||
11317 | spec->jack_present = snd_hda_jack_detect(codec, 0x1b); | 11277 | spec->autocfg.hp_pins[0] = 0x1b; |
11318 | alc262_hp_master_update(codec); | 11278 | spec->autocfg.speaker_pins[0] = 0x16; |
11319 | } | 11279 | spec->automute = 1; |
11320 | 11280 | spec->automute_mode = ALC_AUTOMUTE_PIN; | |
11321 | static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) | ||
11322 | { | ||
11323 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11324 | return; | ||
11325 | alc262_hp_bpc_automute(codec); | ||
11326 | } | 11281 | } |
11327 | 11282 | ||
11328 | static void alc262_hp_wildwest_automute(struct hda_codec *codec) | 11283 | static void alc262_hp_wildwest_setup(struct hda_codec *codec) |
11329 | { | 11284 | { |
11330 | struct alc_spec *spec = codec->spec; | 11285 | struct alc_spec *spec = codec->spec; |
11331 | 11286 | ||
11332 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); | 11287 | spec->autocfg.hp_pins[0] = 0x15; |
11333 | alc262_hp_master_update(codec); | 11288 | spec->autocfg.speaker_pins[0] = 0x16; |
11334 | } | 11289 | spec->automute = 1; |
11335 | 11290 | spec->automute_mode = ALC_AUTOMUTE_PIN; | |
11336 | static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, | ||
11337 | unsigned int res) | ||
11338 | { | ||
11339 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11340 | return; | ||
11341 | alc262_hp_wildwest_automute(codec); | ||
11342 | } | 11291 | } |
11343 | 11292 | ||
11344 | #define alc262_hp_master_sw_get alc260_hp_master_sw_get | 11293 | #define alc262_hp_master_sw_get alc260_hp_master_sw_get |
11345 | 11294 | #define alc262_hp_master_sw_put alc260_hp_master_sw_put | |
11346 | static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
11347 | struct snd_ctl_elem_value *ucontrol) | ||
11348 | { | ||
11349 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
11350 | struct alc_spec *spec = codec->spec; | ||
11351 | int val = !!*ucontrol->value.integer.value; | ||
11352 | |||
11353 | if (val == spec->master_sw) | ||
11354 | return 0; | ||
11355 | spec->master_sw = val; | ||
11356 | alc262_hp_master_update(codec); | ||
11357 | return 1; | ||
11358 | } | ||
11359 | 11295 | ||
11360 | #define ALC262_HP_MASTER_SWITCH \ | 11296 | #define ALC262_HP_MASTER_SWITCH \ |
11361 | { \ | 11297 | { \ |
@@ -11485,44 +11421,9 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = { | |||
11485 | }; | 11421 | }; |
11486 | 11422 | ||
11487 | /* bind hp and internal speaker mute (with plug check) as master switch */ | 11423 | /* bind hp and internal speaker mute (with plug check) as master switch */ |
11488 | static void alc262_hippo_master_update(struct hda_codec *codec) | 11424 | #define alc262_hippo_master_update alc262_hp_master_update |
11489 | { | ||
11490 | struct alc_spec *spec = codec->spec; | ||
11491 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
11492 | hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; | ||
11493 | hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; | ||
11494 | unsigned int mute; | ||
11495 | |||
11496 | /* HP */ | ||
11497 | mute = spec->master_sw ? 0 : HDA_AMP_MUTE; | ||
11498 | snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, | ||
11499 | HDA_AMP_MUTE, mute); | ||
11500 | /* mute internal speaker per jack sense */ | ||
11501 | if (spec->jack_present) | ||
11502 | mute = HDA_AMP_MUTE; | ||
11503 | if (line_nid) | ||
11504 | snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, | ||
11505 | HDA_AMP_MUTE, mute); | ||
11506 | if (speaker_nid && speaker_nid != line_nid) | ||
11507 | snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, | ||
11508 | HDA_AMP_MUTE, mute); | ||
11509 | } | ||
11510 | |||
11511 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get | 11425 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get |
11512 | 11426 | #define alc262_hippo_master_sw_put alc262_hp_master_sw_put | |
11513 | static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, | ||
11514 | struct snd_ctl_elem_value *ucontrol) | ||
11515 | { | ||
11516 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
11517 | struct alc_spec *spec = codec->spec; | ||
11518 | int val = !!*ucontrol->value.integer.value; | ||
11519 | |||
11520 | if (val == spec->master_sw) | ||
11521 | return 0; | ||
11522 | spec->master_sw = val; | ||
11523 | alc262_hippo_master_update(codec); | ||
11524 | return 1; | ||
11525 | } | ||
11526 | 11427 | ||
11527 | #define ALC262_HIPPO_MASTER_SWITCH \ | 11428 | #define ALC262_HIPPO_MASTER_SWITCH \ |
11528 | { \ | 11429 | { \ |
@@ -11573,28 +11474,14 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | |||
11573 | }; | 11474 | }; |
11574 | 11475 | ||
11575 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 11476 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
11576 | static void alc262_hippo_automute(struct hda_codec *codec) | ||
11577 | { | ||
11578 | struct alc_spec *spec = codec->spec; | ||
11579 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
11580 | |||
11581 | spec->jack_present = snd_hda_jack_detect(codec, hp_nid); | ||
11582 | alc262_hippo_master_update(codec); | ||
11583 | } | ||
11584 | |||
11585 | static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) | ||
11586 | { | ||
11587 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11588 | return; | ||
11589 | alc262_hippo_automute(codec); | ||
11590 | } | ||
11591 | |||
11592 | static void alc262_hippo_setup(struct hda_codec *codec) | 11477 | static void alc262_hippo_setup(struct hda_codec *codec) |
11593 | { | 11478 | { |
11594 | struct alc_spec *spec = codec->spec; | 11479 | struct alc_spec *spec = codec->spec; |
11595 | 11480 | ||
11596 | spec->autocfg.hp_pins[0] = 0x15; | 11481 | spec->autocfg.hp_pins[0] = 0x15; |
11597 | spec->autocfg.speaker_pins[0] = 0x14; | 11482 | spec->autocfg.speaker_pins[0] = 0x14; |
11483 | spec->automute = 1; | ||
11484 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
11598 | } | 11485 | } |
11599 | 11486 | ||
11600 | static void alc262_hippo1_setup(struct hda_codec *codec) | 11487 | static void alc262_hippo1_setup(struct hda_codec *codec) |
@@ -11603,6 +11490,8 @@ static void alc262_hippo1_setup(struct hda_codec *codec) | |||
11603 | 11490 | ||
11604 | spec->autocfg.hp_pins[0] = 0x1b; | 11491 | spec->autocfg.hp_pins[0] = 0x1b; |
11605 | spec->autocfg.speaker_pins[0] = 0x14; | 11492 | spec->autocfg.speaker_pins[0] = 0x14; |
11493 | spec->automute = 1; | ||
11494 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
11606 | } | 11495 | } |
11607 | 11496 | ||
11608 | 11497 | ||
@@ -12816,9 +12705,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12816 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12705 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12817 | .channel_mode = alc262_modes, | 12706 | .channel_mode = alc262_modes, |
12818 | .input_mux = &alc262_capture_source, | 12707 | .input_mux = &alc262_capture_source, |
12819 | .unsol_event = alc262_hippo_unsol_event, | 12708 | .unsol_event = alc_sku_unsol_event, |
12820 | .setup = alc262_hippo_setup, | 12709 | .setup = alc262_hippo_setup, |
12821 | .init_hook = alc262_hippo_automute, | 12710 | .init_hook = alc_inithook, |
12822 | }, | 12711 | }, |
12823 | [ALC262_HIPPO_1] = { | 12712 | [ALC262_HIPPO_1] = { |
12824 | .mixers = { alc262_hippo1_mixer }, | 12713 | .mixers = { alc262_hippo1_mixer }, |
@@ -12830,9 +12719,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12830 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12719 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12831 | .channel_mode = alc262_modes, | 12720 | .channel_mode = alc262_modes, |
12832 | .input_mux = &alc262_capture_source, | 12721 | .input_mux = &alc262_capture_source, |
12833 | .unsol_event = alc262_hippo_unsol_event, | 12722 | .unsol_event = alc_sku_unsol_event, |
12834 | .setup = alc262_hippo1_setup, | 12723 | .setup = alc262_hippo1_setup, |
12835 | .init_hook = alc262_hippo_automute, | 12724 | .init_hook = alc_inithook, |
12836 | }, | 12725 | }, |
12837 | [ALC262_FUJITSU] = { | 12726 | [ALC262_FUJITSU] = { |
12838 | .mixers = { alc262_fujitsu_mixer }, | 12727 | .mixers = { alc262_fujitsu_mixer }, |
@@ -12857,8 +12746,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12857 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12746 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12858 | .channel_mode = alc262_modes, | 12747 | .channel_mode = alc262_modes, |
12859 | .input_mux = &alc262_HP_capture_source, | 12748 | .input_mux = &alc262_HP_capture_source, |
12860 | .unsol_event = alc262_hp_bpc_unsol_event, | 12749 | .unsol_event = alc_sku_unsol_event, |
12861 | .init_hook = alc262_hp_bpc_automute, | 12750 | .setup = alc262_hp_bpc_setup, |
12751 | .init_hook = alc_inithook, | ||
12862 | }, | 12752 | }, |
12863 | [ALC262_HP_BPC_D7000_WF] = { | 12753 | [ALC262_HP_BPC_D7000_WF] = { |
12864 | .mixers = { alc262_HP_BPC_WildWest_mixer }, | 12754 | .mixers = { alc262_HP_BPC_WildWest_mixer }, |
@@ -12869,8 +12759,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12869 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12759 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12870 | .channel_mode = alc262_modes, | 12760 | .channel_mode = alc262_modes, |
12871 | .input_mux = &alc262_HP_D7000_capture_source, | 12761 | .input_mux = &alc262_HP_D7000_capture_source, |
12872 | .unsol_event = alc262_hp_wildwest_unsol_event, | 12762 | .unsol_event = alc_sku_unsol_event, |
12873 | .init_hook = alc262_hp_wildwest_automute, | 12763 | .setup = alc262_hp_wildwest_setup, |
12764 | .init_hook = alc_inithook, | ||
12874 | }, | 12765 | }, |
12875 | [ALC262_HP_BPC_D7000_WL] = { | 12766 | [ALC262_HP_BPC_D7000_WL] = { |
12876 | .mixers = { alc262_HP_BPC_WildWest_mixer, | 12767 | .mixers = { alc262_HP_BPC_WildWest_mixer, |
@@ -12882,8 +12773,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12882 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12773 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12883 | .channel_mode = alc262_modes, | 12774 | .channel_mode = alc262_modes, |
12884 | .input_mux = &alc262_HP_D7000_capture_source, | 12775 | .input_mux = &alc262_HP_D7000_capture_source, |
12885 | .unsol_event = alc262_hp_wildwest_unsol_event, | 12776 | .unsol_event = alc_sku_unsol_event, |
12886 | .init_hook = alc262_hp_wildwest_automute, | 12777 | .setup = alc262_hp_wildwest_setup, |
12778 | .init_hook = alc_inithook, | ||
12887 | }, | 12779 | }, |
12888 | [ALC262_HP_TC_T5735] = { | 12780 | [ALC262_HP_TC_T5735] = { |
12889 | .mixers = { alc262_hp_t5735_mixer }, | 12781 | .mixers = { alc262_hp_t5735_mixer }, |
@@ -12926,9 +12818,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12926 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12818 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12927 | .channel_mode = alc262_modes, | 12819 | .channel_mode = alc262_modes, |
12928 | .input_mux = &alc262_capture_source, | 12820 | .input_mux = &alc262_capture_source, |
12929 | .unsol_event = alc262_hippo_unsol_event, | 12821 | .unsol_event = alc_sku_unsol_event, |
12930 | .setup = alc262_hippo_setup, | 12822 | .setup = alc262_hippo_setup, |
12931 | .init_hook = alc262_hippo_automute, | 12823 | .init_hook = alc_inithook, |
12932 | }, | 12824 | }, |
12933 | [ALC262_BENQ_T31] = { | 12825 | [ALC262_BENQ_T31] = { |
12934 | .mixers = { alc262_benq_t31_mixer }, | 12826 | .mixers = { alc262_benq_t31_mixer }, |
@@ -12940,9 +12832,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12940 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12832 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12941 | .channel_mode = alc262_modes, | 12833 | .channel_mode = alc262_modes, |
12942 | .input_mux = &alc262_capture_source, | 12834 | .input_mux = &alc262_capture_source, |
12943 | .unsol_event = alc262_hippo_unsol_event, | 12835 | .unsol_event = alc_sku_unsol_event, |
12944 | .setup = alc262_hippo_setup, | 12836 | .setup = alc262_hippo_setup, |
12945 | .init_hook = alc262_hippo_automute, | 12837 | .init_hook = alc_inithook, |
12946 | }, | 12838 | }, |
12947 | [ALC262_ULTRA] = { | 12839 | [ALC262_ULTRA] = { |
12948 | .mixers = { alc262_ultra_mixer }, | 12840 | .mixers = { alc262_ultra_mixer }, |
@@ -13008,9 +12900,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
13008 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12900 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
13009 | .channel_mode = alc262_modes, | 12901 | .channel_mode = alc262_modes, |
13010 | .input_mux = &alc262_capture_source, | 12902 | .input_mux = &alc262_capture_source, |
13011 | .unsol_event = alc262_hippo_unsol_event, | 12903 | .unsol_event = alc_sku_unsol_event, |
13012 | .setup = alc262_hippo_setup, | 12904 | .setup = alc262_hippo_setup, |
13013 | .init_hook = alc262_hippo_automute, | 12905 | .init_hook = alc_inithook, |
13014 | }, | 12906 | }, |
13015 | [ALC262_TYAN] = { | 12907 | [ALC262_TYAN] = { |
13016 | .mixers = { alc262_tyan_mixer }, | 12908 | .mixers = { alc262_tyan_mixer }, |
@@ -13347,9 +13239,7 @@ static struct hda_verb alc268_acer_verbs[] = { | |||
13347 | }; | 13239 | }; |
13348 | 13240 | ||
13349 | /* unsolicited event for HP jack sensing */ | 13241 | /* unsolicited event for HP jack sensing */ |
13350 | #define alc268_toshiba_unsol_event alc262_hippo_unsol_event | ||
13351 | #define alc268_toshiba_setup alc262_hippo_setup | 13242 | #define alc268_toshiba_setup alc262_hippo_setup |
13352 | #define alc268_toshiba_automute alc262_hippo_automute | ||
13353 | 13243 | ||
13354 | static void alc268_acer_unsol_event(struct hda_codec *codec, | 13244 | static void alc268_acer_unsol_event(struct hda_codec *codec, |
13355 | unsigned int res) | 13245 | unsigned int res) |
@@ -13985,9 +13875,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
13985 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 13875 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
13986 | .channel_mode = alc268_modes, | 13876 | .channel_mode = alc268_modes, |
13987 | .input_mux = &alc268_capture_source, | 13877 | .input_mux = &alc268_capture_source, |
13988 | .unsol_event = alc268_toshiba_unsol_event, | 13878 | .unsol_event = alc_sku_unsol_event, |
13989 | .setup = alc268_toshiba_setup, | 13879 | .setup = alc268_toshiba_setup, |
13990 | .init_hook = alc268_toshiba_automute, | 13880 | .init_hook = alc_inithook, |
13991 | }, | 13881 | }, |
13992 | [ALC268_ACER] = { | 13882 | [ALC268_ACER] = { |
13993 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, | 13883 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, |
@@ -14073,8 +13963,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
14073 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 13963 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
14074 | .channel_mode = alc268_modes, | 13964 | .channel_mode = alc268_modes, |
14075 | .input_mux = &alc268_capture_source, | 13965 | .input_mux = &alc268_capture_source, |
13966 | .unsol_event = alc_sku_unsol_event, | ||
14076 | .setup = alc268_toshiba_setup, | 13967 | .setup = alc268_toshiba_setup, |
14077 | .init_hook = alc268_toshiba_automute, | 13968 | .init_hook = alc_inithook, |
14078 | }, | 13969 | }, |
14079 | #ifdef CONFIG_SND_DEBUG | 13970 | #ifdef CONFIG_SND_DEBUG |
14080 | [ALC268_TEST] = { | 13971 | [ALC268_TEST] = { |
@@ -18249,16 +18140,6 @@ static void alc662_lenovo_101e_setup(struct hda_codec *codec) | |||
18249 | spec->automute_mode = ALC_AUTOMUTE_AMP; | 18140 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
18250 | } | 18141 | } |
18251 | 18142 | ||
18252 | /* unsolicited event for HP jack sensing */ | ||
18253 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, | ||
18254 | unsigned int res) | ||
18255 | { | ||
18256 | if ((res >> 26) == ALC880_MIC_EVENT) | ||
18257 | alc_mic_automute(codec); | ||
18258 | else | ||
18259 | alc262_hippo_unsol_event(codec, res); | ||
18260 | } | ||
18261 | |||
18262 | static void alc662_eeepc_setup(struct hda_codec *codec) | 18143 | static void alc662_eeepc_setup(struct hda_codec *codec) |
18263 | { | 18144 | { |
18264 | struct alc_spec *spec = codec->spec; | 18145 | struct alc_spec *spec = codec->spec; |
@@ -18271,22 +18152,16 @@ static void alc662_eeepc_setup(struct hda_codec *codec) | |||
18271 | spec->auto_mic = 1; | 18152 | spec->auto_mic = 1; |
18272 | } | 18153 | } |
18273 | 18154 | ||
18274 | static void alc662_eeepc_inithook(struct hda_codec *codec) | ||
18275 | { | ||
18276 | alc262_hippo_automute(codec); | ||
18277 | alc_mic_automute(codec); | ||
18278 | } | ||
18279 | |||
18280 | static void alc662_eeepc_ep20_setup(struct hda_codec *codec) | 18155 | static void alc662_eeepc_ep20_setup(struct hda_codec *codec) |
18281 | { | 18156 | { |
18282 | struct alc_spec *spec = codec->spec; | 18157 | struct alc_spec *spec = codec->spec; |
18283 | 18158 | ||
18284 | spec->autocfg.hp_pins[0] = 0x14; | 18159 | spec->autocfg.hp_pins[0] = 0x14; |
18285 | spec->autocfg.speaker_pins[0] = 0x1b; | 18160 | spec->autocfg.speaker_pins[0] = 0x1b; |
18161 | spec->automute = 1; | ||
18162 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
18286 | } | 18163 | } |
18287 | 18164 | ||
18288 | #define alc662_eeepc_ep20_inithook alc262_hippo_master_update | ||
18289 | |||
18290 | static void alc663_m51va_setup(struct hda_codec *codec) | 18165 | static void alc663_m51va_setup(struct hda_codec *codec) |
18291 | { | 18166 | { |
18292 | struct alc_spec *spec = codec->spec; | 18167 | struct alc_spec *spec = codec->spec; |
@@ -18675,9 +18550,9 @@ static struct alc_config_preset alc662_presets[] = { | |||
18675 | .dac_nids = alc662_dac_nids, | 18550 | .dac_nids = alc662_dac_nids, |
18676 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18551 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18677 | .channel_mode = alc662_3ST_2ch_modes, | 18552 | .channel_mode = alc662_3ST_2ch_modes, |
18678 | .unsol_event = alc662_eeepc_unsol_event, | 18553 | .unsol_event = alc_sku_unsol_event, |
18679 | .setup = alc662_eeepc_setup, | 18554 | .setup = alc662_eeepc_setup, |
18680 | .init_hook = alc662_eeepc_inithook, | 18555 | .init_hook = alc_inithook, |
18681 | }, | 18556 | }, |
18682 | [ALC662_ASUS_EEEPC_EP20] = { | 18557 | [ALC662_ASUS_EEEPC_EP20] = { |
18683 | .mixers = { alc662_eeepc_ep20_mixer, | 18558 | .mixers = { alc662_eeepc_ep20_mixer, |
@@ -18690,9 +18565,9 @@ static struct alc_config_preset alc662_presets[] = { | |||
18690 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | 18565 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), |
18691 | .channel_mode = alc662_3ST_6ch_modes, | 18566 | .channel_mode = alc662_3ST_6ch_modes, |
18692 | .input_mux = &alc662_lenovo_101e_capture_source, | 18567 | .input_mux = &alc662_lenovo_101e_capture_source, |
18693 | .unsol_event = alc662_eeepc_unsol_event, | 18568 | .unsol_event = alc_sku_unsol_event, |
18694 | .setup = alc662_eeepc_ep20_setup, | 18569 | .setup = alc662_eeepc_ep20_setup, |
18695 | .init_hook = alc662_eeepc_ep20_inithook, | 18570 | .init_hook = alc_inithook, |
18696 | }, | 18571 | }, |
18697 | [ALC662_ECS] = { | 18572 | [ALC662_ECS] = { |
18698 | .mixers = { alc662_ecs_mixer }, | 18573 | .mixers = { alc662_ecs_mixer }, |
@@ -18703,9 +18578,9 @@ static struct alc_config_preset alc662_presets[] = { | |||
18703 | .dac_nids = alc662_dac_nids, | 18578 | .dac_nids = alc662_dac_nids, |
18704 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18579 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18705 | .channel_mode = alc662_3ST_2ch_modes, | 18580 | .channel_mode = alc662_3ST_2ch_modes, |
18706 | .unsol_event = alc662_eeepc_unsol_event, | 18581 | .unsol_event = alc_sku_unsol_event, |
18707 | .setup = alc662_eeepc_setup, | 18582 | .setup = alc662_eeepc_setup, |
18708 | .init_hook = alc662_eeepc_inithook, | 18583 | .init_hook = alc_inithook, |
18709 | }, | 18584 | }, |
18710 | [ALC663_ASUS_M51VA] = { | 18585 | [ALC663_ASUS_M51VA] = { |
18711 | .mixers = { alc663_m51va_mixer }, | 18586 | .mixers = { alc663_m51va_mixer }, |