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

ASoC: Implement WM835x microphone jack detection support

The WM8350 provides microphone presence and short circuit detection.
Integrate this with the ASoC jack reporting API.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>

+63
+2
include/linux/mfd/wm8350/audio.h
··· 492 492 */ 493 493 #define WM8350_JACK_L_LVL 0x0800 494 494 #define WM8350_JACK_R_LVL 0x0400 495 + #define WM8350_JACK_MICSCD_LVL 0x0200 496 + #define WM8350_JACK_MICSD_LVL 0x0100 495 497 496 498 /* 497 499 * WM8350 Platform setup
+58
sound/soc/codecs/wm8350.c
··· 54 54 struct wm8350_jack_data { 55 55 struct snd_soc_jack *jack; 56 56 int report; 57 + int short_report; 57 58 }; 58 59 59 60 struct wm8350_data { ··· 63 62 struct wm8350_output out2; 64 63 struct wm8350_jack_data hpl; 65 64 struct wm8350_jack_data hpr; 65 + struct wm8350_jack_data mic; 66 66 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 67 67 int fll_freq_out; 68 68 int fll_freq_in; ··· 1432 1430 } 1433 1431 EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); 1434 1432 1433 + static irqreturn_t wm8350_mic_handler(int irq, void *data) 1434 + { 1435 + struct wm8350_data *priv = data; 1436 + struct wm8350 *wm8350 = priv->codec.control_data; 1437 + u16 reg; 1438 + int report = 0; 1439 + 1440 + reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); 1441 + if (reg & WM8350_JACK_MICSCD_LVL) 1442 + report |= priv->mic.short_report; 1443 + if (reg & WM8350_JACK_MICSD_LVL) 1444 + report |= priv->mic.report; 1445 + 1446 + snd_soc_jack_report(priv->mic.jack, report, 1447 + priv->mic.report | priv->mic.short_report); 1448 + 1449 + return IRQ_HANDLED; 1450 + } 1451 + 1452 + /** 1453 + * wm8350_mic_jack_detect - Enable microphone jack detection. 1454 + * 1455 + * @codec: WM8350 codec 1456 + * @jack: jack to report detection events on 1457 + * @detect_report: value to report when presence detected 1458 + * @short_report: value to report when microphone short detected 1459 + * 1460 + * Enables the microphone jack detection of the WM8350. 1461 + */ 1462 + int wm8350_mic_jack_detect(struct snd_soc_codec *codec, 1463 + struct snd_soc_jack *jack, 1464 + int detect_report, int short_report) 1465 + { 1466 + struct wm8350_data *priv = codec->private_data; 1467 + struct wm8350 *wm8350 = codec->control_data; 1468 + 1469 + priv->mic.jack = jack; 1470 + priv->mic.report = detect_report; 1471 + priv->mic.short_report = short_report; 1472 + 1473 + wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1474 + wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1, WM8350_MIC_DET_ENA); 1475 + 1476 + snd_soc_dapm_force_enable_pin(codec, "Mic Bias"); 1477 + 1478 + return 0; 1479 + } 1480 + EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); 1481 + 1435 1482 static struct snd_soc_codec *wm8350_codec; 1436 1483 1437 1484 static int wm8350_probe(struct platform_device *pdev) ··· 1544 1493 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1545 1494 wm8350_hp_jack_handler, 0, "Right jack detect", 1546 1495 priv); 1496 + wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, 1497 + wm8350_mic_handler, 0, "Microphone short", priv); 1498 + wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, 1499 + wm8350_mic_handler, 0, "Microphone detect", priv); 1547 1500 1548 1501 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1549 1502 if (ret < 0) { ··· 1576 1521 WM8350_JDL_ENA | WM8350_JDR_ENA); 1577 1522 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1578 1523 1524 + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv); 1525 + wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv); 1579 1526 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); 1580 1527 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); 1581 1528 1582 1529 priv->hpl.jack = NULL; 1583 1530 priv->hpr.jack = NULL; 1531 + priv->mic.jack = NULL; 1584 1532 1585 1533 /* cancel any work waiting to be queued. */ 1586 1534 ret = cancel_delayed_work(&codec->delayed_work);
+3
sound/soc/codecs/wm8350.h
··· 25 25 26 26 int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, 27 27 struct snd_soc_jack *jack, int report); 28 + int wm8350_mic_jack_detect(struct snd_soc_codec *codec, 29 + struct snd_soc_jack *jack, 30 + int detect_report, int short_report); 28 31 29 32 #endif