aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-12-15 08:59:58 -0500
committerTakashi Iwai <tiwai@suse.de>2015-12-15 09:11:58 -0500
commit70a0976b0c0d90f4246d7e63359d796ec82b87d6 (patch)
tree922cbe0ed3b0b914fd217b02d0a7d7eb391a3bf9
parent157f0b7f6c0cc0bc88647390006e959e267a0143 (diff)
ALSA: hda - Set codec to D3 at reboot/shutdown on Thinkpads
Lenovo Thinkpads with Realtek codecs may still have some loud crackling noises at reboot/shutdown even though a few previous fixes have been applied. It's because the previous fix (disabling the default shutup callback) takes effect only at transition of the codec power state. Meanwhile, at reboot or shutdown, we don't take down the codec power as default, thus it triggers the same problem unless the codec is powered down casually by runtime PM. This patch tries to address the issue. It gives two things: - implement the separate reboot_notify hook to struct alc_spec, and call it optionally if defined. - turn off the codec to D3 for Thinkpad models via this new callback Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=958439 Reported-and-tested-by: Benjamin Poirier <bpoirier@suse.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_realtek.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 531065eaac1b..5a79c7a2187a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -111,6 +111,7 @@ struct alc_spec {
111 void (*power_hook)(struct hda_codec *codec); 111 void (*power_hook)(struct hda_codec *codec);
112#endif 112#endif
113 void (*shutup)(struct hda_codec *codec); 113 void (*shutup)(struct hda_codec *codec);
114 void (*reboot_notify)(struct hda_codec *codec);
114 115
115 int init_amp; 116 int init_amp;
116 int codec_variant; /* flag for other variants */ 117 int codec_variant; /* flag for other variants */
@@ -773,6 +774,25 @@ static inline void alc_shutup(struct hda_codec *codec)
773 snd_hda_shutup_pins(codec); 774 snd_hda_shutup_pins(codec);
774} 775}
775 776
777static void alc_reboot_notify(struct hda_codec *codec)
778{
779 struct alc_spec *spec = codec->spec;
780
781 if (spec && spec->reboot_notify)
782 spec->reboot_notify(codec);
783 else
784 alc_shutup(codec);
785}
786
787/* power down codec to D3 at reboot/shutdown; set as reboot_notify ops */
788static void alc_d3_at_reboot(struct hda_codec *codec)
789{
790 snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3);
791 snd_hda_codec_write(codec, codec->core.afg, 0,
792 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
793 msleep(10);
794}
795
776#define alc_free snd_hda_gen_free 796#define alc_free snd_hda_gen_free
777 797
778#ifdef CONFIG_PM 798#ifdef CONFIG_PM
@@ -818,7 +838,7 @@ static const struct hda_codec_ops alc_patch_ops = {
818 .suspend = alc_suspend, 838 .suspend = alc_suspend,
819 .check_power_status = snd_hda_gen_check_power_status, 839 .check_power_status = snd_hda_gen_check_power_status,
820#endif 840#endif
821 .reboot_notify = alc_shutup, 841 .reboot_notify = alc_reboot_notify,
822}; 842};
823 843
824 844
@@ -4199,6 +4219,7 @@ static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4199 4219
4200 if (action == HDA_FIXUP_ACT_PRE_PROBE) { 4220 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4201 spec->shutup = alc_no_shutup; /* reduce click noise */ 4221 spec->shutup = alc_no_shutup; /* reduce click noise */
4222 spec->reboot_notify = alc_d3_at_reboot; /* reduce noise */
4202 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; 4223 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4203 codec->power_save_node = 0; /* avoid click noises */ 4224 codec->power_save_node = 0; /* avoid click noises */
4204 snd_hda_apply_pincfgs(codec, pincfgs); 4225 snd_hda_apply_pincfgs(codec, pincfgs);