Commit 2633f736 authored by Mark Brown's avatar Mark Brown

ASoC: wm5100: Handle failures to determine accessory polarity

If we get an indeterminate impedance with both headset polarities then
give up and report the accessory as a headphone rather than continually
retrying.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 24e0c57b
...@@ -72,6 +72,7 @@ struct wm5100_priv { ...@@ -72,6 +72,7 @@ struct wm5100_priv {
bool jack_detecting; bool jack_detecting;
bool jack_mic; bool jack_mic;
int jack_mode; int jack_mode;
int jack_flips;
struct wm5100_fll fll[2]; struct wm5100_fll fll[2];
...@@ -1996,6 +1997,19 @@ static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode) ...@@ -1996,6 +1997,19 @@ static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
wm5100->jack_mode); wm5100->jack_mode);
} }
static void wm5100_report_headphone(struct wm5100_priv *wm5100)
{
dev_dbg(wm5100->dev, "Headphone detected\n");
wm5100->jack_detecting = false;
snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
SND_JACK_HEADPHONE);
/* Increase the detection rate a bit for responsiveness. */
regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
WM5100_ACCDET_RATE_MASK,
7 << WM5100_ACCDET_RATE_SHIFT);
}
static void wm5100_micd_irq(struct wm5100_priv *wm5100) static void wm5100_micd_irq(struct wm5100_priv *wm5100)
{ {
unsigned int val; unsigned int val;
...@@ -2020,6 +2034,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) ...@@ -2020,6 +2034,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
dev_dbg(wm5100->dev, "Jack removal detected\n"); dev_dbg(wm5100->dev, "Jack removal detected\n");
wm5100->jack_mic = false; wm5100->jack_mic = false;
wm5100->jack_detecting = true; wm5100->jack_detecting = true;
wm5100->jack_flips = 0;
snd_soc_jack_report(wm5100->jack, 0, snd_soc_jack_report(wm5100->jack, 0,
SND_JACK_LINEOUT | SND_JACK_HEADSET | SND_JACK_LINEOUT | SND_JACK_HEADSET |
SND_JACK_BTN_0); SND_JACK_BTN_0);
...@@ -2058,10 +2073,16 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) ...@@ -2058,10 +2073,16 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
/* If we detected a lower impedence during initial startup /* If we detected a lower impedence during initial startup
* then we probably have the wrong polarity, flip it. Don't * then we probably have the wrong polarity, flip it. Don't
* do this for the lowest impedences to speed up detection of * do this for the lowest impedences to speed up detection of
* plain headphones. * plain headphones and give up if neither polarity looks
* sensible.
*/ */
if (wm5100->jack_detecting && (val & 0x3f8)) { if (wm5100->jack_detecting && (val & 0x3f8)) {
wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); wm5100->jack_flips++;
if (wm5100->jack_flips > 1)
wm5100_report_headphone(wm5100);
else
wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
return; return;
} }
...@@ -2075,16 +2096,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100) ...@@ -2075,16 +2096,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
SND_JACK_BTN_0); SND_JACK_BTN_0);
} else if (wm5100->jack_detecting) { } else if (wm5100->jack_detecting) {
dev_dbg(wm5100->dev, "Headphone detected\n"); wm5100_report_headphone(wm5100);
snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
SND_JACK_HEADPHONE);
/* Increase the detection rate a bit for
* responsiveness.
*/
regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
WM5100_ACCDET_RATE_MASK,
7 << WM5100_ACCDET_RATE_SHIFT);
} }
} }
} }
...@@ -2096,6 +2108,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) ...@@ -2096,6 +2108,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
if (jack) { if (jack) {
wm5100->jack = jack; wm5100->jack = jack;
wm5100->jack_detecting = true; wm5100->jack_detecting = true;
wm5100->jack_flips = 0;
wm5100_set_detect_mode(wm5100, 0); wm5100_set_detect_mode(wm5100, 0);
......
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