[alsa-devel] [PATCH] ALSA: hda - Add snd_hda_jack_detect_state() helper function
David Henningsson
david.henningsson at canonical.com
Sat Jul 20 20:39:56 CEST 2013
On 07/19/2013 05:06 PM, Takashi Iwai wrote:
> 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.
>
> Signed-off-by: Takashi Iwai <tiwai at suse.de>
Acked-by: David Henningsson <david.henningsson at canonical.com>
Although I doubt this is needed on the input side. If we have more than
one input source that is fixed/phantom, we should always have a capture
switch rather than auto-mic switch, right?
> ---
> sound/pci/hda/hda_generic.c | 8 +++++---
> sound/pci/hda/hda_jack.c | 18 ++++++++++++------
> sound/pci/hda/hda_jack.h | 13 ++++++++++++-
> 3 files changed, 29 insertions(+), 10 deletions(-)
>
> diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
> index 8e77cbb..f5c2d1f 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,
> /* check each pin in the given array; returns true if any of them is plugged */
> static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
> {
> - int i, present = 0;
> + int i;
> + bool present = false;
>
> for (i = 0; i < num_pins; i++) {
> 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)
> /* don't detect pins retasked as inputs */
> if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN)
> continue;
> - present |= snd_hda_jack_detect(codec, nid);
> + if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT)
> + present = true;
> }
> return present;
> }
> @@ -3887,7 +3889,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
> /* don't detect pins retasked as outputs */
> if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN)
> continue;
> - if (snd_hda_jack_detect(codec, pin)) {
> + if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) {
> mux_select(codec, 0, spec->am_entry[i].idx);
> return;
> }
> diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
> index 3fd2973..dc93761 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)
> EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
>
> /**
> - * snd_hda_jack_detect - query pin Presence Detect status
> + * snd_hda_jack_detect_state - query pin Presence Detect status
> * @codec: the CODEC to sense
> * @nid: the pin NID to sense
> *
> - * Query and return the pin's Presence Detect status.
> + * Query and return the pin's Presence Detect status, as either
> + * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
> */
> -int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
> +int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
> {
> - u32 sense = snd_hda_pin_sense(codec, nid);
> - return get_jack_plug_state(sense);
> + struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
> + if (jack && jack->phantom_jack)
> + return HDA_JACK_PHANTOM;
> + else if (snd_hda_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE)
> + return HDA_JACK_PRESENT;
> + else
> + return HDA_JACK_NOT_PRESENT;
> }
> -EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
> +EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state);
>
> /**
> * 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 ec12abd..379420c 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,
> hda_nid_t gating_nid);
>
> u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
> -int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
> +
> +/* the jack state returned from snd_hda_jack_detect_state() */
> +enum {
> + HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM,
> +};
> +
> +int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid);
> +
> +static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
> +{
> + return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT;
> +}
>
> bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
>
>
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
More information about the Alsa-devel
mailing list