diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-07-19 07:58:02 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-28 16:30:22 -0700 |
commit | 9c563a54c85bcd531cc671d9575d4dff64852124 (patch) | |
tree | 5ab829f83f48be2376e7d3e904190e084f49bef4 /sound/pci | |
parent | 5a0ecab6b7f55d7b2162e95c396ce778f2f2154c (diff) | |
download | linux-3.10-9c563a54c85bcd531cc671d9575d4dff64852124.tar.gz linux-3.10-9c563a54c85bcd531cc671d9575d4dff64852124.tar.bz2 linux-3.10-9c563a54c85bcd531cc671d9575d4dff64852124.zip |
ALSA: hda - Fix EAPD GPIO control for Sigmatel codecs
commit 1ea9a69d1a36a5b62bf281ba8bb304fcac656dad upstream.
The EAPD GPIO is dynamically turned on/off for some machines with
Sigmatel codecs, but this didn't work as expected, and it resulted in
spontaneous lost of speaker outputs per HP plugging or power-saving.
This patch fixes the bug by simply including spec->eapd_mask into
spec->gpio_mask and spec->gpio_data bits.
Reported-and-tested-by: Eric Shattow <lucent@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 486df8a867c..e849e1e0d7d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -417,9 +417,11 @@ static void stac_update_outputs(struct hda_codec *codec) val &= ~spec->eapd_mask; else val |= spec->eapd_mask; - if (spec->gpio_data != val) + if (spec->gpio_data != val) { + spec->gpio_data = val; stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, val); + } } } @@ -3608,20 +3610,18 @@ static int stac_parse_auto_config(struct hda_codec *codec) static int stac_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - unsigned int gpio; int i; /* override some hints */ stac_store_hints(codec); /* set up GPIO */ - gpio = spec->gpio_data; /* turn on EAPD statically when spec->eapd_switch isn't set. * otherwise, unsol event will turn it on/off dynamically */ if (!spec->eapd_switch) - gpio |= spec->eapd_mask; - stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); + spec->gpio_data |= spec->eapd_mask; + stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); snd_hda_gen_init(codec); @@ -3921,6 +3921,7 @@ static void stac_setup_gpio(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; + spec->gpio_mask |= spec->eapd_mask; if (spec->gpio_led) { if (!spec->vref_mute_led_nid) { spec->gpio_mask |= spec->gpio_led; |