Commit 9dd90c5db0401061009183e6407feff3724ebc8b

Authored by Rhyland Klein
Committed by Mark Brown
1 parent 5f1cba63a3

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>

Showing 3 changed files with 191 additions and 1 deletions Side-by-side Diff

include/sound/max98095.h
... ... @@ -49,6 +49,18 @@
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
sound/soc/codecs/max98095.c
... ... @@ -24,6 +24,7 @@
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 {
... ... @@ -51,6 +52,8 @@
51 52 u8 lin_state;
52 53 unsigned int mic1pre;
53 54 unsigned int mic2pre;
  55 + struct snd_soc_jack *headphone_jack;
  56 + struct snd_soc_jack *mic_jack;
54 57 };
55 58  
56 59 static const u8 max98095_reg_def[M98095_REG_CNT] = {
57 60  
... ... @@ -2173,9 +2176,125 @@
2173 2176 max98095_handle_bq_pdata(codec);
2174 2177 }
2175 2178  
  2179 +static irqreturn_t max98095_report_jack(int irq, void *data)
  2180 +{
  2181 + struct snd_soc_codec *codec = data;
  2182 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
  2183 + unsigned int value;
  2184 + int hp_report = 0;
  2185 + int mic_report = 0;
  2186 +
  2187 + /* Read the Jack Status Register */
  2188 + value = snd_soc_read(codec, M98095_007_JACK_AUTO_STS);
  2189 +
  2190 + /* If ddone is not set, then detection isn't finished yet */
  2191 + if ((value & M98095_DDONE) == 0)
  2192 + return IRQ_NONE;
  2193 +
  2194 + /* if hp, check its bit, and if set, clear it */
  2195 + if ((value & M98095_HP_IN || value & M98095_LO_IN) &&
  2196 + max98095->headphone_jack)
  2197 + hp_report |= SND_JACK_HEADPHONE;
  2198 +
  2199 + /* if mic, check its bit, and if set, clear it */
  2200 + if ((value & M98095_MIC_IN) && max98095->mic_jack)
  2201 + mic_report |= SND_JACK_MICROPHONE;
  2202 +
  2203 + if (max98095->headphone_jack == max98095->mic_jack) {
  2204 + snd_soc_jack_report(max98095->headphone_jack,
  2205 + hp_report | mic_report,
  2206 + SND_JACK_HEADSET);
  2207 + } else {
  2208 + if (max98095->headphone_jack)
  2209 + snd_soc_jack_report(max98095->headphone_jack,
  2210 + hp_report, SND_JACK_HEADPHONE);
  2211 + if (max98095->mic_jack)
  2212 + snd_soc_jack_report(max98095->mic_jack,
  2213 + mic_report, SND_JACK_MICROPHONE);
  2214 + }
  2215 +
  2216 + return IRQ_HANDLED;
  2217 +}
  2218 +
  2219 +int max98095_jack_detect_enable(struct snd_soc_codec *codec)
  2220 +{
  2221 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
  2222 + int ret = 0;
  2223 + int detect_enable = M98095_JDEN;
  2224 + unsigned int slew = M98095_DEFAULT_SLEW_DELAY;
  2225 +
  2226 + if (max98095->pdata->jack_detect_pin5en)
  2227 + detect_enable |= M98095_PIN5EN;
  2228 +
  2229 + if (max98095->jack_detect_delay)
  2230 + slew = max98095->jack_detect_delay;
  2231 +
  2232 + ret = snd_soc_write(codec, M98095_08E_JACK_DC_SLEW, slew);
  2233 + if (ret < 0) {
  2234 + dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
  2235 + return ret;
  2236 + }
  2237 +
  2238 + /* configure auto detection to be enabled */
  2239 + ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, detect_enable);
  2240 + if (ret < 0) {
  2241 + dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
  2242 + return ret;
  2243 + }
  2244 +
  2245 + return ret;
  2246 +}
  2247 +
  2248 +int max98095_jack_detect_disable(struct snd_soc_codec *codec)
  2249 +{
  2250 + int ret = 0;
  2251 +
  2252 + /* configure auto detection to be disabled */
  2253 + ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, 0x0);
  2254 + if (ret < 0) {
  2255 + dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
  2256 + return ret;
  2257 + }
  2258 +
  2259 + return ret;
  2260 +}
  2261 +
  2262 +int max98095_jack_detect(struct snd_soc_codec *codec,
  2263 + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack)
  2264 +{
  2265 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
  2266 + struct i2c_client *client = to_i2c_client(codec->dev);
  2267 + int ret = 0;
  2268 +
  2269 + max98095->headphone_jack = hp_jack;
  2270 + max98095->mic_jack = mic_jack;
  2271 +
  2272 + /* only progress if we have at least 1 jack pointer */
  2273 + if (!hp_jack && !mic_jack)
  2274 + return -EINVAL;
  2275 +
  2276 + max98095_jack_detect_enable(codec);
  2277 +
  2278 + /* enable interrupts for headphone jack detection */
  2279 + ret = snd_soc_update_bits(codec, M98095_013_JACK_INT_EN,
  2280 + M98095_IDDONE, M98095_IDDONE);
  2281 + if (ret < 0) {
  2282 + dev_err(codec->dev, "Failed to cfg jack irqs %d\n", ret);
  2283 + return ret;
  2284 + }
  2285 +
  2286 + max98095_report_jack(client->irq, codec);
  2287 + return 0;
  2288 +}
  2289 +
