diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-07-19 01:58:02 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-07-19 01:58:02 -0400 |
commit | 1ea9a69d1a36a5b62bf281ba8bb304fcac656dad (patch) | |
tree | 8449e0ca65b2de44c1ffb88d023bca09c986fb0b | |
parent | 256ca9c3ad5013ff8a8f165e5a82fab437628c8e (diff) |
ALSA: hda - Fix EAPD GPIO control for Sigmatel codecs
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>
Cc: <stable@vger.kernel.org> [v3.9+]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-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 e2f83591161b..766e56754c64 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) | |||
417 | val &= ~spec->eapd_mask; | 417 | val &= ~spec->eapd_mask; |
418 | else | 418 | else |
419 | val |= spec->eapd_mask; | 419 | val |= spec->eapd_mask; |
420 | if (spec->gpio_data != val) | 420 | if (spec->gpio_data != val) { |
421 | spec->gpio_data = val; | ||
421 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, | 422 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, |
422 | val); | 423 | val); |
424 | } | ||
423 | } | 425 | } |
424 | } | 426 | } |
425 | 427 | ||
@@ -3612,20 +3614,18 @@ static int stac_parse_auto_config(struct hda_codec *codec) | |||
3612 | static int stac_init(struct hda_codec *codec) | 3614 | static int stac_init(struct hda_codec *codec) |
3613 | { | 3615 | { |
3614 | struct sigmatel_spec *spec = codec->spec; | 3616 | struct sigmatel_spec *spec = codec->spec; |
3615 | unsigned int gpio; | ||
3616 | int i; | 3617 | int i; |
3617 | 3618 | ||
3618 | /* override some hints */ | 3619 | /* override some hints */ |
3619 | stac_store_hints(codec); | 3620 | stac_store_hints(codec); |
3620 | 3621 | ||
3621 | /* set up GPIO */ | 3622 | /* set up GPIO */ |
3622 | gpio = spec->gpio_data; | ||
3623 | /* turn on EAPD statically when spec->eapd_switch isn't set. | 3623 | /* turn on EAPD statically when spec->eapd_switch isn't set. |
3624 | * otherwise, unsol event will turn it on/off dynamically | 3624 | * otherwise, unsol event will turn it on/off dynamically |
3625 | */ | 3625 | */ |
3626 | if (!spec->eapd_switch) | 3626 | if (!spec->eapd_switch) |
3627 | gpio |= spec->eapd_mask; | 3627 | spec->gpio_data |= spec->eapd_mask; |
3628 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); | 3628 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); |
3629 | 3629 | ||
3630 | snd_hda_gen_init(codec); | 3630 | snd_hda_gen_init(codec); |
3631 | 3631 | ||
@@ -3915,6 +3915,7 @@ static void stac_setup_gpio(struct hda_codec *codec) | |||
3915 | { | 3915 | { |
3916 | struct sigmatel_spec *spec = codec->spec; | 3916 | struct sigmatel_spec *spec = codec->spec; |
3917 | 3917 | ||
3918 | spec->gpio_mask |= spec->eapd_mask; | ||
3918 | if (spec->gpio_led) { | 3919 | if (spec->gpio_led) { |
3919 | if (!spec->vref_mute_led_nid) { | 3920 | if (!spec->vref_mute_led_nid) { |
3920 | spec->gpio_mask |= spec->gpio_led; | 3921 | spec->gpio_mask |= spec->gpio_led; |