aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-07-19 10:59:46 -0400
committerTakashi Iwai <tiwai@suse.de>2013-07-21 05:52:54 -0400
commit60ea8ca21b4584cebb8163879b50ab3d941090bf (patch)
tree0642ef12921c948f9697efc877c6b4beda88c5bc /sound
parente4c3bce26de240457370d00ce396602cc98bb3cc (diff)
ALSA: hda - Add snd_hda_jack_detect_state() helper function
snd_hda_jack_detect() function returns a boolean value for a jack plugged in or not, but it also returns always true when the corresponding pin is phantom (i.e. fixed). This is OK in most cases, but it makes the generic parser misbehaving about the auto-mute or auto-mic switching, e.g. when one of headphone pins is a fixed. Namely, the driver decides whether to mute the speaker or not, just depending on the headphone plug state: if one of the headphone jacks is seen as active, then the speaker is muted. Thus this will result always in the muted speaker output. So, the problem is the function returns a boolean, after all, although we need to think of "phantom" jack. Now a new function, snd_hda_jack_detect_state() is introduced to return these tristates. The generic parser uses this function for checking the headphone or mic jack states. Meanwhile, the behavior of snd_hda_jack_detect() is kept as is, for keeping compatibility in other driver codes. Acked-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_generic.c8
-rw-r--r--sound/pci/hda/hda_jack.c18
-rw-r--r--sound/pci/hda/hda_jack.h13
3 files changed, 29 insertions, 10 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 8e77cbbad871..f5c2d1ff1a09 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3724,7 +3724,8 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
3724/* check each pin in the given array; returns true if any of them is plugged */ 3724/* check each pin in the given array; returns true if any of them is plugged */
3725static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3725static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3726{ 3726{
3727 int i, present = 0; 3727 int i;
3728 bool present = false;
3728 3729
3729 for (i = 0; i < num_pins; i++) { 3730 for (i = 0; i < num_pins; i++) {
3730 hda_nid_t nid = pins[i]; 3731 hda_nid_t nid = pins[i];
@@ -3733,7 +3734,8 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3733 /* don't detect pins retasked as inputs */ 3734 /* don't detect pins retasked as inputs */
3734 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN) 3735 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN)
3735 continue; 3736 continue;
3736 present |= snd_hda_jack_detect(codec, nid); 3737 if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT)
3738 present = true;
3737 } 3739 }
3738 return present; 3740 return present;
3739} 3741}
@@ -3887,7 +3889,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
3887 /* don't detect pins retasked as outputs */ 3889 /* don't detect pins retasked as outputs */
3888 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) 3890 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN)
3889 continue; 3891 continue;
3890 if (snd_hda_jack_detect(codec, pin)) { 3892 if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) {
3891 mux_select(codec, 0, spec->am_entry[i].idx); 3893 mux_select(codec, 0, spec->am_entry[i].idx);
3892 return; 3894 return;
3893 } 3895 }
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 3fd2973183e2..dc93761a4bc5 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -194,18 +194,24 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
194EXPORT_SYMBOL_HDA(snd_hda_pin_sense); 194EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
195 195
196/** 196/**
197 * snd_hda_jack_detect - query pin Presence Detect status 197 * snd_hda_jack_detect_state - query pin Presence Detect status
198 * @codec: the CODEC to sense 198 * @codec: the CODEC to sense
199 * @nid: the pin NID to sense 199 * @nid: the pin NID to sense
200 * 200 *
201 * Query and return the pin's Presence Detect status. 201 * Query and return the pin's Presence Detect status, as either
202 * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
202 */ 203 */
203int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 204int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
204{ 205{
205 u32 sense = snd_hda_pin_sense(codec, nid); 206 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
206 return get_jack_plug_state(sense); 207 if (jack && jack->phantom_jack)
208 return HDA_JACK_PHANTOM;
209 else if (snd_hda_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE)
210 return HDA_JACK_PRESENT;
211 else
212 return HDA_JACK_NOT_PRESENT;
207} 213}
208EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 214EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state);
209 215
210/** 216/**
211 * snd_hda_jack_detect_enable - enable the jack-detection 217 * snd_hda_jack_detect_enable - enable the jack-detection
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index ec12abd45263..379420c44eef 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -75,7 +75,18 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
75 hda_nid_t gating_nid); 75 hda_nid_t gating_nid);
76 76
77u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 77u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
78int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 78
79/* the jack state returned from snd_hda_jack_detect_state() */
80enum {
81 HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM,
82};
83
84int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid);
85
86static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
87{
88 return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT;
89}
79 90
80bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); 91bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
81 92