diff options
| -rw-r--r-- | Documentation/sound/hd-audio/notes.rst | 2 | ||||
| -rw-r--r-- | sound/pci/hda/hda_auto_parser.c | 1 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
| -rw-r--r-- | sound/pci/hda/hda_generic.c | 9 | ||||
| -rw-r--r-- | sound/pci/hda/hda_generic.h | 1 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 72 |
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) | |||
| 494 | hp_mic_detect (bool) | 494 | hp_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 |
| 497 | vmaster (bool) | ||
| 498 | enable/disable the virtual Master control; default true | ||
| 497 | mixer_nid (int) | 499 | mixer_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 | ||
| 1805 | static void alc889_fixup_coef(struct hda_codec *codec, | 1806 | static void alc889_fixup_coef(struct hda_codec *codec, |
| @@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec, | |||
| 1962 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 1963 | static 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 | */ | ||
| 1969 | static 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 | |||
| 1987 | static 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 | |||
| 1997 | static 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 | |||
| 1965 | static const struct hda_fixup alc882_fixups[] = { | 2021 | static 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 | ||
| 2203 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 2263 | static 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 | } |
