[alsa-devel] [PATCH] ALSA: hda - Fix clicking noise on Thinkpad T61/R61i
Takashi Iwai
tiwai at suse.de
Wed Dec 12 18:15:05 CET 2012
At Wed, 12 Dec 2012 18:02:04 +0100,
David Henningsson wrote:
>
> The bug reporter reports that setting the speaker pin to
> D3 before turning off its pinctl fixes the clicking noise on
> powersave for Thinkpad T61.
>
> Thanks to c4pp4 for doing most of the work with this bug, including
> reporting and testing, and writing preliminary patches.
>
> BugLink: https://bugs.launchpad.net/bugs/886975
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> ---
> sound/pci/hda/patch_conexant.c | 36 ++++++++++++++++++++++++++++++++----
> 1 file changed, 32 insertions(+), 4 deletions(-)
>
> Note: c4pp4 pointed out that in his case, only the speaker needed to go to
> D3 before pinctl, but noticed no regressions from the below implementation,
> so I made the fixup more generic (easier to reuse later).
Well, if going to D3 is already achieved there, there is no point to
call snd_hda_shutup_pins(). snd_hda_shutup_pins() itself is for
reducing the click noise while the codec is going down to D3.
Thus, for this particular machine, simply disable
snd_hda_shutup_pins() call from suspend, and make D3 call in
reboot_notify.
Takashi
> diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
> index a3a2263..27e6ca7 100644
> --- a/sound/pci/hda/patch_conexant.c
> +++ b/sound/pci/hda/patch_conexant.c
> @@ -144,6 +144,7 @@ struct conexant_spec {
> unsigned int asus:1;
> unsigned int pin_eapd_ctrls:1;
> unsigned int fixup_stereo_dmic:1;
> + unsigned int d3_before_shutup:1; /* Needs speaker to go to D3 before pinctl */
>
> unsigned int adc_switching:1;
>
> @@ -558,13 +559,22 @@ static int conexant_build_controls(struct hda_codec *codec)
> return 0;
> }
>
> -#ifdef CONFIG_PM
> static int conexant_suspend(struct hda_codec *codec)
> {
> + struct conexant_spec *spec = codec->spec;
> +
> + if (spec->d3_before_shutup)
> + snd_hda_codec_set_power_to_all(codec, codec->afg, AC_PWRST_D3,
> + false);
> snd_hda_shutup_pins(codec);
> return 0;
> }
> -#endif
> +
> +static void conexant_reboot_notify(struct hda_codec *codec)
> +{
> + conexant_suspend(codec);
> +}
> +
>
> static const struct hda_codec_ops conexant_patch_ops = {
> .build_controls = conexant_build_controls,
> @@ -575,7 +585,7 @@ static const struct hda_codec_ops conexant_patch_ops = {
> #ifdef CONFIG_PM
> .suspend = conexant_suspend,
> #endif
> - .reboot_notify = snd_hda_shutup_pins,
> + .reboot_notify = conexant_reboot_notify,
> };
>
> #ifdef CONFIG_SND_HDA_INPUT_BEEP
> @@ -4408,7 +4418,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = {
> #ifdef CONFIG_PM
> .suspend = conexant_suspend,
> #endif
> - .reboot_notify = snd_hda_shutup_pins,
> + .reboot_notify = conexant_reboot_notify,
> };
>
> /*
> @@ -4421,6 +4431,7 @@ enum {
> CXT_PINCFG_LEMOTE_A1205,
> CXT_FIXUP_STEREO_DMIC,
> CXT_FIXUP_INC_MIC_BOOST,
> + CXT_FIXUP_D3_BEFORE_SHUTUP,
> };
>
> static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
> @@ -4430,6 +4441,13 @@ static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
> spec->fixup_stereo_dmic = 1;
> }
>
> +static void cxt_fixup_d3_before_shutup(struct hda_codec *codec,
> + const struct hda_fixup *fix, int action)
> +{
> + struct conexant_spec *spec = codec->spec;
> + spec->d3_before_shutup = 1;
> +}
> +
> static void cxt5066_increase_mic_boost(struct hda_codec *codec,
> const struct hda_fixup *fix, int action)
> {
> @@ -4499,6 +4517,15 @@ static const struct hda_fixup cxt_fixups[] = {
> .type = HDA_FIXUP_FUNC,
> .v.func = cxt5066_increase_mic_boost,
> },
> + [CXT_FIXUP_D3_BEFORE_SHUTUP] = {
> + .type = HDA_FIXUP_FUNC,
> + .v.func = cxt_fixup_d3_before_shutup,
> + },
> +};
> +
> +static const struct snd_pci_quirk cxt5045_fixups[] = {
> + SND_PCI_QUIRK(0x17aa, 0x20ac, "Lenovo T61/R61i", CXT_FIXUP_D3_BEFORE_SHUTUP),
> + {}
> };
>
> static const struct snd_pci_quirk cxt5051_fixups[] = {
> @@ -4553,6 +4580,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
> switch (codec->vendor_id) {
> case 0x14f15045:
> codec->single_adc_amp = 1;
> + snd_hda_pick_fixup(codec, NULL, cxt5045_fixups, cxt_fixups);
> break;
> case 0x14f15051:
> add_cx5051_fake_mutes(codec);
> --
> 1.7.9.5
>
More information about the Alsa-devel
mailing list