@@ -72,6 +72,7 @@ struct wm5100_priv {
72
72
bool jack_detecting ;
73
73
bool jack_mic ;
74
74
int jack_mode ;
75
+ int jack_flips ;
75
76
76
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
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
2013
static void wm5100_micd_irq (struct wm5100_priv * wm5100 )
2000
2014
{
2001
2015
unsigned int val ;
@@ -2020,6 +2034,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2020
2034
dev_dbg (wm5100 -> dev , "Jack removal detected\n" );
2021
2035
wm5100 -> jack_mic = false;
2022
2036
wm5100 -> jack_detecting = true;
2037
+ wm5100 -> jack_flips = 0 ;
2023
2038
snd_soc_jack_report (wm5100 -> jack , 0 ,
2024
2039
SND_JACK_LINEOUT | SND_JACK_HEADSET |
2025
2040
SND_JACK_BTN_0 );
@@ -2058,10 +2073,16 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2058
2073
/* If we detected a lower impedence during initial startup
2059
2074
* then we probably have the wrong polarity, flip it. Don't
2060
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
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
2087
return ;
2067
2088
}
@@ -2075,16 +2096,7 @@ static void wm5100_micd_irq(struct wm5100_priv *wm5100)
2075
2096
snd_soc_jack_report (wm5100 -> jack , SND_JACK_BTN_0 ,
2076
2097
SND_JACK_BTN_0 );
2077
2098
} else if (wm5100 -> jack_detecting ) {
2078
- dev_dbg (wm5100 -> dev , "Headphone detected\n" );
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 );
2099
+ wm5100_report_headphone (wm5100 );
2088
2100
}
2089
2101
}
2090
2102
}
@@ -2096,6 +2108,7 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2096
2108
if (jack ) {
2097
2109
wm5100 -> jack = jack ;
2098
2110
wm5100 -> jack_detecting = true;
2111
+ wm5100 -> jack_flips = 0 ;
2099
2112
2100
2113
wm5100_set_detect_mode (wm5100 , 0 );
2101
2114
0 commit comments