summaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_generic.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-12-20 15:36:30 +0100
committerTakashi Iwai <tiwai@suse.de>2013-01-12 08:34:19 +0100
commitd5a9f1bb38354ef4786d7fd761d75594bc33f7d2 (patch)
tree6755b8d3cba32e2eb9c7235b7fe41ca5d1848f35 /sound/pci/hda/hda_generic.c
parent64049c81df38aa5f550cc0fae9c74c6bd5c31e58 (diff)
downloadlwn-d5a9f1bb38354ef4786d7fd761d75594bc33f7d2.tar.gz
lwn-d5a9f1bb38354ef4786d7fd761d75594bc33f7d2.zip
ALSA: hda - Dynamically turn on/off EAPD in generic codec driver
When spec->own_eapd_ctl isn't set, try to turn on/off EAPD on demand for each pin. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_generic.c')
-rw-r--r--sound/pci/hda/hda_generic.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index a133fcfd2fb4..46b00e0756c5 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -523,6 +523,18 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
}
EXPORT_SYMBOL_HDA(snd_hda_activate_path);
+/* turn on/off EAPD on the given pin */
+static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable)
+{
+ struct hda_gen_spec *spec = codec->spec;
+ if (spec->own_eapd_ctl ||
+ !(snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD))
+ return;
+ snd_hda_codec_update_cache(codec, pin, 0,
+ AC_VERB_SET_EAPD_BTLENABLE,
+ enable ? 0x02 : 0x00);
+}
+
/*
* Helper functions for creating mixer ctl elements
@@ -1485,7 +1497,9 @@ static int set_multi_io(struct hda_codec *codec, int idx, bool output)
if (output) {
snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT);
snd_hda_activate_path(codec, path, true, true);
+ set_pin_eapd(codec, nid, true);
} else {
+ set_pin_eapd(codec, nid, false);
snd_hda_activate_path(codec, path, false, true);
snd_hda_set_pin_ctl_cache(codec, nid,
spec->multi_io[idx].ctl_in);
@@ -2418,6 +2432,7 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
val = 0;
val |= pin_bits;
snd_hda_set_pin_ctl(codec, nid, val);
+ set_pin_eapd(codec, nid, !mute);
}
}
@@ -3351,7 +3366,6 @@ EXPORT_SYMBOL_HDA(snd_hda_gen_build_pcms);
static void set_output_and_unmute(struct hda_codec *codec, hda_nid_t pin,
int pin_type, hda_nid_t dac)
{
- struct hda_gen_spec *spec = codec->spec;
struct nid_path *path;
snd_hda_set_pin_ctl_cache(codec, pin, pin_type);
@@ -3361,11 +3375,7 @@ static void set_output_and_unmute(struct hda_codec *codec, hda_nid_t pin,
if (path->active)
return;
snd_hda_activate_path(codec, path, true, true);
-
- if (!spec->own_eapd_ctl &&
- (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD))
- snd_hda_codec_update_cache(codec, pin, 0,
- AC_VERB_SET_EAPD_BTLENABLE, 0x02);
+ set_pin_eapd(codec, pin, true);
}
/* initialize primary output paths */