aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8994.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r--sound/soc/codecs/wm8994.c110
1 files changed, 76 insertions, 34 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 283399468b0c..8232d5e73194 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -1535,6 +1535,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
1535static int wm8994_set_bias_level(struct snd_soc_codec *codec, 1535static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1536 enum snd_soc_bias_level level) 1536 enum snd_soc_bias_level level)
1537{ 1537{
1538 struct wm8994 *control = codec->control_data;
1538 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1539 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1539 1540
1540 switch (level) { 1541 switch (level) {
@@ -1551,7 +1552,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
1551 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1552 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1552 /* Tweak DC servo and DSP configuration for 1553 /* Tweak DC servo and DSP configuration for
1553 * improved performance. */ 1554 * improved performance. */
1554 if (wm8994->revision < 4) { 1555 if (control->type == WM8994 && wm8994->revision < 4) {
1555 /* Tweak DC servo and DSP configuration for 1556 /* Tweak DC servo and DSP configuration for
1556 * improved performance. */ 1557 * improved performance. */
1557 snd_soc_write(codec, 0x102, 0x3); 1558 snd_soc_write(codec, 0x102, 0x3);
@@ -2264,8 +2265,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2264{ 2265{
2265 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2266 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2266 struct wm8994_micdet *micdet; 2267 struct wm8994_micdet *micdet;
2268 struct wm8994 *control = codec->control_data;
2267 int reg; 2269 int reg;
2268 2270
2271 if (control->type != WM8994)
2272 return -EINVAL;
2273
2269 switch (micbias) { 2274 switch (micbias) {
2270 case 1: 2275 case 1:
2271 micdet = &wm8994->micdet[0]; 2276 micdet = &wm8994->micdet[0];
@@ -2334,11 +2339,13 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
2334 2339
2335static int wm8994_codec_probe(struct snd_soc_codec *codec) 2340static int wm8994_codec_probe(struct snd_soc_codec *codec)
2336{ 2341{
2342 struct wm8994 *control;
2337 struct wm8994_priv *wm8994; 2343 struct wm8994_priv *wm8994;
2338 struct snd_soc_dapm_context *dapm = &codec->dapm; 2344 struct snd_soc_dapm_context *dapm = &codec->dapm;
2339 int ret, i; 2345 int ret, i;
2340 2346
2341 codec->control_data = dev_get_drvdata(codec->dev->parent); 2347 codec->control_data = dev_get_drvdata(codec->dev->parent);
2348 control = codec->control_data;
2342 2349
2343 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); 2350 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
2344 if (wm8994 == NULL) 2351 if (wm8994 == NULL)
@@ -2369,41 +2376,67 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
2369 2376
2370 /* Set revision-specific configuration */ 2377 /* Set revision-specific configuration */
2371 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); 2378 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
2372 switch (wm8994->revision) { 2379 switch (control->type) {
2373 case 2: 2380 case WM8994:
2374 case 3: 2381 switch (wm8994->revision) {
2375 wm8994->hubs.dcs_codes = -5; 2382 case 2:
2376 wm8994->hubs.hp_startup_mode = 1; 2383 case 3:
2384 wm8994->hubs.dcs_codes = -5;
2385 wm8994->hubs.hp_startup_mode = 1;
2386 wm8994->hubs.dcs_readback_mode = 1;
2387 break;
2388 default:
2389 wm8994->hubs.dcs_readback_mode = 1;
2390 break;
2391 }
2392
2393 case WM8958:
2377 wm8994->hubs.dcs_readback_mode = 1; 2394 wm8994->hubs.dcs_readback_mode = 1;
2378 break; 2395 break;
2396
2379 default: 2397 default:
2380 wm8994->hubs.dcs_readback_mode = 1;
2381 break; 2398 break;
2382 } 2399 }
2383 2400
2384 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 2401 switch (control->type) {
2385 wm8994_mic_irq, "Mic 1 detect", wm8994); 2402 case WM8994:
2386 if (ret != 0) 2403 ret = wm8994_request_irq(codec->control_data,
2387 dev_warn(codec->dev, 2404 WM8994_IRQ_MIC1_DET,
2388 "Failed to request Mic1 detect IRQ: %d\n", ret); 2405 wm8994_mic_irq, "Mic 1 detect",
2389 2406 wm8994);
2390 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 2407 if (ret != 0)
2391 wm8994_mic_irq, "Mic 1 short", wm8994); 2408 dev_warn(codec->dev,
2392 if (ret != 0) 2409 "Failed to request Mic1 detect IRQ: %d\n",
2393 dev_warn(codec->dev, 2410 ret);
2394 "Failed to request Mic1 short IRQ: %d\n", ret); 2411
2395 2412 ret = wm8994_request_irq(codec->control_data,
2396 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 2413 WM8994_IRQ_MIC1_SHRT,
2397 wm8994_mic_irq, "Mic 2 detect", wm8994); 2414 wm8994_mic_irq, "Mic 1 short",
2398 if (ret != 0) 2415 wm8994);
2399 dev_warn(codec->dev, 2416 if (ret != 0)
2400 "Failed to request Mic2 detect IRQ: %d\n", ret); 2417 dev_warn(codec->dev,
2401 2418 "Failed to request Mic1 short IRQ: %d\n",
2402 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 2419 ret);
2403 wm8994_mic_irq, "Mic 2 short", wm8994); 2420
2404 if (ret != 0) 2421 ret = wm8994_request_irq(codec->control_data,
2405 dev_warn(codec->dev, 2422 WM8994_IRQ_MIC2_DET,
2406 "Failed to request Mic2 short IRQ: %d\n", ret); 2423 wm8994_mic_irq, "Mic 2 detect",
2424 wm8994);
2425 if (ret != 0)
2426 dev_warn(codec->dev,
2427 "Failed to request Mic2 detect IRQ: %d\n",
2428 ret);
2429
2430 ret = wm8994_request_irq(codec->control_data,
2431 WM8994_IRQ_MIC2_SHRT,
2432 wm8994_mic_irq, "Mic 2 short",
2433 wm8994);
2434 if (ret != 0)
2435 dev_warn(codec->dev,
2436 "Failed to request Mic2 short IRQ: %d\n",
2437 ret);
2438 break;
2439 }
2407 2440
2408 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 2441 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
2409 * configured on init - if a system wants to do this dynamically 2442 * configured on init - if a system wants to do this dynamically
@@ -2496,13 +2529,22 @@ err:
2496static int wm8994_codec_remove(struct snd_soc_codec *codec) 2529static int wm8994_codec_remove(struct snd_soc_codec *codec)
2497{ 2530{
2498 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2531 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2532 struct wm8994 *control = codec->control_data;
2499 2533
2500 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 2534 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
2501 2535
2502 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 2536 switch (control->type) {
2503 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 2537 case WM8994:
2504 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 2538 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
2505 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 2539 wm8994);
2540 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
2541 wm8994);
2542 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
2543 wm8994);
2544 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
2545 wm8994);
2546 break;
2547 }
2506 kfree(wm8994->retune_mobile_texts); 2548 kfree(wm8994->retune_mobile_texts);
2507 kfree(wm8994->drc_texts); 2549 kfree(wm8994->drc_texts);
2508 kfree(wm8994); 2550 kfree(wm8994);