[alsa-devel] Loud pops from Intel HDA onboard sound, may damage speakers (fwd)
Takashi Iwai
tiwai at suse.de
Tue Mar 29 15:16:44 CEST 2011
At Sun, 27 Mar 2011 03:27:28 +0100 (BST),
Chris Wilson wrote:
>
> Hi Takashi,
>
> On Sat, 26 Mar 2011, Takashi Iwai wrote:
>
> > I attached below. This is no final version and we are working on it. But
> > it'd be helpful if you can test it whether it solves the issue.
>
> Thanks for sending the patch :) I think it makes some progress towards
> solving the issue. On suspend I now get only one pop instead of two, and
> none on resume. The pop that I still get on suspend is the one that causes
> my amplifier to trip out (which was the second one previously).
Good to hear of improvements.
I cleaned up the patch a bit. Could you try the patch below instead?
I removed the second msleep() in the resume callback, supposedly it's
irrelevant. If you get a noise again in the resume path, try to add
msleep(150) after codec->patch_ops.init() in alc_resume().
The remaining noise in the suspend path is still unclear.
We have one place that we do NOT turn down the power to D3 -- in
hda_set_power_state() in hda_codec.c, D3-transition is skipped on a
widget with EAPD control. It's interesting whether any widgets hit
this.
Otherwise, we may need to check which call actually gives the noise.
You can put a printk() and a long timeout at each line, and watch the
kernel message....
thanks,
Takashi
---
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 12c6f45..29eb397 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -375,6 +375,7 @@ struct alc_spec {
#ifdef CONFIG_SND_HDA_POWER_SAVE
void (*power_hook)(struct hda_codec *codec);
#endif
+ void (*shutup)(struct hda_codec *codec);
/* for pin sensing */
unsigned int sense_updated: 1;
@@ -1236,6 +1237,15 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
on ? 2 : 0);
}
+static void alc_eapd_shutup(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+
+ set_eapd(codec, 0x14, 0);
+ set_eapd(codec, 0x15, 0);
+ msleep(200);
+}
+
static void alc_auto_init_amp(struct hda_codec *codec, int type)
{
unsigned int tmp;
@@ -4193,6 +4203,10 @@ static int alc_build_pcms(struct hda_codec *codec)
static inline void alc_shutup(struct hda_codec *codec)
{
+ struct alc_spec *spec = codec->spec;
+
+ if (spec && spec->shutup)
+ spec->shutup(codec);
snd_hda_shutup_pins(codec);
}
@@ -4263,6 +4277,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
#ifdef SND_HDA_NEEDS_RESUME
static int alc_resume(struct hda_codec *codec)
{
+ msleep(150); /* to avoid pop noise */
codec->patch_ops.init(codec);
snd_hda_codec_resume_amp(codec);
snd_hda_codec_resume_cache(codec);
@@ -13018,6 +13033,7 @@ static int patch_alc262(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC262_AUTO)
spec->init_hook = alc262_auto_init;
+ spec->shutup = alc_eapd_shutup;
alc_init_jacks(codec);
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -14092,6 +14108,7 @@ static int patch_alc268(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC268_AUTO)
spec->init_hook = alc268_auto_init;
+ spec->shutup = alc_eapd_shutup;
alc_init_jacks(codec);
@@ -17410,6 +17418,8 @@ static int patch_alc861vd(struct hda_codec *codec)
if (board_config == ALC861VD_AUTO)
spec->init_hook = alc861vd_auto_init;
+ spec->shutup = alc_eapd_shutup;
+
#ifdef CONFIG_SND_HDA_POWER_SAVE
if (!spec->loopback.amplist)
spec->loopback.amplist = alc861vd_loopbacks;
@@ -19611,6 +19621,7 @@ static int patch_alc662(struct hda_codec *codec)
codec->patch_ops = alc_patch_ops;
if (board_config == ALC662_AUTO)
spec->init_hook = alc662_auto_init;
+ spec->shutup = alc_eapd_shutup;
alc_init_jacks(codec);
More information about the Alsa-devel
mailing list