aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/hd-audio/notes.rst2
-rw-r--r--sound/pci/hda/hda_auto_parser.c1
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_generic.c9
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/patch_realtek.c72
6 files changed, 77 insertions, 9 deletions
diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst
index 9eeb9b468706..f59c3cdbfaf4 100644
--- a/Documentation/sound/hd-audio/notes.rst
+++ b/Documentation/sound/hd-audio/notes.rst
@@ -494,6 +494,8 @@ add_hp_mic (bool)
494hp_mic_detect (bool) 494hp_mic_detect (bool)
495 enable/disable the hp/mic shared input for a single built-in mic 495 enable/disable the hp/mic shared input for a single built-in mic
496 case; default true 496 case; default true
497vmaster (bool)
498 enable/disable the virtual Master control; default true
497mixer_nid (int) 499mixer_nid (int)
498 specifies the widget NID of the analog-loopback mixer 500 specifies the widget NID of the analog-loopback mixer
499 501
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index a03cf68d0bcd..d3ea73171a3d 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -580,6 +580,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
580 has_multiple_pins = 1; 580 has_multiple_pins = 1;
581 if (has_multiple_pins && type == AUTO_PIN_MIC) 581 if (has_multiple_pins && type == AUTO_PIN_MIC)
582 has_multiple_pins &= check_mic_location_need(codec, cfg, input); 582 has_multiple_pins &= check_mic_location_need(codec, cfg, input);
583 has_multiple_pins |= codec->force_pin_prefix;
583 return hda_get_input_pin_label(codec, &cfg->inputs[input], 584 return hda_get_input_pin_label(codec, &cfg->inputs[input],
584 cfg->inputs[input].pin, 585 cfg->inputs[input].pin,
585 has_multiple_pins); 586 has_multiple_pins);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f17f25245e52..d6fb2d5d01a7 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -256,6 +256,7 @@ struct hda_codec {
256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */ 256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
257 unsigned int power_save_node:1; /* advanced PM for each widget */ 257 unsigned int power_save_node:1; /* advanced PM for each widget */
258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */ 258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
259 unsigned int force_pin_prefix:1; /* Add location prefix */
259#ifdef CONFIG_PM 260#ifdef CONFIG_PM
260 unsigned long power_on_acct; 261 unsigned long power_on_acct;
261 unsigned long power_off_acct; 262 unsigned long power_off_acct;
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index e7c8f4f076d5..2842c82363c0 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -196,6 +196,9 @@ static void parse_user_hints(struct hda_codec *codec)
196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect"); 196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
197 if (val >= 0) 197 if (val >= 0)
198 spec->suppress_hp_mic_detect = !val; 198 spec->suppress_hp_mic_detect = !val;
199 val = snd_hda_get_bool_hint(codec, "vmaster");
200 if (val >= 0)
201 spec->suppress_vmaster = !val;
199 202
200 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) 203 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
201 spec->mixer_nid = val; 204 spec->mixer_nid = val;
@@ -1125,6 +1128,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
1125 1128
1126 *index = 0; 1129 *index = 0;
1127 if (cfg->line_outs == 1 && !spec->multi_ios && 1130 if (cfg->line_outs == 1 && !spec->multi_ios &&
1131 !codec->force_pin_prefix &&
1128 !cfg->hp_outs && !cfg->speaker_outs) 1132 !cfg->hp_outs && !cfg->speaker_outs)
1129 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1133 return spec->vmaster_mute.hook ? "PCM" : "Master";
1130 1134
@@ -1132,6 +1136,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
1132 * use it master (or "PCM" if a vmaster hook is present) 1136 * use it master (or "PCM" if a vmaster hook is present)
1133 */ 1137 */
1134 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid && 1138 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
1139 !codec->force_pin_prefix &&
1135 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) 1140 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
1136 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1141 return spec->vmaster_mute.hook ? "PCM" : "Master";
1137 1142
@@ -5031,7 +5036,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
5031 } 5036 }
5032 5037
5033 /* if we have no master control, let's create it */ 5038 /* if we have no master control, let's create it */
5034 if (!spec->no_analog && 5039 if (!spec->no_analog && !spec->suppress_vmaster &&
5035 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 5040 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
5036 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 5041 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
5037 spec->vmaster_tlv, slave_pfxs, 5042 spec->vmaster_tlv, slave_pfxs,
@@ -5039,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
5039 if (err < 0) 5044 if (err < 0)
5040 return err; 5045 return err;
5041 } 5046 }
5042 if (!spec->no_analog && 5047 if (!spec->no_analog && !spec->suppress_vmaster &&
5043 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 5048 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
5044 err = __snd_hda_add_vmaster(codec, "Master Playback Switch", 5049 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
5045 NULL, slave_pfxs, 5050 NULL, slave_pfxs,
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index f66fc7e25e07..61772317de46 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -229,6 +229,7 @@ struct hda_gen_spec {
229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */ 229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
230 unsigned int power_down_unused:1; /* power down unused widgets */ 230 unsigned int power_down_unused:1; /* power down unused widgets */
231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */ 231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */
232 unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
232 233
233 /* other internal flags */ 234 /* other internal flags */
234 unsigned int no_analog:1; /* digital I/O only */ 235 unsigned int no_analog:1; /* digital I/O only */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 05a26fba5ef2..93846bf65a23 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1800,6 +1800,7 @@ enum {
1800 ALC882_FIXUP_NO_PRIMARY_HP, 1800 ALC882_FIXUP_NO_PRIMARY_HP,
1801 ALC887_FIXUP_ASUS_BASS, 1801 ALC887_FIXUP_ASUS_BASS,
1802 ALC887_FIXUP_BASS_CHMAP, 1802 ALC887_FIXUP_BASS_CHMAP,
1803 ALC1220_FIXUP_GB_DUAL_CODECS,
1803}; 1804};
1804 1805
1805static void alc889_fixup_coef(struct hda_codec *codec, 1806static void alc889_fixup_coef(struct hda_codec *codec,
@@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1962static void alc_fixup_bass_chmap(struct hda_codec *codec, 1963static void alc_fixup_bass_chmap(struct hda_codec *codec,
1963 const struct hda_fixup *fix, int action); 1964 const struct hda_fixup *fix, int action);
1964 1965
1966/* For dual-codec configuration, we need to disable some features to avoid
1967 * conflicts of kctls and PCM streams
1968 */
1969static void alc_fixup_dual_codecs(struct hda_codec *codec,
1970 const struct hda_fixup *fix, int action)
1971{
1972 struct alc_spec *spec = codec->spec;
1973
1974 if (action != HDA_FIXUP_ACT_PRE_PROBE)
1975 return;
1976 /* disable vmaster */
1977 spec->gen.suppress_vmaster = 1;
1978 /* auto-mute and auto-mic switch don't work with multiple codecs */
1979 spec->gen.suppress_auto_mute = 1;
1980 spec->gen.suppress_auto_mic = 1;
1981 /* disable aamix as well */
1982 spec->gen.mixer_nid = 0;
1983 /* add location prefix to avoid conflicts */
1984 codec->force_pin_prefix = 1;
1985}
1986
1987static void rename_ctl(struct hda_codec *codec, const char *oldname,
1988 const char *newname)
1989{
1990 struct snd_kcontrol *kctl;
1991
1992 kctl = snd_hda_find_mixer_ctl(codec, oldname);
1993 if (kctl)
1994 strcpy(kctl->id.name, newname);
1995}
1996
1997static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
1998 const struct hda_fixup *fix,
1999 int action)
2000{
2001 alc_fixup_dual_codecs(codec, fix, action);
2002 switch (action) {
2003 case HDA_FIXUP_ACT_PRE_PROBE:
2004 /* override card longname to provide a unique UCM profile */
2005 strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
2006 break;
2007 case HDA_FIXUP_ACT_BUILD:
2008 /* rename Capture controls depending on the codec */
2009 rename_ctl(codec, "Capture Volume",
2010 codec->addr == 0 ?
2011 "Rear-Panel Capture Volume" :
2012 "Front-Panel Capture Volume");
2013 rename_ctl(codec, "Capture Switch",
2014 codec->addr == 0 ?
2015 "Rear-Panel Capture Switch" :
2016 "Front-Panel Capture Switch");
2017 break;
2018 }
2019}
2020
1965static const struct hda_fixup alc882_fixups[] = { 2021static const struct hda_fixup alc882_fixups[] = {
1966 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 2022 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1967 .type = HDA_FIXUP_PINS, 2023 .type = HDA_FIXUP_PINS,
@@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
2198 .type = HDA_FIXUP_FUNC, 2254 .type = HDA_FIXUP_FUNC,
2199 .v.func = alc_fixup_bass_chmap, 2255 .v.func = alc_fixup_bass_chmap,
2200 }, 2256 },
2257 [ALC1220_FIXUP_GB_DUAL_CODECS] = {
2258 .type = HDA_FIXUP_FUNC,
2259 .v.func = alc1220_fixup_gb_dual_codecs,
2260 },
2201}; 2261};
2202 2262
2203static const struct snd_pci_quirk alc882_fixup_tbl[] = { 2263static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -2267,6 +2327,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2267 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2327 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2268 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2328 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2269 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), 2329 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2330 SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
2270 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2331 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2271 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2332 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2272 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), 2333 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
@@ -4663,7 +4724,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4663 { 0x1b, 0x21114000 }, /* dock speaker pin */ 4724 { 0x1b, 0x21114000 }, /* dock speaker pin */
4664 {} 4725 {}
4665 }; 4726 };
4666 struct snd_kcontrol *kctl;
4667 4727
4668 switch (action) { 4728 switch (action) {
4669 case HDA_FIXUP_ACT_PRE_PROBE: 4729 case HDA_FIXUP_ACT_PRE_PROBE:
@@ -4678,12 +4738,10 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4678 /* this is a bit tricky; give more sane names for the main 4738 /* this is a bit tricky; give more sane names for the main
4679 * (tablet) speaker and the dock speaker, respectively 4739 * (tablet) speaker and the dock speaker, respectively
4680 */ 4740 */
4681 kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); 4741 rename_ctl(codec, "Speaker Playback Switch",
4682 if (kctl) 4742 "Dock Speaker Playback Switch");
4683 strcpy(kctl->id.name, "Dock Speaker Playback Switch"); 4743 rename_ctl(codec, "Bass Speaker Playback Switch",
4684 kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); 4744 "Speaker Playback Switch");
4685 if (kctl)
4686 strcpy(kctl->id.name, "Speaker Playback Switch");
4687 break; 4745 break;
4688 } 4746 }
4689} 4747}