diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-01-26 12:43:09 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-02-01 05:31:12 -0500 |
commit | 2633f736470e803ac9f5372a0d83ba108345a80a (patch) | |
tree | 5dfebf7eb0899a36f1dbe81b73ff28a4fe14957d /sound/soc/codecs/wm5100.c | |
parent | 24e0c57b8ed2b3a9fe07c07edc1c0062df5be8bf (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.c | 37 |
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 | ||
2000 | static 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 | |||
1999 | static void wm5100_micd_irq(struct wm5100_priv *wm5100) | 2013 | static 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 | ||