2176 2290 #ifdef CONFIG_PM
2177 2291 static int max98095_suspend(struct snd_soc_codec *codec)
2178 2292 {
  2293 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
  2294 +
  2295 + if (max98095->headphone_jack || max98095->mic_jack)
  2296 + max98095_jack_detect_disable(codec);
  2297 +
2179 2298 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2180 2299  
2181 2300 return 0;
2182 2301  
... ... @@ -2183,8 +2302,16 @@
2183 2302  
2184 2303 static int max98095_resume(struct snd_soc_codec *codec)
2185 2304 {
  2305 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
  2306 + struct i2c_client *client = to_i2c_client(codec->dev);
  2307 +
2186 2308 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2187 2309  
  2310 + if (max98095->headphone_jack || max98095->mic_jack) {
  2311 + max98095_jack_detect_enable(codec);
  2312 + max98095_report_jack(client->irq, codec);
  2313 + }
  2314 +
2188 2315 return 0;
2189 2316 }
2190 2317 #else
... ... @@ -2227,6 +2354,7 @@
2227 2354 {
2228 2355 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2229 2356 struct max98095_cdata *cdata;
  2357 + struct i2c_client *client;
2230 2358 int ret = 0;
2231 2359  
2232 2360 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
... ... @@ -2238,6 +2366,8 @@
2238 2366 /* reset the codec, the DSP core, and disable all interrupts */
2239 2367 max98095_reset(codec);
2240 2368  
  2369 + client = to_i2c_client(codec->dev);
  2370 +
2241 2371 /* initialize private data */
2242 2372  
2243 2373 max98095->sysclk = (unsigned)-1;
2244 2374  
... ... @@ -2266,11 +2396,23 @@
2266 2396 max98095->mic1pre = 0;
2267 2397 max98095->mic2pre = 0;
2268 2398  
  2399 + if (client->irq) {
  2400 + /* register an audio interrupt */
  2401 + ret = request_threaded_irq(client->irq, NULL,
  2402 + max98095_report_jack,
  2403 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
  2404 + "max98095", codec);
  2405 + if (ret) {
  2406 + dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
  2407 + goto err_access;
  2408 + }
  2409 + }
  2410 +
2269 2411 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2270 2412 if (ret < 0) {
2271 2413 dev_err(codec->dev, "Failure reading hardware revision: %d\n",
2272 2414 ret);
2273   - goto err_access;
  2415 + goto err_irq;
2274 2416 }
2275 2417 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
2276 2418  
2277 2419  
2278 2420  
... ... @@ -2306,13 +2448,27 @@
2306 2448  
2307 2449 max98095_add_widgets(codec);
2308 2450  
  2451 + return 0;
  2452 +
  2453 +err_irq:
  2454 + if (client->irq)
  2455 + free_irq(client->irq, codec);
2309 2456 err_access:
2310 2457 return ret;
2311 2458 }
2312 2459  
2313 2460 static int max98095_remove(struct snd_soc_codec *codec)
2314 2461 {
  2462 + struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
  2463 + struct i2c_client *client = to_i2c_client(codec->dev);
  2464 +
2315 2465 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
  2466 +
  2467 + if (max98095->headphone_jack || max98095->mic_jack)
  2468 + max98095_jack_detect_disable(codec);
  2469 +
  2470 + if (client->irq)
  2471 + free_irq(client->irq, codec);
2316 2472  
2317 2473 return 0;
2318 2474 }
sound/soc/codecs/max98095.h
... ... @@ -175,11 +175,23 @@
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)
182 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)
  194 +
183 195 /* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 196 #define M98095_CLKMODE_MASK 0xFF
185 197  
... ... @@ -255,6 +267,10 @@
255 267 #define M98095_EQ2EN (1<<1)
256 268 #define M98095_EQ1EN (1<<0)
257 269  
  270 +/* M98095_089_JACK_DET_AUTO */
  271 + #define M98095_PIN5EN (1<<2)
  272 + #define M98095_JDEN (1<<7)
  273 +
258 274 /* M98095_090_PWR_EN_IN */
259 275 #define M98095_INEN (1<<7)
260 276 #define M98095_MB2EN (1<<3)
... ... @@ -295,6 +311,12 @@
295 311 /* Biquad filter coefficients */
296 312 #define M98095_174_DAI1_BQ_BASE 0x74
297 313 #define M98095_17E_DAI2_BQ_BASE 0x7E
  314 +
  315 +/* Default Delay used in Slew Rate Calculation for Jack detection */
  316 +#define M98095_DEFAULT_SLEW_DELAY 0x18
  317 +
  318 +extern int max98095_jack_detect(struct snd_soc_codec *codec,
  319 + struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack);
298 320  
299 321 #endif