提交 610793fe 编写于 作者: T Takashi Iwai

Merge branch 'topic/hda-dual-codecs' into for-next

......@@ -494,6 +494,8 @@ add_hp_mic (bool)
hp_mic_detect (bool)
enable/disable the hp/mic shared input for a single built-in mic
case; default true
vmaster (bool)
enable/disable the virtual Master control; default true
mixer_nid (int)
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;
if (has_multiple_pins && type == AUTO_PIN_MIC)
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],
cfg->inputs[input].pin,
has_multiple_pins);
......
......@@ -256,6 +256,7 @@ struct hda_codec {
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 auto_runtime_pm:1; /* enable automatic codec runtime pm */
unsigned int force_pin_prefix:1; /* Add location prefix */
#ifdef CONFIG_PM
unsigned long power_on_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");
if (val >= 0)
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))
spec->mixer_nid = val;
......@@ -1125,6 +1128,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
*index = 0;
if (cfg->line_outs == 1 && !spec->multi_ios &&
!codec->force_pin_prefix &&
!cfg->hp_outs && !cfg->speaker_outs)
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)
*/
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])
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 (!spec->no_analog &&
if (!spec->no_analog && !spec->suppress_vmaster &&
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
spec->vmaster_tlv, slave_pfxs,
......@@ -5039,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
}
if (!spec->no_analog &&
if (!spec->no_analog && !spec->suppress_vmaster &&
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
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 power_down_unused:1; /* power down unused widgets */
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
/* other internal flags */
unsigned int no_analog:1; /* digital I/O only */
......
......@@ -1800,6 +1800,7 @@ enum {
ALC882_FIXUP_NO_PRIMARY_HP,
ALC887_FIXUP_ASUS_BASS,
ALC887_FIXUP_BASS_CHMAP,
ALC1220_FIXUP_GB_DUAL_CODECS,
};
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,
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[] = {
[ALC882_FIXUP_ABIT_AW9D_MAX] = {
.type = HDA_FIXUP_PINS,
......@@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
.type = HDA_FIXUP_FUNC,
.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[] = {
......@@ -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_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, 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_VENDOR(0x1558, "Clevo laptop", ALC882_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 */
{}
};
struct snd_kcontrol *kctl;
switch (action) {
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
* (tablet) speaker and the dock speaker, respectively
*/
kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
if (kctl)
strcpy(kctl->id.name, "Dock Speaker Playback Switch");
kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
if (kctl)
strcpy(kctl->id.name, "Speaker Playback Switch");
rename_ctl(codec, "Speaker Playback Switch",
"Dock Speaker Playback Switch");
rename_ctl(codec, "Bass Speaker Playback Switch",
"Speaker Playback Switch");
break;
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册