aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_realtek.c222
1 files changed, 49 insertions, 173 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a97e46027412..b76d3b3fb63c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -390,7 +390,6 @@ struct alc_spec {
390 void (*shutup)(struct hda_codec *codec); 390 void (*shutup)(struct hda_codec *codec);
391 391
392 /* for pin sensing */ 392 /* for pin sensing */
393 unsigned int sense_updated: 1;
394 unsigned int jack_present: 1; 393 unsigned int jack_present: 1;
395 unsigned int line_jack_present:1; 394 unsigned int line_jack_present:1;
396 unsigned int master_mute:1; 395 unsigned int master_mute:1;
@@ -11797,40 +11796,15 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = {
11797 }, 11796 },
11798}; 11797};
11799 11798
11800/* mute/unmute internal speaker according to the hp jacks and mute state */ 11799static void alc262_fujitsu_setup(struct hda_codec *codec)
11801static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11802{ 11800{
11803 struct alc_spec *spec = codec->spec; 11801 struct alc_spec *spec = codec->spec;
11804 unsigned int mute;
11805
11806 if (force || !spec->sense_updated) {
11807 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11808 snd_hda_jack_detect(codec, 0x1b);
11809 spec->sense_updated = 1;
11810 }
11811 /* unmute internal speaker only if both HPs are unplugged and
11812 * master switch is on
11813 */
11814 if (spec->jack_present)
11815 mute = HDA_AMP_MUTE;
11816 else
11817 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11818 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11819 HDA_AMP_MUTE, mute);
11820}
11821
11822/* unsolicited event for HP jack sensing */
11823static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11824 unsigned int res)
11825{
11826 if ((res >> 26) != ALC_HP_EVENT)
11827 return;
11828 alc262_fujitsu_automute(codec, 1);
11829}
11830 11802
11831static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11803 spec->autocfg.hp_pins[0] = 0x14;
11832{ 11804 spec->autocfg.hp_pins[1] = 0x1b;
11833 alc262_fujitsu_automute(codec, 1); 11805 spec->autocfg.speaker_pins[0] = 0x15;
11806 spec->automute = 1;
11807 spec->automute_mode = ALC_AUTOMUTE_AMP;
11834} 11808}
11835 11809
11836/* bind volumes of both NID 0x0c and 0x0d */ 11810/* bind volumes of both NID 0x0c and 0x0d */
@@ -11843,78 +11817,15 @@ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11843 }, 11817 },
11844}; 11818};
11845 11819
11846/* mute/unmute internal speaker according to the hp jack and mute state */
11847static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11848{
11849 struct alc_spec *spec = codec->spec;
11850 unsigned int mute;
11851
11852 if (force || !spec->sense_updated) {
11853 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11854 spec->sense_updated = 1;
11855 }
11856 if (spec->jack_present) {
11857 /* mute internal speaker */
11858 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11859 HDA_AMP_MUTE, HDA_AMP_MUTE);
11860 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11861 HDA_AMP_MUTE, HDA_AMP_MUTE);
11862 } else {
11863 /* unmute internal speaker if necessary */
11864 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11865 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11866 HDA_AMP_MUTE, mute);
11867 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11868 HDA_AMP_MUTE, mute);
11869 }
11870}
11871
11872/* unsolicited event for HP jack sensing */
11873static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11874 unsigned int res)
11875{
11876 if ((res >> 26) != ALC_HP_EVENT)
11877 return;
11878 alc262_lenovo_3000_automute(codec, 1);
11879}
11880
11881static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11882 int dir, int idx, long *valp)
11883{
11884 int i, change = 0;
11885
11886 for (i = 0; i < 2; i++, valp++)
11887 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11888 HDA_AMP_MUTE,
11889 *valp ? 0 : HDA_AMP_MUTE);
11890 return change;
11891}
11892
11893/* bind hp and internal speaker mute (with plug check) */
11894static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11895 struct snd_ctl_elem_value *ucontrol)
11896{
11897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11898 long *valp = ucontrol->value.integer.value;
11899 int change;
11900
11901 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11902 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11903 if (change)
11904 alc262_fujitsu_automute(codec, 0);
11905 return change;
11906}
11907
11908static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11820static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11909 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11821 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11910 { 11822 {
11911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11912 .name = "Master Playback Switch", 11824 .name = "Master Playback Switch",
11913 .subdevice = HDA_SUBDEV_AMP_FLAG, 11825 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11914 .info = snd_hda_mixer_amp_switch_info, 11826 .info = snd_ctl_boolean_mono_info,
11915 .get = snd_hda_mixer_amp_switch_get, 11827 .get = alc262_hp_master_sw_get,
11916 .put = alc262_fujitsu_master_sw_put, 11828 .put = alc262_hp_master_sw_put,
11917 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11918 }, 11829 },
11919 { 11830 {
11920 .iface = NID_MAPPING, 11831 .iface = NID_MAPPING,
@@ -11932,18 +11843,15 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11932 { } /* end */ 11843 { } /* end */
11933}; 11844};
11934 11845
11935/* bind hp and internal speaker mute (with plug check) */ 11846static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11936static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11937 struct snd_ctl_elem_value *ucontrol)
11938{ 11847{
11939 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11848 struct alc_spec *spec = codec->spec;
11940 long *valp = ucontrol->value.integer.value;
11941 int change;
11942 11849
11943 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11850 spec->autocfg.hp_pins[0] = 0x1b;
11944 if (change) 11851 spec->autocfg.speaker_pins[0] = 0x14;
11945 alc262_lenovo_3000_automute(codec, 0); 11852 spec->autocfg.speaker_pins[1] = 0x16;
11946 return change; 11853 spec->automute = 1;
11854 spec->automute_mode = ALC_AUTOMUTE_AMP;
11947} 11855}
11948 11856
11949static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11857static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
@@ -11951,11 +11859,10 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11951 { 11859 {
11952 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11953 .name = "Master Playback Switch", 11861 .name = "Master Playback Switch",
11954 .subdevice = HDA_SUBDEV_AMP_FLAG, 11862 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11955 .info = snd_hda_mixer_amp_switch_info, 11863 .info = snd_ctl_boolean_mono_info,
11956 .get = snd_hda_mixer_amp_switch_get, 11864 .get = alc262_hp_master_sw_get,
11957 .put = alc262_lenovo_3000_master_sw_put, 11865 .put = alc262_hp_master_sw_put,
11958 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11959 }, 11866 },
11960 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11867 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11961 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11868 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -12734,8 +12641,9 @@ static struct alc_config_preset alc262_presets[] = {
12734 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12641 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12735 .channel_mode = alc262_modes, 12642 .channel_mode = alc262_modes,
12736 .input_mux = &alc262_fujitsu_capture_source, 12643 .input_mux = &alc262_fujitsu_capture_source,
12737 .unsol_event = alc262_fujitsu_unsol_event, 12644 .unsol_event = alc_sku_unsol_event,
12738 .init_hook = alc262_fujitsu_init_hook, 12645 .setup = alc262_fujitsu_setup,
12646 .init_hook = alc_inithook,
12739 }, 12647 },
12740 [ALC262_HP_BPC] = { 12648 [ALC262_HP_BPC] = {
12741 .mixers = { alc262_HP_BPC_mixer }, 12649 .mixers = { alc262_HP_BPC_mixer },
@@ -12863,7 +12771,9 @@ static struct alc_config_preset alc262_presets[] = {
12863 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12771 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12864 .channel_mode = alc262_modes, 12772 .channel_mode = alc262_modes,
12865 .input_mux = &alc262_fujitsu_capture_source, 12773 .input_mux = &alc262_fujitsu_capture_source,
12866 .unsol_event = alc262_lenovo_3000_unsol_event, 12774 .unsol_event = alc_sku_unsol_event,
12775 .setup = alc262_lenovo_3000_setup,
12776 .init_hook = alc_inithook,
12867 }, 12777 },
12868 [ALC262_NEC] = { 12778 [ALC262_NEC] = {
12869 .mixers = { alc262_nec_mixer }, 12779 .mixers = { alc262_nec_mixer },
@@ -13133,38 +13043,18 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13133 }, 13043 },
13134}; 13044};
13135 13045
13136/* mute/unmute internal speaker according to the hp jack and mute state */ 13046static void alc268_acer_setup(struct hda_codec *codec)
13137static void alc268_acer_automute(struct hda_codec *codec, int force)
13138{ 13047{
13139 struct alc_spec *spec = codec->spec; 13048 struct alc_spec *spec = codec->spec;
13140 unsigned int mute;
13141 13049
13142 if (force || !spec->sense_updated) { 13050 spec->autocfg.hp_pins[0] = 0x14;
13143 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 13051 spec->autocfg.speaker_pins[0] = 0x15;
13144 spec->sense_updated = 1; 13052 spec->automute = 1;
13145 } 13053 spec->automute_mode = ALC_AUTOMUTE_AMP;
13146 if (spec->jack_present)
13147 mute = HDA_AMP_MUTE; /* mute internal speaker */
13148 else /* unmute internal speaker if necessary */
13149 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13150 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13151 HDA_AMP_MUTE, mute);
13152} 13054}
13153 13055
13154 13056#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13155/* bind hp and internal speaker mute (with plug check) */ 13057#define alc268_acer_master_sw_put alc262_hp_master_sw_put
13156static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13157 struct snd_ctl_elem_value *ucontrol)
13158{
13159 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13160 long *valp = ucontrol->value.integer.value;
13161 int change;
13162
13163 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13164 if (change)
13165 alc268_acer_automute(codec, 0);
13166 return change;
13167}
13168 13058
13169static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 13059static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13170 /* output mixer control */ 13060 /* output mixer control */
@@ -13172,11 +13062,10 @@ static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13172 { 13062 {
13173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13063 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13174 .name = "Master Playback Switch", 13064 .name = "Master Playback Switch",
13175 .subdevice = HDA_SUBDEV_AMP_FLAG, 13065 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13176 .info = snd_hda_mixer_amp_switch_info, 13066 .info = snd_ctl_boolean_mono_info,
13177 .get = snd_hda_mixer_amp_switch_get, 13067 .get = alc268_acer_master_sw_get,
13178 .put = alc268_acer_master_sw_put, 13068 .put = alc268_acer_master_sw_put,
13179 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13180 }, 13069 },
13181 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13070 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13182 { } 13071 { }
@@ -13188,11 +13077,10 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
13188 { 13077 {
13189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13078 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13190 .name = "Master Playback Switch", 13079 .name = "Master Playback Switch",
13191 .subdevice = HDA_SUBDEV_AMP_FLAG, 13080 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13192 .info = snd_hda_mixer_amp_switch_info, 13081 .info = snd_ctl_boolean_mono_info,
13193 .get = snd_hda_mixer_amp_switch_get, 13082 .get = alc268_acer_master_sw_get,
13194 .put = alc268_acer_master_sw_put, 13083 .put = alc268_acer_master_sw_put,
13195 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13196 }, 13084 },
13197 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13085 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13198 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13086 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
@@ -13206,11 +13094,10 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13206 { 13094 {
13207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13208 .name = "Master Playback Switch", 13096 .name = "Master Playback Switch",
13209 .subdevice = HDA_SUBDEV_AMP_FLAG, 13097 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13210 .info = snd_hda_mixer_amp_switch_info, 13098 .info = snd_ctl_boolean_mono_info,
13211 .get = snd_hda_mixer_amp_switch_get, 13099 .get = alc268_acer_master_sw_get,
13212 .put = alc268_acer_master_sw_put, 13100 .put = alc268_acer_master_sw_put,
13213 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13214 }, 13101 },
13215 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13102 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13216 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13103 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
@@ -13241,19 +13128,6 @@ static struct hda_verb alc268_acer_verbs[] = {
13241/* unsolicited event for HP jack sensing */ 13128/* unsolicited event for HP jack sensing */
13242#define alc268_toshiba_setup alc262_hippo_setup 13129#define alc268_toshiba_setup alc262_hippo_setup
13243 13130
13244static void alc268_acer_unsol_event(struct hda_codec *codec,
13245 unsigned int res)
13246{
13247 if ((res >> 26) != ALC880_HP_EVENT)
13248 return;
13249 alc268_acer_automute(codec, 1);
13250}
13251
13252static void alc268_acer_init_hook(struct hda_codec *codec)
13253{
13254 alc268_acer_automute(codec, 1);
13255}
13256
13257static void alc268_acer_lc_setup(struct hda_codec *codec) 13131static void alc268_acer_lc_setup(struct hda_codec *codec)
13258{ 13132{
13259 struct alc_spec *spec = codec->spec; 13133 struct alc_spec *spec = codec->spec;
@@ -13893,8 +13767,9 @@ static struct alc_config_preset alc268_presets[] = {
13893 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13767 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13894 .channel_mode = alc268_modes, 13768 .channel_mode = alc268_modes,
13895 .input_mux = &alc268_acer_capture_source, 13769 .input_mux = &alc268_acer_capture_source,
13896 .unsol_event = alc268_acer_unsol_event, 13770 .unsol_event = alc_sku_unsol_event,
13897 .init_hook = alc268_acer_init_hook, 13771 .setup = alc268_acer_setup,
13772 .init_hook = alc_inithook,
13898 }, 13773 },
13899 [ALC268_ACER_DMIC] = { 13774 [ALC268_ACER_DMIC] = {
13900 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13775 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
@@ -13910,8 +13785,9 @@ static struct alc_config_preset alc268_presets[] = {
13910 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13785 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13911 .channel_mode = alc268_modes, 13786 .channel_mode = alc268_modes,
13912 .input_mux = &alc268_acer_dmic_capture_source, 13787 .input_mux = &alc268_acer_dmic_capture_source,
13913 .unsol_event = alc268_acer_unsol_event, 13788 .unsol_event = alc_sku_unsol_event,
13914 .init_hook = alc268_acer_init_hook, 13789 .setup = alc268_acer_setup,
13790 .init_hook = alc_inithook,
13915 }, 13791 },
13916 [ALC268_ACER_ASPIRE_ONE] = { 13792 [ALC268_ACER_ASPIRE_ONE] = {
13917 .mixers = { alc268_acer_aspire_one_mixer, 13793 .mixers = { alc268_acer_aspire_one_mixer,