Merge branch 'topic/hda-dual-codecs' into for-next
This commit is contained in:
commit
610793fe2b
|
@ -494,6 +494,8 @@ add_hp_mic (bool)
|
||||||
hp_mic_detect (bool)
|
hp_mic_detect (bool)
|
||||||
enable/disable the hp/mic shared input for a single built-in mic
|
enable/disable the hp/mic shared input for a single built-in mic
|
||||||
case; default true
|
case; default true
|
||||||
|
vmaster (bool)
|
||||||
|
enable/disable the virtual Master control; default true
|
||||||
mixer_nid (int)
|
mixer_nid (int)
|
||||||
specifies the widget NID of the analog-loopback mixer
|
specifies the widget NID of the analog-loopback mixer
|
||||||
|
|
||||||
|
|
|
@ -580,6 +580,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
|
||||||
has_multiple_pins = 1;
|
has_multiple_pins = 1;
|
||||||
if (has_multiple_pins && type == AUTO_PIN_MIC)
|
if (has_multiple_pins && type == AUTO_PIN_MIC)
|
||||||
has_multiple_pins &= check_mic_location_need(codec, cfg, input);
|
has_multiple_pins &= check_mic_location_need(codec, cfg, input);
|
||||||
|
has_multiple_pins |= codec->force_pin_prefix;
|
||||||
return hda_get_input_pin_label(codec, &cfg->inputs[input],
|
return hda_get_input_pin_label(codec, &cfg->inputs[input],
|
||||||
cfg->inputs[input].pin,
|
cfg->inputs[input].pin,
|
||||||
has_multiple_pins);
|
has_multiple_pins);
|
||||||
|
|
|
@ -256,6 +256,7 @@ struct hda_codec {
|
||||||
unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
|
unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
|
||||||
unsigned int power_save_node:1; /* advanced PM for each widget */
|
unsigned int power_save_node:1; /* advanced PM for each widget */
|
||||||
unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
|
unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
|
||||||
|
unsigned int force_pin_prefix:1; /* Add location prefix */
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
unsigned long power_on_acct;
|
unsigned long power_on_acct;
|
||||||
unsigned long power_off_acct;
|
unsigned long power_off_acct;
|
||||||
|
|
|
@ -196,6 +196,9 @@ static void parse_user_hints(struct hda_codec *codec)
|
||||||
val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
|
val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
|
||||||
if (val >= 0)
|
if (val >= 0)
|
||||||
spec->suppress_hp_mic_detect = !val;
|
spec->suppress_hp_mic_detect = !val;
|
||||||
|
val = snd_hda_get_bool_hint(codec, "vmaster");
|
||||||
|
if (val >= 0)
|
||||||
|
spec->suppress_vmaster = !val;
|
||||||
|
|
||||||
if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
|
if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
|
||||||
spec->mixer_nid = val;
|
spec->mixer_nid = val;
|
||||||
|
@ -1125,6 +1128,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
|
||||||
|
|
||||||
*index = 0;
|
*index = 0;
|
||||||
if (cfg->line_outs == 1 && !spec->multi_ios &&
|
if (cfg->line_outs == 1 && !spec->multi_ios &&
|
||||||
|
!codec->force_pin_prefix &&
|
||||||
!cfg->hp_outs && !cfg->speaker_outs)
|
!cfg->hp_outs && !cfg->speaker_outs)
|
||||||
return spec->vmaster_mute.hook ? "PCM" : "Master";
|
return spec->vmaster_mute.hook ? "PCM" : "Master";
|
||||||
|
|
||||||
|
@ -1132,6 +1136,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
|
||||||
* use it master (or "PCM" if a vmaster hook is present)
|
* use it master (or "PCM" if a vmaster hook is present)
|
||||||
*/
|
*/
|
||||||
if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
|
if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
|
||||||
|
!codec->force_pin_prefix &&
|
||||||
!spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
|
!spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
|
||||||
return spec->vmaster_mute.hook ? "PCM" : "Master";
|
return spec->vmaster_mute.hook ? "PCM" : "Master";
|
||||||
|
|
||||||
|
@ -5031,7 +5036,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we have no master control, let's create it */
|
/* if we have no master control, let's create it */
|
||||||
if (!spec->no_analog &&
|
if (!spec->no_analog && !spec->suppress_vmaster &&
|
||||||
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
|
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
|
||||||
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
|
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
|
||||||
spec->vmaster_tlv, slave_pfxs,
|
spec->vmaster_tlv, slave_pfxs,
|
||||||
|
@ -5039,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (!spec->no_analog &&
|
if (!spec->no_analog && !spec->suppress_vmaster &&
|
||||||
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
|
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
|
||||||
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
||||||
NULL, slave_pfxs,
|
NULL, slave_pfxs,
|
||||||
|
|
|
@ -229,6 +229,7 @@ struct hda_gen_spec {
|
||||||
unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
|
unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
|
||||||
unsigned int power_down_unused:1; /* power down unused widgets */
|
unsigned int power_down_unused:1; /* power down unused widgets */
|
||||||
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
||||||
|
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
|
||||||
|
|
||||||
/* other internal flags */
|
/* other internal flags */
|
||||||
unsigned int no_analog:1; /* digital I/O only */
|
unsigned int no_analog:1; /* digital I/O only */
|
||||||
|
|
|
@ -1800,6 +1800,7 @@ enum {
|
||||||
ALC882_FIXUP_NO_PRIMARY_HP,
|
ALC882_FIXUP_NO_PRIMARY_HP,
|
||||||
ALC887_FIXUP_ASUS_BASS,
|
ALC887_FIXUP_ASUS_BASS,
|
||||||
ALC887_FIXUP_BASS_CHMAP,
|
ALC887_FIXUP_BASS_CHMAP,
|
||||||
|
ALC1220_FIXUP_GB_DUAL_CODECS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void alc889_fixup_coef(struct hda_codec *codec,
|
static void alc889_fixup_coef(struct hda_codec *codec,
|
||||||
|
@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
|
||||||
static void alc_fixup_bass_chmap(struct hda_codec *codec,
|
static void alc_fixup_bass_chmap(struct hda_codec *codec,
|
||||||
const struct hda_fixup *fix, int action);
|
const struct hda_fixup *fix, int action);
|
||||||
|
|
||||||
|
/* For dual-codec configuration, we need to disable some features to avoid
|
||||||
|
* conflicts of kctls and PCM streams
|
||||||
|
*/
|
||||||
|
static void alc_fixup_dual_codecs(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix, int action)
|
||||||
|
{
|
||||||
|
struct alc_spec *spec = codec->spec;
|
||||||
|
|
||||||
|
if (action != HDA_FIXUP_ACT_PRE_PROBE)
|
||||||
|
return;
|
||||||
|
/* disable vmaster */
|
||||||
|
spec->gen.suppress_vmaster = 1;
|
||||||
|
/* auto-mute and auto-mic switch don't work with multiple codecs */
|
||||||
|
spec->gen.suppress_auto_mute = 1;
|
||||||
|
spec->gen.suppress_auto_mic = 1;
|
||||||
|
/* disable aamix as well */
|
||||||
|
spec->gen.mixer_nid = 0;
|
||||||
|
/* add location prefix to avoid conflicts */
|
||||||
|
codec->force_pin_prefix = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rename_ctl(struct hda_codec *codec, const char *oldname,
|
||||||
|
const char *newname)
|
||||||
|
{
|
||||||
|
struct snd_kcontrol *kctl;
|
||||||
|
|
||||||
|
kctl = snd_hda_find_mixer_ctl(codec, oldname);
|
||||||
|
if (kctl)
|
||||||
|
strcpy(kctl->id.name, newname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix,
|
||||||
|
int action)
|
||||||
|
{
|
||||||
|
alc_fixup_dual_codecs(codec, fix, action);
|
||||||
|
switch (action) {
|
||||||
|
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||||
|
/* override card longname to provide a unique UCM profile */
|
||||||
|
strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
|
||||||
|
break;
|
||||||
|
case HDA_FIXUP_ACT_BUILD:
|
||||||
|
/* rename Capture controls depending on the codec */
|
||||||
|
rename_ctl(codec, "Capture Volume",
|
||||||
|
codec->addr == 0 ?
|
||||||
|
"Rear-Panel Capture Volume" :
|
||||||
|
"Front-Panel Capture Volume");
|
||||||
|
rename_ctl(codec, "Capture Switch",
|
||||||
|
codec->addr == 0 ?
|
||||||
|
"Rear-Panel Capture Switch" :
|
||||||
|
"Front-Panel Capture Switch");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct hda_fixup alc882_fixups[] = {
|
static const struct hda_fixup alc882_fixups[] = {
|
||||||
[ALC882_FIXUP_ABIT_AW9D_MAX] = {
|
[ALC882_FIXUP_ABIT_AW9D_MAX] = {
|
||||||
.type = HDA_FIXUP_PINS,
|
.type = HDA_FIXUP_PINS,
|
||||||
|
@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
|
||||||
.type = HDA_FIXUP_FUNC,
|
.type = HDA_FIXUP_FUNC,
|
||||||
.v.func = alc_fixup_bass_chmap,
|
.v.func = alc_fixup_bass_chmap,
|
||||||
},
|
},
|
||||||
|
[ALC1220_FIXUP_GB_DUAL_CODECS] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc1220_fixup_gb_dual_codecs,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||||
|
@ -2267,6 +2327,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
|
SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
|
||||||
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
||||||
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
||||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
||||||
|
@ -4663,7 +4724,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
|
||||||
{ 0x1b, 0x21114000 }, /* dock speaker pin */
|
{ 0x1b, 0x21114000 }, /* dock speaker pin */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
struct snd_kcontrol *kctl;
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||||
|
@ -4678,12 +4738,10 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
|
||||||
/* this is a bit tricky; give more sane names for the main
|
/* this is a bit tricky; give more sane names for the main
|
||||||
* (tablet) speaker and the dock speaker, respectively
|
* (tablet) speaker and the dock speaker, respectively
|
||||||
*/
|
*/
|
||||||
kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
|
rename_ctl(codec, "Speaker Playback Switch",
|
||||||
if (kctl)
|
"Dock Speaker Playback Switch");
|
||||||
strcpy(kctl->id.name, "Dock Speaker Playback Switch");
|
rename_ctl(codec, "Bass Speaker Playback Switch",
|
||||||
kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
|
"Speaker Playback Switch");
|
||||||
if (kctl)
|
|
||||||
strcpy(kctl->id.name, "Speaker Playback Switch");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue