aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-05-08 08:11:43 -0400
committerTakashi Iwai <tiwai@suse.de>2009-05-08 08:28:35 -0400
commit42171c17f267d7fdc5167ad7b6b5fb9edfd04186 (patch)
treef83576bd2f2c95aca859ad3524179884f7f2aac8 /sound
parent41d5545d23d2ccf4d34725094dccebd37f15c1c4 (diff)
ALSA: hda - Fix and clean up hippo-compat HP auto-muting
The speaker auto-muting per HP plugging for ALC262 HIPPO and compatible devices is slightly buggy as the "Master" or "Front" mixer control can still toggle the speaker output even if the headphone is plugged. This patch fixes the issue, and clean up the hippo-related codes together with fixes of some inconsistent mixer names. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_realtek.c372
1 files changed, 158 insertions, 214 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b9495342c921..8b242c9da4dd 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -9534,24 +9534,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
9534 { } /* end */ 9534 { } /* end */
9535}; 9535};
9536 9536
9537static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9538 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9539 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9540 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9541 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9546 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9547 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9548 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9549 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9550 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9551 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9552 { } /* end */
9553};
9554
9555/* update HP, line and mono-out pins according to the master switch */ 9537/* update HP, line and mono-out pins according to the master switch */
9556static void alc262_hp_master_update(struct hda_codec *codec) 9538static void alc262_hp_master_update(struct hda_codec *codec)
9557{ 9539{
@@ -9772,46 +9754,132 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9772 }, 9754 },
9773}; 9755};
9774 9756
9775/* bind hp and internal speaker mute (with plug check) */ 9757/* bind hp and internal speaker mute (with plug check) as master switch */
9776static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 9758static void alc262_hippo_master_update(struct hda_codec *codec)
9777 struct snd_ctl_elem_value *ucontrol)
9778{ 9759{
9779 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 9760 struct alc_spec *spec = codec->spec;
9780 long *valp = ucontrol->value.integer.value; 9761 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9781 int change; 9762 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9763 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9764 unsigned int mute;
9782 9765
9783 /* change hp mute */ 9766 /* HP */
9784 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, 9767 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9785 HDA_AMP_MUTE, 9768 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9786 valp[0] ? 0 : HDA_AMP_MUTE); 9769 HDA_AMP_MUTE, mute);
9787 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, 9770 /* mute internal speaker per jack sense */
9788 HDA_AMP_MUTE, 9771 if (spec->jack_present)
9789 valp[1] ? 0 : HDA_AMP_MUTE); 9772 mute = HDA_AMP_MUTE;
9790 if (change) { 9773 if (line_nid)
9791 /* change speaker according to HP jack state */ 9774 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9792 struct alc_spec *spec = codec->spec; 9775 HDA_AMP_MUTE, mute);
9793 unsigned int mute; 9776 if (speaker_nid && speaker_nid != line_nid)
9794 if (spec->jack_present) 9777 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
9795 mute = HDA_AMP_MUTE;
9796 else
9797 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9798 HDA_OUTPUT, 0);
9799 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9800 HDA_AMP_MUTE, mute); 9778 HDA_AMP_MUTE, mute);
9779}
9780
9781#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9782
9783static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9784 struct snd_ctl_elem_value *ucontrol)
9785{
9786 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9787 struct alc_spec *spec = codec->spec;
9788 int val = !!*ucontrol->value.integer.value;
9789
9790 if (val == spec->master_sw)
9791 return 0;
9792 spec->master_sw = val;
9793 alc262_hippo_master_update(codec);
9794 return 1;
9795}
9796
9797#define ALC262_HIPPO_MASTER_SWITCH \
9798 { \
9799 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9800 .name = "Master Playback Switch", \
9801 .info = snd_ctl_boolean_mono_info, \
9802 .get = alc262_hippo_master_sw_get, \
9803 .put = alc262_hippo_master_sw_put, \
9801 } 9804 }
9802 return change; 9805
9806static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9807 ALC262_HIPPO_MASTER_SWITCH,
9808 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9809 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9810 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9811 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9812 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9815 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9816 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9817 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9818 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9819 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9820 { } /* end */
9821};
9822
9823static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9824 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9825 ALC262_HIPPO_MASTER_SWITCH,
9826 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9827 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9828 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9829 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9831 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9833 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9834 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9835 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9836 { } /* end */
9837};
9838
9839/* mute/unmute internal speaker according to the hp jack and mute state */
9840static void alc262_hippo_automute(struct hda_codec *codec)
9841{
9842 struct alc_spec *spec = codec->spec;
9843 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9844 unsigned int present;
9845
9846 /* need to execute and sync at first */
9847 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9848 present = snd_hda_codec_read(codec, hp_nid, 0,
9849 AC_VERB_GET_PIN_SENSE, 0);
9850 spec->jack_present = (present & 0x80000000) != 0;
9851 alc262_hippo_master_update(codec);
9803} 9852}
9804 9853
9854static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9855{
9856 if ((res >> 26) != ALC880_HP_EVENT)
9857 return;
9858 alc262_hippo_automute(codec);
9859}
9860
9861static void alc262_hippo_init_hook(struct hda_codec *codec)
9862{
9863 struct alc_spec *spec = codec->spec;
9864
9865 spec->autocfg.hp_pins[0] = 0x15;
9866 spec->autocfg.speaker_pins[0] = 0x14;
9867 alc262_hippo_automute(codec);
9868}
9869
9870static void alc262_hippo1_init_hook(struct hda_codec *codec)
9871{
9872 struct alc_spec *spec = codec->spec;
9873
9874 spec->autocfg.hp_pins[0] = 0x1b;
9875 spec->autocfg.speaker_pins[0] = 0x14;
9876 alc262_hippo_automute(codec);
9877}
9878
9879
9805static struct snd_kcontrol_new alc262_sony_mixer[] = { 9880static struct snd_kcontrol_new alc262_sony_mixer[] = {
9806 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9881 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9807 { 9882 ALC262_HIPPO_MASTER_SWITCH,
9808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9809 .name = "Master Playback Switch",
9810 .info = snd_hda_mixer_amp_switch_info,
9811 .get = snd_hda_mixer_amp_switch_get,
9812 .put = alc262_sony_master_sw_put,
9813 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9814 },
9815 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9817 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 9885 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
@@ -9820,8 +9888,8 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {
9820}; 9888};
9821 9889
9822static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 9890static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9823 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9891 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9824 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9892 ALC262_HIPPO_MASTER_SWITCH,
9825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9894 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9895 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
@@ -10076,69 +10144,6 @@ static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10076 alc262_dmic_automute(codec); 10144 alc262_dmic_automute(codec);
10077} 10145}
10078 10146
10079/* mute/unmute internal speaker according to the hp jack and mute state */
10080static void alc262_hippo_automute(struct hda_codec *codec)
10081{
10082 struct alc_spec *spec = codec->spec;
10083 unsigned int mute;
10084 unsigned int present;
10085
10086 /* need to execute and sync at first */
10087 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10088 present = snd_hda_codec_read(codec, 0x15, 0,
10089 AC_VERB_GET_PIN_SENSE, 0);
10090 spec->jack_present = (present & 0x80000000) != 0;
10091 if (spec->jack_present) {
10092 /* mute internal speaker */
10093 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10094 HDA_AMP_MUTE, HDA_AMP_MUTE);
10095 } else {
10096 /* unmute internal speaker if necessary */
10097 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10098 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10099 HDA_AMP_MUTE, mute);
10100 }
10101}
10102
10103/* unsolicited event for HP jack sensing */
10104static void alc262_hippo_unsol_event(struct hda_codec *codec,
10105 unsigned int res)
10106{
10107 if ((res >> 26) != ALC880_HP_EVENT)
10108 return;
10109 alc262_hippo_automute(codec);
10110}
10111
10112static void alc262_hippo1_automute(struct hda_codec *codec)
10113{
10114 unsigned int mute;
10115 unsigned int present;
10116
10117 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10118 present = snd_hda_codec_read(codec, 0x1b, 0,
10119 AC_VERB_GET_PIN_SENSE, 0);
10120 present = (present & 0x80000000) != 0;
10121 if (present) {
10122 /* mute internal speaker */
10123 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10124 HDA_AMP_MUTE, HDA_AMP_MUTE);
10125 } else {
10126 /* unmute internal speaker if necessary */
10127 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10128 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10129 HDA_AMP_MUTE, mute);
10130 }
10131}
10132
10133/* unsolicited event for HP jack sensing */
10134static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10135 unsigned int res)
10136{
10137 if ((res >> 26) != ALC880_HP_EVENT)
10138 return;
10139 alc262_hippo1_automute(codec);
10140}
10141
10142/* 10147/*
10143 * nec model 10148 * nec model
10144 * 0x15 = headphone 10149 * 0x15 = headphone
@@ -10406,14 +10411,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10406 10411
10407static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 10412static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10408 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 10413 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10409 { 10414 ALC262_HIPPO_MASTER_SWITCH,
10410 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10411 .name = "Master Playback Switch",
10412 .info = snd_hda_mixer_amp_switch_info,
10413 .get = snd_hda_mixer_amp_switch_get,
10414 .put = alc262_sony_master_sw_put,
10415 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10416 },
10417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10415 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10418 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10416 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10419 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10417 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@ -11068,7 +11066,7 @@ static struct alc_config_preset alc262_presets[] = {
11068 .input_mux = &alc262_capture_source, 11066 .input_mux = &alc262_capture_source,
11069 }, 11067 },
11070 [ALC262_HIPPO] = { 11068 [ALC262_HIPPO] = {
11071 .mixers = { alc262_base_mixer }, 11069 .mixers = { alc262_hippo_mixer },
11072 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 11070 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
11073 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11071 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11074 .dac_nids = alc262_dac_nids, 11072 .dac_nids = alc262_dac_nids,
@@ -11078,7 +11076,7 @@ static struct alc_config_preset alc262_presets[] = {
11078 .channel_mode = alc262_modes, 11076 .channel_mode = alc262_modes,
11079 .input_mux = &alc262_capture_source, 11077 .input_mux = &alc262_capture_source,
11080 .unsol_event = alc262_hippo_unsol_event, 11078 .unsol_event = alc262_hippo_unsol_event,
11081 .init_hook = alc262_hippo_automute, 11079 .init_hook = alc262_hippo_init_hook,
11082 }, 11080 },
11083 [ALC262_HIPPO_1] = { 11081 [ALC262_HIPPO_1] = {
11084 .mixers = { alc262_hippo1_mixer }, 11082 .mixers = { alc262_hippo1_mixer },
@@ -11090,8 +11088,8 @@ static struct alc_config_preset alc262_presets[] = {
11090 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11088 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11091 .channel_mode = alc262_modes, 11089 .channel_mode = alc262_modes,
11092 .input_mux = &alc262_capture_source, 11090 .input_mux = &alc262_capture_source,
11093 .unsol_event = alc262_hippo1_unsol_event, 11091 .unsol_event = alc262_hippo_unsol_event,
11094 .init_hook = alc262_hippo1_automute, 11092 .init_hook = alc262_hippo1_init_hook,
11095 }, 11093 },
11096 [ALC262_FUJITSU] = { 11094 [ALC262_FUJITSU] = {
11097 .mixers = { alc262_fujitsu_mixer }, 11095 .mixers = { alc262_fujitsu_mixer },
@@ -11185,7 +11183,7 @@ static struct alc_config_preset alc262_presets[] = {
11185 .channel_mode = alc262_modes, 11183 .channel_mode = alc262_modes,
11186 .input_mux = &alc262_capture_source, 11184 .input_mux = &alc262_capture_source,
11187 .unsol_event = alc262_hippo_unsol_event, 11185 .unsol_event = alc262_hippo_unsol_event,
11188 .init_hook = alc262_hippo_automute, 11186 .init_hook = alc262_hippo_init_hook,
11189 }, 11187 },
11190 [ALC262_BENQ_T31] = { 11188 [ALC262_BENQ_T31] = {
11191 .mixers = { alc262_benq_t31_mixer }, 11189 .mixers = { alc262_benq_t31_mixer },
@@ -11197,7 +11195,7 @@ static struct alc_config_preset alc262_presets[] = {
11197 .channel_mode = alc262_modes, 11195 .channel_mode = alc262_modes,
11198 .input_mux = &alc262_capture_source, 11196 .input_mux = &alc262_capture_source,
11199 .unsol_event = alc262_hippo_unsol_event, 11197 .unsol_event = alc262_hippo_unsol_event,
11200 .init_hook = alc262_hippo_automute, 11198 .init_hook = alc262_hippo_init_hook,
11201 }, 11199 },
11202 [ALC262_ULTRA] = { 11200 [ALC262_ULTRA] = {
11203 .mixers = { alc262_ultra_mixer }, 11201 .mixers = { alc262_ultra_mixer },
@@ -11262,7 +11260,7 @@ static struct alc_config_preset alc262_presets[] = {
11262 .channel_mode = alc262_modes, 11260 .channel_mode = alc262_modes,
11263 .input_mux = &alc262_capture_source, 11261 .input_mux = &alc262_capture_source,
11264 .unsol_event = alc262_hippo_unsol_event, 11262 .unsol_event = alc262_hippo_unsol_event,
11265 .init_hook = alc262_hippo_automute, 11263 .init_hook = alc262_hippo_init_hook,
11266 }, 11264 },
11267 [ALC262_TYAN] = { 11265 [ALC262_TYAN] = {
11268 .mixers = { alc262_tyan_mixer }, 11266 .mixers = { alc262_tyan_mixer },
@@ -11419,6 +11417,17 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
11419 { } 11417 { }
11420}; 11418};
11421 11419
11420static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11421 /* output mixer control */
11422 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11423 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11424 ALC262_HIPPO_MASTER_SWITCH,
11425 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11426 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11427 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11428 { }
11429};
11430
11422/* bind Beep switches of both NID 0x0f and 0x10 */ 11431/* bind Beep switches of both NID 0x0f and 0x10 */
11423static struct hda_bind_ctls alc268_bind_beep_sw = { 11432static struct hda_bind_ctls alc268_bind_beep_sw = {
11424 .ops = &snd_hda_bind_sw, 11433 .ops = &snd_hda_bind_sw,
@@ -11442,8 +11451,6 @@ static struct hda_verb alc268_eapd_verbs[] = {
11442}; 11451};
11443 11452
11444/* Toshiba specific */ 11453/* Toshiba specific */
11445#define alc268_toshiba_automute alc262_hippo_automute
11446
11447static struct hda_verb alc268_toshiba_verbs[] = { 11454static struct hda_verb alc268_toshiba_verbs[] = {
11448 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11449 { } /* end */ 11456 { } /* end */
@@ -11579,13 +11586,8 @@ static struct hda_verb alc268_acer_verbs[] = {
11579}; 11586};
11580 11587
11581/* unsolicited event for HP jack sensing */ 11588/* unsolicited event for HP jack sensing */
11582static void alc268_toshiba_unsol_event(struct hda_codec *codec, 11589#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11583 unsigned int res) 11590#define alc268_toshiba_init_hook alc262_hippo_init_hook
11584{
11585 if ((res >> 26) != ALC880_HP_EVENT)
11586 return;
11587 alc268_toshiba_automute(codec);
11588}
11589 11591
11590static void alc268_acer_unsol_event(struct hda_codec *codec, 11592static void alc268_acer_unsol_event(struct hda_codec *codec,
11591 unsigned int res) 11593 unsigned int res)
@@ -12230,7 +12232,7 @@ static struct alc_config_preset alc268_presets[] = {
12230 .input_mux = &alc268_capture_source, 12232 .input_mux = &alc268_capture_source,
12231 }, 12233 },
12232 [ALC268_TOSHIBA] = { 12234 [ALC268_TOSHIBA] = {
12233 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12235 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12234 alc268_beep_mixer }, 12236 alc268_beep_mixer },
12235 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12237 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12236 alc268_toshiba_verbs }, 12238 alc268_toshiba_verbs },
@@ -12244,7 +12246,7 @@ static struct alc_config_preset alc268_presets[] = {
12244 .channel_mode = alc268_modes, 12246 .channel_mode = alc268_modes,
12245 .input_mux = &alc268_capture_source, 12247 .input_mux = &alc268_capture_source,
12246 .unsol_event = alc268_toshiba_unsol_event, 12248 .unsol_event = alc268_toshiba_unsol_event,
12247 .init_hook = alc268_toshiba_automute, 12249 .init_hook = alc268_toshiba_init_hook,
12248 }, 12250 },
12249 [ALC268_ACER] = { 12251 [ALC268_ACER] = {
12250 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 12252 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
@@ -12327,7 +12329,7 @@ static struct alc_config_preset alc268_presets[] = {
12327 .channel_mode = alc268_modes, 12329 .channel_mode = alc268_modes,
12328 .input_mux = &alc268_capture_source, 12330 .input_mux = &alc268_capture_source,
12329 .unsol_event = alc268_toshiba_unsol_event, 12331 .unsol_event = alc268_toshiba_unsol_event,
12330 .init_hook = alc268_toshiba_automute 12332 .init_hook = alc268_toshiba_init_hook
12331 }, 12333 },
12332#ifdef CONFIG_SND_DEBUG 12334#ifdef CONFIG_SND_DEBUG
12333 [ALC268_TEST] = { 12335 [ALC268_TEST] = {
@@ -15552,10 +15554,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15552}; 15554};
15553 15555
15554static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 15556static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15557 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15556 15558 ALC262_HIPPO_MASTER_SWITCH,
15557 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15558 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15559 15559
15560 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 15560 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15561 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 15561 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -15568,15 +15568,11 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15568}; 15568};
15569 15569
15570static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 15570static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15571 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15571 ALC262_HIPPO_MASTER_SWITCH,
15572 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), 15572 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15573 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15573 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15574 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15575 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 15574 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15576 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 15575 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15577 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15578 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15579 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15580 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 15576 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15581 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 15577 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15582 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 15578 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
@@ -16084,51 +16080,25 @@ static void alc662_eeepc_mic_automute(struct hda_codec *codec)
16084static void alc662_eeepc_unsol_event(struct hda_codec *codec, 16080static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16085 unsigned int res) 16081 unsigned int res)
16086{ 16082{
16087 if ((res >> 26) == ALC880_HP_EVENT)
16088 alc262_hippo1_automute( codec );
16089
16090 if ((res >> 26) == ALC880_MIC_EVENT) 16083 if ((res >> 26) == ALC880_MIC_EVENT)
16091 alc662_eeepc_mic_automute(codec); 16084 alc662_eeepc_mic_automute(codec);
16085 else
16086 alc262_hippo_unsol_event(codec, res);
16092} 16087}
16093 16088
16094static void alc662_eeepc_inithook(struct hda_codec *codec) 16089static void alc662_eeepc_inithook(struct hda_codec *codec)
16095{ 16090{
16096 alc262_hippo1_automute( codec ); 16091 alc262_hippo1_init_hook(codec);
16097 alc662_eeepc_mic_automute(codec); 16092 alc662_eeepc_mic_automute(codec);
16098} 16093}
16099 16094
16100static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
16101{
16102 unsigned int mute;
16103 unsigned int present;
16104
16105 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
16106 present = snd_hda_codec_read(codec, 0x14, 0,
16107 AC_VERB_GET_PIN_SENSE, 0);
16108 present = (present & 0x80000000) != 0;
16109 if (present) {
16110 /* mute internal speaker */
16111 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
16112 HDA_AMP_MUTE, HDA_AMP_MUTE);
16113 } else {
16114 /* unmute internal speaker if necessary */
16115 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
16116 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
16117 HDA_AMP_MUTE, mute);
16118 }
16119}
16120
16121/* unsolicited event for HP jack sensing */
16122static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
16123 unsigned int res)
16124{
16125 if ((res >> 26) == ALC880_HP_EVENT)
16126 alc662_eeepc_ep20_automute(codec);
16127}
16128
16129static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) 16095static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16130{ 16096{
16131 alc662_eeepc_ep20_automute(codec); 16097 struct alc_spec *spec = codec->spec;
16098
16099 spec->autocfg.hp_pins[0] = 0x14;
16100 spec->autocfg.speaker_pins[0] = 0x1b;
16101 alc262_hippo_master_update(codec);
16132} 16102}
16133 16103
16134static void alc663_m51va_speaker_automute(struct hda_codec *codec) 16104static void alc663_m51va_speaker_automute(struct hda_codec *codec)
@@ -16462,35 +16432,9 @@ static void alc663_g50v_inithook(struct hda_codec *codec)
16462 alc662_eeepc_mic_automute(codec); 16432 alc662_eeepc_mic_automute(codec);
16463} 16433}
16464 16434
16465/* bind hp and internal speaker mute (with plug check) */
16466static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16467 struct snd_ctl_elem_value *ucontrol)
16468{
16469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16470 long *valp = ucontrol->value.integer.value;
16471 int change;
16472
16473 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16474 HDA_AMP_MUTE,
16475 valp[0] ? 0 : HDA_AMP_MUTE);
16476 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16477 HDA_AMP_MUTE,
16478 valp[1] ? 0 : HDA_AMP_MUTE);
16479 if (change)
16480 alc262_hippo1_automute(codec);
16481 return change;
16482}
16483
16484static struct snd_kcontrol_new alc662_ecs_mixer[] = { 16435static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16485 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16436 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16486 { 16437 ALC262_HIPPO_MASTER_SWITCH,
16487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16488 .name = "Master Playback Switch",
16489 .info = snd_hda_mixer_amp_switch_info,
16490 .get = snd_hda_mixer_amp_switch_get,
16491 .put = alc662_ecs_master_sw_put,
16492 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16493 },
16494 16438
16495 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 16439 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16496 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 16440 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -16682,7 +16626,7 @@ static struct alc_config_preset alc662_presets[] = {
16682 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 16626 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16683 .channel_mode = alc662_3ST_6ch_modes, 16627 .channel_mode = alc662_3ST_6ch_modes,
16684 .input_mux = &alc662_lenovo_101e_capture_source, 16628 .input_mux = &alc662_lenovo_101e_capture_source,
16685 .unsol_event = alc662_eeepc_ep20_unsol_event, 16629 .unsol_event = alc662_eeepc_unsol_event,
16686 .init_hook = alc662_eeepc_ep20_inithook, 16630 .init_hook = alc662_eeepc_ep20_inithook,
16687 }, 16631 },
16688 [ALC662_ECS] = { 16632 [ALC662_ECS] = {