aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm5100.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-01-26 12:43:09 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-01 05:31:12 -0500
commit2633f736470e803ac9f5372a0d83ba108345a80a (patch)
tree5dfebf7eb0899a36f1dbe81b73ff28a4fe14957d /sound/soc/codecs/wm5100.c
parent24e0c57b8ed2b3a9fe07c07edc1c0062df5be8bf (diff)
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: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm5100.c')
-rw-r--r--sound/soc/codecs/wm5100.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index c6c382197fe2..f6b6ea898022 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -72,6 +72,7 @@ struct wm5100_priv {
72 bool jack_detecting; 72 bool jack_detecting;
73 bool jack_mic; 73 bool jack_mic;
74 int jack_mode; 74 int jack_mode;
75 int jack_flips;
75 76
76 struct wm5100_fll fll[2]; 77 struct wm5100_fll fll[2];
77 78
@@ -1996,6 +1997,19 @@ static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
1996 wm5100->jack_mode); 1997 wm5100->jack_mode);
1997} 1998}
1998 1999
2000static void wm5100_report_headphone(struct wm5100_priv *wm5100)
2001{
2002 dev_dbg(wm5100->dev, "Headphone detected\n");
2003 wm5100->jack_detecting = false;
2004 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2005 SND_JACK_HEADPHONE);
2006
2007 /* Increase the detection rate a bit for responsiveness. */
2008 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2009 WM5100_ACCDET_RATE_MASK,
2010 7 << WM5100_ACCDET_RATE_SHIFT);
2011}
2012
1999static void wm5100_micd_irq(struct wm5100_priv *wm5100) 2013static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2000{ 2014{
2001 unsigned int val; 2015 unsigned int val;
@@ -2020,6 +2034,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2020 dev_dbg(wm5100->dev, "Jack removal detected\n"); 2034 dev_dbg(wm5100->dev, "Jack removal detected\n");
2021 wm5100->jack_mic = false; 2035 wm5100->jack_mic = false;
2022 wm5100->jack_detecting = true; 2036 wm5100->jack_detecting = true;
2037 wm5100->jack_flips = 0;
2023 snd_soc_jack_report(wm5100->jack, 0, 2038 snd_soc_jack_report(wm5100->jack, 0,
2024 SND_JACK_LINEOUT | SND_JACK_HEADSET | 2039 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2025 SND_JACK_BTN_0); 2040 SND_JACK_BTN_0);
@@ -2058,10 +2073,16 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2058 /* If we detected a lower impedence during initial startup 2073 /* If we detected a lower impedence during initial startup
2059 * then we probably have the wrong polarity, flip it. Don't 2074 * then we probably have the wrong polarity, flip it. Don't
2060 * do this for the lowest impedences to speed up detection of 2075 * do this for the lowest impedences to speed up detection of
2061 * plain headphones. 2076 * plain headphones and give up if neither polarity looks
2077 * sensible.
2062 */ 2078 */
2063 if (wm5100->jack_detecting && (val & 0x3f8)) { 2079 if (wm5100->jack_detecting && (val & 0x3f8)) {
2064 wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); 2080 wm5100->jack_flips++;
2081
2082 if (wm5100->jack_flips > 1)
2083 wm5100_report_headphone(wm5100);
2084 else
2085 wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
2065 2086
2066 return; 2087 return;
2067 } 2088 }
@@ -2075,16 +2096,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2075 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, 2096 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
2076 SND_JACK_BTN_0); 2097 SND_JACK_BTN_0);
2077 } else if (wm5100->jack_detecting) { 2098 } else if (wm5100->jack_detecting) {
2078 dev_dbg(wm5100->dev, "Headphone detected\n"); 2099 wm5100_report_headphone(wm5100);
2079 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2080 SND_JACK_HEADPHONE);
2081
2082 /* Increase the detection rate a bit for
2083 * responsiveness.
2084 */
2085 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2086 WM5100_ACCDET_RATE_MASK,
2087 7 << WM5100_ACCDET_RATE_SHIFT);
2088 } 2100 }
2089 } 2101 }
2090} 2102}
@@ -2096,6 +2108,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2096 if (jack) { 2108 if (jack) {
2097 wm5100->jack = jack; 2109 wm5100->jack = jack;
2098 wm5100->jack_detecting = true; 2110 wm5100->jack_detecting = true;
2111 wm5100->jack_flips = 0;
2099 2112
2100 wm5100_set_detect_mode(wm5100, 0); 2113 wm5100_set_detect_mode(wm5100, 0);
2101 2114