diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_generic.c | 68 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 23 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 9 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 10 |
5 files changed, 80 insertions, 31 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index ae85bbd2e6f..4b1524a861f 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -788,6 +788,8 @@ static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable) return; if (codec->inv_eapd) enable = !enable; + if (spec->keep_eapd_on && !enable) + return; snd_hda_codec_update_cache(codec, pin, 0, AC_VERB_SET_EAPD_BTLENABLE, enable ? 0x02 : 0x00); @@ -1938,17 +1940,7 @@ static int create_speaker_out_ctls(struct hda_codec *codec) * independent HP controls */ -/* update HP auto-mute state too */ -static void update_hp_automute_hook(struct hda_codec *codec) -{ - struct hda_gen_spec *spec = codec->spec; - - if (spec->hp_automute_hook) - spec->hp_automute_hook(codec, NULL); - else - snd_hda_gen_hp_automute(codec, NULL); -} - +static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack); static int indep_hp_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2009,7 +2001,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol, else *dacp = spec->alt_dac_nid; - update_hp_automute_hook(codec); + call_hp_automute(codec, NULL); ret = 1; } unlock: @@ -2305,7 +2297,7 @@ static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force) else val = PIN_HP; set_pin_target(codec, pin, val, true); - update_hp_automute_hook(codec); + call_hp_automute(codec, NULL); } } @@ -2714,7 +2706,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, val = snd_hda_get_default_vref(codec, nid); } snd_hda_set_pin_ctl_cache(codec, nid, val); - update_hp_automute_hook(codec); + call_hp_automute(codec, NULL); return 1; } @@ -3859,20 +3851,42 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja } EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch); -/* update jack retasking */ -static void update_automute_all(struct hda_codec *codec) +/* call appropriate hooks */ +static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) { struct hda_gen_spec *spec = codec->spec; + if (spec->hp_automute_hook) + spec->hp_automute_hook(codec, jack); + else + snd_hda_gen_hp_automute(codec, jack); +} - update_hp_automute_hook(codec); +static void call_line_automute(struct hda_codec *codec, + struct hda_jack_tbl *jack) +{ + struct hda_gen_spec *spec = codec->spec; if (spec->line_automute_hook) - spec->line_automute_hook(codec, NULL); + spec->line_automute_hook(codec, jack); else - snd_hda_gen_line_automute(codec, NULL); + snd_hda_gen_line_automute(codec, jack); +} + +static void call_mic_autoswitch(struct hda_codec *codec, + struct hda_jack_tbl *jack) +{ + struct hda_gen_spec *spec = codec->spec; if (spec->mic_autoswitch_hook) - spec->mic_autoswitch_hook(codec, NULL); + spec->mic_autoswitch_hook(codec, jack); else - snd_hda_gen_mic_autoswitch(codec, NULL); + snd_hda_gen_mic_autoswitch(codec, jack); +} + +/* update jack retasking */ +static void update_automute_all(struct hda_codec *codec) +{ + call_hp_automute(codec, NULL); + call_line_automute(codec, NULL); + call_mic_autoswitch(codec, NULL); } /* @@ -4009,9 +4023,7 @@ static int check_auto_mute_availability(struct hda_codec *codec) snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n", nid); snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT, - spec->hp_automute_hook ? - spec->hp_automute_hook : - snd_hda_gen_hp_automute); + call_hp_automute); spec->detect_hp = 1; } @@ -4024,9 +4036,7 @@ static int check_auto_mute_availability(struct hda_codec *codec) snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid); snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_FRONT_EVENT, - spec->line_automute_hook ? - spec->line_automute_hook : - snd_hda_gen_line_automute); + call_line_automute); spec->detect_lo = 1; } spec->automute_lo_possible = spec->detect_hp; @@ -4068,9 +4078,7 @@ static bool auto_mic_check_imux(struct hda_codec *codec) snd_hda_jack_detect_enable_callback(codec, spec->am_entry[i].pin, HDA_GEN_MIC_EVENT, - spec->mic_autoswitch_hook ? - spec->mic_autoswitch_hook : - snd_hda_gen_mic_autoswitch); + call_mic_autoswitch); return true; } diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 54e66516037..76200314ee9 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -222,6 +222,7 @@ struct hda_gen_spec { unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ unsigned int own_eapd_ctl:1; /* set EAPD by own function */ + unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */ unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */ unsigned int indep_hp:1; /* independent HP supported */ unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */ diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index bd8d46cca2b..cccaf9c7a7b 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -58,6 +58,7 @@ enum { CS420X_GPIO_23, CS420X_MBP101, CS420X_MBP81, + CS420X_MBA42, CS420X_AUTO, /* aliases */ CS420X_IMAC27_122 = CS420X_GPIO_23, @@ -346,6 +347,7 @@ static const struct hda_model_fixup cs420x_models[] = { { .id = CS420X_APPLE, .name = "apple" }, { .id = CS420X_MBP101, .name = "mbp101" }, { .id = CS420X_MBP81, .name = "mbp81" }, + { .id = CS420X_MBA42, .name = "mba42" }, {} }; @@ -361,6 +363,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), + SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), {} /* terminator */ }; @@ -414,6 +417,20 @@ static const struct hda_pintbl mbp101_pincfgs[] = { {} /* terminator */ }; +static const struct hda_pintbl mba42_pincfgs[] = { + { 0x09, 0x012b4030 }, /* HP */ + { 0x0a, 0x400000f0 }, + { 0x0b, 0x90100120 }, /* speaker */ + { 0x0c, 0x400000f0 }, + { 0x0d, 0x90a00110 }, /* mic */ + { 0x0e, 0x400000f0 }, + { 0x0f, 0x400000f0 }, + { 0x10, 0x400000f0 }, + { 0x12, 0x400000f0 }, + { 0x15, 0x400000f0 }, + {} /* terminator */ +}; + static void cs420x_fixup_gpio_13(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -482,6 +499,12 @@ static const struct hda_fixup cs420x_fixups[] = { .chained = true, .chain_id = CS420X_GPIO_13, }, + [CS420X_MBA42] = { + .type = HDA_FIXUP_PINS, + .v.pins = mba42_pincfgs, + .chained = true, + .chain_id = CS420X_GPIO_13, + }, }; static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 59d2e91a9ab..403010c9e82 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3483,6 +3483,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), @@ -3493,6 +3494,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), @@ -3530,6 +3535,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), + SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), @@ -3593,6 +3599,8 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, + {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, + {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, {} }; @@ -4272,6 +4280,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = { {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {} }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index e0dadcf2030..e5245544eb5 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -136,6 +136,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec) spec->codec_type = VT1708S; spec->no_pin_power_ctl = 1; spec->gen.indep_hp = 1; + spec->gen.keep_eapd_on = 1; spec->gen.pcm_playback_hook = via_playback_pcm_hook; return spec; } @@ -231,9 +232,14 @@ static void vt1708_update_hp_work(struct hda_codec *codec) static void set_widgets_power_state(struct hda_codec *codec) { +#if 0 /* FIXME: the assumed connections don't match always with the + * actual routes by the generic parser, so better to disable + * the control for safety. + */ struct via_spec *spec = codec->spec; if (spec->set_widgets_power_state) spec->set_widgets_power_state(codec); +#endif } static void update_power_state(struct hda_codec *codec, hda_nid_t nid, @@ -478,7 +484,9 @@ static int via_suspend(struct hda_codec *codec) /* Fix pop noise on headphones */ int i; for (i = 0; i < spec->gen.autocfg.hp_outs; i++) - snd_hda_set_pin_ctl(codec, spec->gen.autocfg.hp_pins[i], 0); + snd_hda_codec_write(codec, spec->gen.autocfg.hp_pins[i], + 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + 0x00); } return 0; |