Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: max98095: add jack detection

This change adds the logic to support using the jack detect mechanism built
in to the codec to detect both when a jack was inserted and what type of
jack is present.

This change also supports the use of an external mechanism for headphone
detection. If this mechanism exists, when the max98095_jack_detect function
is called, the hp_jack is simply passed NULL.

This change supports both simple headphones, powered headphones, microphones
and headsets with both headphones and a mic.

Signed-off-by: Rhyland Klein <rklein@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Rhyland Klein and committed by
Mark Brown
9dd90c5d 5f1cba63

+191 -1
+12
include/sound/max98095.h
··· 49 49 */ 50 50 unsigned int digmic_left_mode:1; 51 51 unsigned int digmic_right_mode:1; 52 + 53 + /* Pin5 is the mechanical method of sensing jack insertion 54 + * but it is something that might not be supported. 55 + * 0 = PIN5 not supported 56 + * 1 = PIN5 supported 57 + */ 58 + int jack_detect_pin5en:1; 59 + 60 + /* Slew amount for jack detection. Calculated as 4 * (delay + 1). 61 + * Default delay is 24 to get a time of 100ms. 62 + */ 63 + unsigned int jack_detect_delay; 52 64 }; 53 65 54 66 #endif
+157 -1
sound/soc/codecs/max98095.c
··· 24 24 #include <linux/slab.h> 25 25 #include <asm/div64.h> 26 26 #include <sound/max98095.h> 27 + #include <sound/jack.h> 27 28 #include "max98095.h" 28 29 29 30 enum max98095_type { ··· 52 51 u8 lin_state; 53 52 unsigned int mic1pre; 54 53 unsigned int mic2pre; 54 + struct snd_soc_jack *headphone_jack; 55 + struct snd_soc_jack *mic_jack; 55 56 }; 56 57 57 58 static const u8 max98095_reg_def[M98095_REG_CNT] = { ··· 2176 2173 max98095_handle_bq_pdata(codec); 2177 2174 } 2178 2175 2176 + static irqreturn_t max98095_report_jack(int irq, void *data) 2177 + { 2178 + struct snd_soc_codec *codec = data; 2179 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2180 + unsigned int value; 2181 + int hp_report = 0; 2182 + int mic_report = 0; 2183 + 2184 + /* Read the Jack Status Register */ 2185 + value = snd_soc_read(codec, M98095_007_JACK_AUTO_STS); 2186 + 2187 + /* If ddone is not set, then detection isn't finished yet */ 2188 + if ((value & M98095_DDONE) == 0) 2189 + return IRQ_NONE; 2190 + 2191 + /* if hp, check its bit, and if set, clear it */ 2192 + if ((value & M98095_HP_IN || value & M98095_LO_IN) && 2193 + max98095->headphone_jack) 2194 + hp_report |= SND_JACK_HEADPHONE; 2195 + 2196 + /* if mic, check its bit, and if set, clear it */ 2197 + if ((value & M98095_MIC_IN) && max98095->mic_jack) 2198 + mic_report |= SND_JACK_MICROPHONE; 2199 + 2200 + if (max98095->headphone_jack == max98095->mic_jack) { 2201 + snd_soc_jack_report(max98095->headphone_jack, 2202 + hp_report | mic_report, 2203 + SND_JACK_HEADSET); 2204 + } else { 2205 + if (max98095->headphone_jack) 2206 + snd_soc_jack_report(max98095->headphone_jack, 2207 + hp_report, SND_JACK_HEADPHONE); 2208 + if (max98095->mic_jack) 2209 + snd_soc_jack_report(max98095->mic_jack, 2210 + mic_report, SND_JACK_MICROPHONE); 2211 + } 2212 + 2213 + return IRQ_HANDLED; 2214 + } 2215 + 2216 + int max98095_jack_detect_enable(struct snd_soc_codec *codec) 2217 + { 2218 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2219 + int ret = 0; 2220 + int detect_enable = M98095_JDEN; 2221 + unsigned int slew = M98095_DEFAULT_SLEW_DELAY; 2222 + 2223 + if (max98095->pdata->jack_detect_pin5en) 2224 + detect_enable |= M98095_PIN5EN; 2225 + 2226 + if (max98095->jack_detect_delay) 2227 + slew = max98095->jack_detect_delay; 2228 + 2229 + ret = snd_soc_write(codec, M98095_08E_JACK_DC_SLEW, slew); 2230 + if (ret < 0) { 2231 + dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret); 2232 + return ret; 2233 + } 2234 + 2235 + /* configure auto detection to be enabled */ 2236 + ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, detect_enable); 2237 + if (ret < 0) { 2238 + dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret); 2239 + return ret; 2240 + } 2241 + 2242 + return ret; 2243 + } 2244 + 2245 + int max98095_jack_detect_disable(struct snd_soc_codec *codec) 2246 + { 2247 + int ret = 0; 2248 + 2249 + /* configure auto detection to be disabled */ 2250 + ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, 0x0); 2251 + if (ret < 0) { 2252 + dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret); 2253 + return ret; 2254 + } 2255 + 2256 + return ret; 2257 + } 2258 + 2259 + int max98095_jack_detect(struct snd_soc_codec *codec, 2260 + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack) 2261 + { 2262 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2263 + struct i2c_client *client = to_i2c_client(codec->dev); 2264 + int ret = 0; 2265 + 2266 + max98095->headphone_jack = hp_jack; 2267 + max98095->mic_jack = mic_jack; 2268 + 2269 + /* only progress if we have at least 1 jack pointer */ 2270 + if (!hp_jack && !mic_jack) 2271 + return -EINVAL; 2272 + 2273 + max98095_jack_detect_enable(codec); 2274 + 2275 + /* enable interrupts for headphone jack detection */ 2276 + ret = snd_soc_update_bits(codec, M98095_013_JACK_INT_EN, 2277 + M98095_IDDONE, M98095_IDDONE); 2278 + if (ret < 0) { 2279 + dev_err(codec->dev, "Failed to cfg jack irqs %d\n", ret); 2280 + return ret; 2281 + } 2282 + 2283 + max98095_report_jack(client->irq, codec); 2284 + return 0; 2285 + } 2286 + 2179 2287 #ifdef CONFIG_PM 2180 2288 static int max98095_suspend(struct snd_soc_codec *codec) 2181 2289 { 2290 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2291 + 2292 + if (max98095->headphone_jack || max98095->mic_jack) 2293 + max98095_jack_detect_disable(codec); 2294 + 2182 2295 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); 2183 2296 2184 2297 return 0; ··· 2302 2183 2303 2184 static int max98095_resume(struct snd_soc_codec *codec) 2304 2185 { 2186 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2187 + struct i2c_client *client = to_i2c_client(codec->dev); 2188 + 2305 2189 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2190 + 2191 + if (max98095->headphone_jack || max98095->mic_jack) { 2192 + max98095_jack_detect_enable(codec); 2193 + max98095_report_jack(client->irq, codec); 2194 + } 2306 2195 2307 2196 return 0; 2308 2197 } ··· 2354 2227 { 2355 2228 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2356 2229 struct max98095_cdata *cdata; 2230 + struct i2c_client *client; 2357 2231 int ret = 0; 2358 2232 2359 2233 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); ··· 2365 2237 2366 2238 /* reset the codec, the DSP core, and disable all interrupts */ 2367 2239 max98095_reset(codec); 2240 + 2241 + client = to_i2c_client(codec->dev); 2368 2242 2369 2243 /* initialize private data */ 2370 2244 ··· 2396 2266 max98095->mic1pre = 0; 2397 2267 max98095->mic2pre = 0; 2398 2268 2269 + if (client->irq) { 2270 + /* register an audio interrupt */ 2271 + ret = request_threaded_irq(client->irq, NULL, 2272 + max98095_report_jack, 2273 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 2274 + "max98095", codec); 2275 + if (ret) { 2276 + dev_err(codec->dev, "Failed to request IRQ: %d\n", ret); 2277 + goto err_access; 2278 + } 2279 + } 2280 + 2399 2281 ret = snd_soc_read(codec, M98095_0FF_REV_ID); 2400 2282 if (ret < 0) { 2401 2283 dev_err(codec->dev, "Failure reading hardware revision: %d\n", 2402 2284 ret); 2403 - goto err_access; 2285 + goto err_irq; 2404 2286 } 2405 2287 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A'); 2406 2288 ··· 2448 2306 2449 2307 max98095_add_widgets(codec); 2450 2308 2309 + return 0; 2310 + 2311 + err_irq: 2312 + if (client->irq) 2313 + free_irq(client->irq, codec); 2451 2314 err_access: 2452 2315 return ret; 2453 2316 } 2454 2317 2455 2318 static int max98095_remove(struct snd_soc_codec *codec) 2456 2319 { 2320 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2321 + struct i2c_client *client = to_i2c_client(codec->dev); 2322 + 2457 2323 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); 2324 + 2325 + if (max98095->headphone_jack || max98095->mic_jack) 2326 + max98095_jack_detect_disable(codec); 2327 + 2328 + if (client->irq) 2329 + free_irq(client->irq, codec); 2458 2330 2459 2331 return 0; 2460 2332 }
+22
sound/soc/codecs/max98095.h
··· 175 175 176 176 /* MAX98095 Registers Bit Fields */ 177 177 178 + /* M98095_007_JACK_AUTO_STS */ 179 + #define M98095_MIC_IN (1<<3) 180 + #define M98095_LO_IN (1<<5) 181 + #define M98095_HP_IN (1<<6) 182 + #define M98095_DDONE (1<<7) 183 + 178 184 /* M98095_00F_HOST_CFG */ 179 185 #define M98095_SEG (1<<0) 180 186 #define M98095_XTEN (1<<1) 181 187 #define M98095_MDLLEN (1<<2) 188 + 189 + /* M98095_013_JACK_INT_EN */ 190 + #define M98095_IMIC_IN (1<<3) 191 + #define M98095_ILO_IN (1<<5) 192 + #define M98095_IHP_IN (1<<6) 193 + #define M98095_IDDONE (1<<7) 182 194 183 195 /* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */ 184 196 #define M98095_CLKMODE_MASK 0xFF ··· 267 255 #define M98095_EQ2EN (1<<1) 268 256 #define M98095_EQ1EN (1<<0) 269 257 258 + /* M98095_089_JACK_DET_AUTO */ 259 + #define M98095_PIN5EN (1<<2) 260 + #define M98095_JDEN (1<<7) 261 + 270 262 /* M98095_090_PWR_EN_IN */ 271 263 #define M98095_INEN (1<<7) 272 264 #define M98095_MB2EN (1<<3) ··· 311 295 /* Biquad filter coefficients */ 312 296 #define M98095_174_DAI1_BQ_BASE 0x74 313 297 #define M98095_17E_DAI2_BQ_BASE 0x7E 298 + 299 + /* Default Delay used in Slew Rate Calculation for Jack detection */ 300 + #define M98095_DEFAULT_SLEW_DELAY 0x18 301 + 302 + extern int max98095_jack_detect(struct snd_soc_codec *codec, 303 + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack); 314 304 315 305 #endif