diff options
Diffstat (limited to 'sound/soc/codecs/max98095.c')
-rw-r--r-- | sound/soc/codecs/max98095.c | 158 |
1 files changed, 157 insertions, 1 deletions
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 0bb511a0388d..35179e2c23c9 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <asm/div64.h> | 25 | #include <asm/div64.h> |
26 | #include <sound/max98095.h> | 26 | #include <sound/max98095.h> |
27 | #include <sound/jack.h> | ||
27 | #include "max98095.h" | 28 | #include "max98095.h" |
28 | 29 | ||
29 | enum max98095_type { | 30 | enum max98095_type { |
@@ -51,6 +52,8 @@ struct max98095_priv { | |||
51 | u8 lin_state; | 52 | u8 lin_state; |
52 | unsigned int mic1pre; | 53 | unsigned int mic1pre; |
53 | unsigned int mic2pre; | 54 | unsigned int mic2pre; |
55 | struct snd_soc_jack *headphone_jack; | ||
56 | struct snd_soc_jack *mic_jack; | ||
54 | }; | 57 | }; |
55 | 58 | ||
56 | static const u8 max98095_reg_def[M98095_REG_CNT] = { | 59 | static const u8 max98095_reg_def[M98095_REG_CNT] = { |
@@ -2173,9 +2176,125 @@ static void max98095_handle_pdata(struct snd_soc_codec *codec) | |||
2173 | max98095_handle_bq_pdata(codec); | 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->pdata->jack_detect_delay) | ||
2230 | slew = max98095->pdata->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 | #ifdef CONFIG_PM | 2290 | #ifdef CONFIG_PM |
2177 | static int max98095_suspend(struct snd_soc_codec *codec) | 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 | max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2298 | max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2180 | 2299 | ||
2181 | return 0; | 2300 | return 0; |
@@ -2183,8 +2302,16 @@ static int max98095_suspend(struct snd_soc_codec *codec) | |||
2183 | 2302 | ||
2184 | static int max98095_resume(struct snd_soc_codec *codec) | 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 | max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 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 | return 0; | 2315 | return 0; |
2189 | } | 2316 | } |
2190 | #else | 2317 | #else |
@@ -2227,6 +2354,7 @@ static int max98095_probe(struct snd_soc_codec *codec) | |||
2227 | { | 2354 | { |
2228 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 2355 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
2229 | struct max98095_cdata *cdata; | 2356 | struct max98095_cdata *cdata; |
2357 | struct i2c_client *client; | ||
2230 | int ret = 0; | 2358 | int ret = 0; |
2231 | 2359 | ||
2232 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); | 2360 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); |
@@ -2238,6 +2366,8 @@ static int max98095_probe(struct snd_soc_codec *codec) | |||
2238 | /* reset the codec, the DSP core, and disable all interrupts */ | 2366 | /* reset the codec, the DSP core, and disable all interrupts */ |
2239 | max98095_reset(codec); | 2367 | max98095_reset(codec); |
2240 | 2368 | ||
2369 | client = to_i2c_client(codec->dev); | ||
2370 | |||
2241 | /* initialize private data */ | 2371 | /* initialize private data */ |
2242 | 2372 | ||
2243 | max98095->sysclk = (unsigned)-1; | 2373 | max98095->sysclk = (unsigned)-1; |
@@ -2266,11 +2396,23 @@ static int max98095_probe(struct snd_soc_codec *codec) | |||
2266 | max98095->mic1pre = 0; | 2396 | max98095->mic1pre = 0; |
2267 | max98095->mic2pre = 0; | 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 | ret = snd_soc_read(codec, M98095_0FF_REV_ID); | 2411 | ret = snd_soc_read(codec, M98095_0FF_REV_ID); |
2270 | if (ret < 0) { | 2412 | if (ret < 0) { |
2271 | dev_err(codec->dev, "Failure reading hardware revision: %d\n", | 2413 | dev_err(codec->dev, "Failure reading hardware revision: %d\n", |
2272 | ret); | 2414 | ret); |
2273 | goto err_access; | 2415 | goto err_irq; |
2274 | } | 2416 | } |
2275 | dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A'); | 2417 | dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A'); |
2276 | 2418 | ||
@@ -2306,14 +2448,28 @@ static int max98095_probe(struct snd_soc_codec *codec) | |||
2306 | 2448 | ||
2307 | max98095_add_widgets(codec); | 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 | err_access: | 2456 | err_access: |
2310 | return ret; | 2457 | return ret; |
2311 | } | 2458 | } |
2312 | 2459 | ||
2313 | static int max98095_remove(struct snd_soc_codec *codec) | 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 | max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2465 | max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2316 | 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); | ||
2472 | |||
2317 | return 0; | 2473 | return 0; |
2318 | } | 2474 | } |
2319 | 2475 | ||