Commit 1ea9a69d authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarEric Shattow <lucent@gmail.com>
Cc: <stable@vger.kernel.org> [v3.9+]
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 256ca9c3
...@@ -417,10 +417,12 @@ static void stac_update_outputs(struct hda_codec *codec) ...@@ -417,10 +417,12 @@ static void stac_update_outputs(struct hda_codec *codec)
val &= ~spec->eapd_mask; val &= ~spec->eapd_mask;
else else
val |= spec->eapd_mask; 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, stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir,
val); val);
} }
}
} }
static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
...@@ -3612,20 +3614,18 @@ static int stac_parse_auto_config(struct hda_codec *codec) ...@@ -3612,20 +3614,18 @@ static int stac_parse_auto_config(struct hda_codec *codec)
static int stac_init(struct hda_codec *codec) static int stac_init(struct hda_codec *codec)
{ {
struct sigmatel_spec *spec = codec->spec; struct sigmatel_spec *spec = codec->spec;
unsigned int gpio;
int i; int i;
/* override some hints */ /* override some hints */
stac_store_hints(codec); stac_store_hints(codec);
/* set up GPIO */ /* set up GPIO */
gpio = spec->gpio_data;
/* turn on EAPD statically when spec->eapd_switch isn't set. /* turn on EAPD statically when spec->eapd_switch isn't set.
* otherwise, unsol event will turn it on/off dynamically * otherwise, unsol event will turn it on/off dynamically
*/ */
if (!spec->eapd_switch) if (!spec->eapd_switch)
gpio |= spec->eapd_mask; spec->gpio_data |= spec->eapd_mask;
stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
snd_hda_gen_init(codec); snd_hda_gen_init(codec);
...@@ -3915,6 +3915,7 @@ static void stac_setup_gpio(struct hda_codec *codec) ...@@ -3915,6 +3915,7 @@ static void stac_setup_gpio(struct hda_codec *codec)
{ {
struct sigmatel_spec *spec = codec->spec; struct sigmatel_spec *spec = codec->spec;
spec->gpio_mask |= spec->eapd_mask;
if (spec->gpio_led) { if (spec->gpio_led) {
if (!spec->vref_mute_led_nid) { if (!spec->vref_mute_led_nid) {
spec->gpio_mask |= spec->gpio_led; spec->gpio_mask |= spec->gpio_led;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment