ALSA: hda - Fix invalid mute led state on resume of IDT codecs
authorVitaliy Kulikov <Vitaliy.Kulikov@idt.com>
Fri, 22 Jul 2011 23:18:15 +0000 (18:18 -0500)
committerTakashi Iwai <tiwai@suse.de>
Tue, 26 Jul 2011 07:38:36 +0000 (09:38 +0200)
Codec state is not restored immediately on resume but on the first
access when power-save is enabled.  That leads to an invalid mute led
state after resume until either sound is played or some control is
changed.  This patch adds a possibility for a vendor specific patch to
restore codec state immediately after resume if required.  And it adds
code to restore IDT codecs state immediately on resume on HP systems
with mute led support.

Signed-off-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/patch_sigmatel.c

index 9c27a3a4c4d5a99c81b8820db9e14bb29421ada0..c0e83ed0b351460180afdf26c9b3fb4d500a788c 100644 (file)
@@ -5103,6 +5103,8 @@ int snd_hda_resume(struct hda_bus *bus)
        struct hda_codec *codec;
 
        list_for_each_entry(codec, &bus->codec_list, list) {
+               if (codec->patch_ops.pre_resume)
+                       codec->patch_ops.pre_resume(codec);
                if (snd_hda_codec_needs_resume(codec))
                        hda_call_codec_resume(codec);
        }
index f465e07a4879cce4a634a0874cb69f6456fd33c2..82161466d3b0c92d1254d796616e843db334eea9 100644 (file)
@@ -712,6 +712,9 @@ struct hda_codec_ops {
        int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
 #endif
        void (*reboot_notify)(struct hda_codec *codec);
+#ifdef SND_HDA_NEEDS_RESUME
+       int (*pre_resume)(struct hda_codec *codec);
+#endif
 };
 
 /* record for amp information cache */
index 00ea2bd6bc14a9d3a6d576023e9923613cd537f8..c4a6ecb8e085721a7c6b62382594f64fc3b74731 100644 (file)
@@ -4935,6 +4935,17 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
 #endif
 
 #ifdef SND_HDA_NEEDS_RESUME
+static int stac92xx_pre_resume(struct hda_codec *codec)
+{
+       struct sigmatel_spec *spec = codec->spec;
+
+       /* sync mute LED */
+       if (spec->gpio_led)
+               stac_gpio_set(codec, spec->gpio_mask,
+                               spec->gpio_dir, spec->gpio_data);
+       return 0;
+}
+
 static int stac92xx_resume(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
@@ -5013,6 +5024,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
 #ifdef SND_HDA_NEEDS_RESUME
        .suspend = stac92xx_suspend,
        .resume = stac92xx_resume,
+       .pre_resume = stac92xx_pre_resume,
 #endif
        .reboot_notify = stac92xx_shutup,
 };