aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8350.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-16 11:54:12 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-03-17 05:27:19 -0400
commit2a0761a35b70f170a9c14ecbcb6a959fb6e7bdf3 (patch)
tree545aa27b2a00a3494c046e0856a5b30e4724475a /sound/soc/codecs/wm8350.c
parentfbc2dae854da5fc44e2ce2f97446c8bd283c7e17 (diff)
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>
Diffstat (limited to 'sound/soc/codecs/wm8350.c')
-rw-r--r--sound/soc/codecs/wm8350.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index df2c6d9617fb..ff6c10155ee6 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -54,6 +54,7 @@ struct wm8350_output {
54struct wm8350_jack_data { 54struct wm8350_jack_data {
55 struct snd_soc_jack *jack; 55 struct snd_soc_jack *jack;
56 int report; 56 int report;
57 int short_report;
57}; 58};
58 59
59struct wm8350_data { 60struct wm8350_data {
@@ -62,6 +63,7 @@ struct wm8350_data {
62 struct wm8350_output out2; 63 struct wm8350_output out2;
63 struct wm8350_jack_data hpl; 64 struct wm8350_jack_data hpl;
64 struct wm8350_jack_data hpr; 65 struct wm8350_jack_data hpr;
66 struct wm8350_jack_data mic;
65 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 67 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
66 int fll_freq_out; 68 int fll_freq_out;
67 int fll_freq_in; 69 int fll_freq_in;
@@ -1430,6 +1432,55 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1430} 1432}
1431EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); 1433EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
1432 1434
1435static irqreturn_t wm8350_mic_handler(int irq, void *data)
1436{
1437 struct wm8350_data *priv = data;
1438 struct wm8350 *wm8350 = priv->codec.control_data;
1439 u16 reg;
1440 int report = 0;
1441
1442 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1443 if (reg & WM8350_JACK_MICSCD_LVL)
1444 report |= priv->mic.short_report;
1445 if (reg & WM8350_JACK_MICSD_LVL)
1446 report |= priv->mic.report;
1447
1448 snd_soc_jack_report(priv->mic.jack, report,
1449 priv->mic.report | priv->mic.short_report);
1450
1451 return IRQ_HANDLED;
1452}
1453
1454/**
1455 * wm8350_mic_jack_detect - Enable microphone jack detection.
1456 *
1457 * @codec: WM8350 codec
1458 * @jack: jack to report detection events on
1459 * @detect_report: value to report when presence detected
1460 * @short_report: value to report when microphone short detected
1461 *
1462 * Enables the microphone jack detection of the WM8350.
1463 */
1464int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1465 struct snd_soc_jack *jack,
1466 int detect_report, int short_report)
1467{
1468 struct wm8350_data *priv = codec->private_data;
1469 struct wm8350 *wm8350 = codec->control_data;
1470
1471 priv->mic.jack = jack;
1472 priv->mic.report = detect_report;
1473 priv->mic.short_report = short_report;
1474
1475 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1476 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1, WM8350_MIC_DET_ENA);
1477
1478 snd_soc_dapm_force_enable_pin(codec, "Mic Bias");
1479
1480 return 0;
1481}
1482EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1483
1433static struct snd_soc_codec *wm8350_codec; 1484static struct snd_soc_codec *wm8350_codec;
1434 1485
1435static int wm8350_probe(struct platform_device *pdev) 1486static int wm8350_probe(struct platform_device *pdev)
@@ -1493,6 +1544,10 @@ static int wm8350_probe(struct platform_device *pdev)
1493 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1544 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1494 wm8350_hp_jack_handler, 0, "Right jack detect", 1545 wm8350_hp_jack_handler, 0, "Right jack detect",
1495 priv); 1546 priv);
1547 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD,
1548 wm8350_mic_handler, 0, "Microphone short", priv);
1549 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
1550 wm8350_mic_handler, 0, "Microphone detect", priv);
1496 1551
1497 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1552 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1498 if (ret < 0) { 1553 if (ret < 0) {
@@ -1521,11 +1576,14 @@ static int wm8350_remove(struct platform_device *pdev)
1521 WM8350_JDL_ENA | WM8350_JDR_ENA); 1576 WM8350_JDL_ENA | WM8350_JDR_ENA);
1522 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1577 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1523 1578
1579 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv);
1580 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv);
1524 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); 1581 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); 1582 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1526 1583
1527 priv->hpl.jack = NULL; 1584 priv->hpl.jack = NULL;
1528 priv->hpr.jack = NULL; 1585 priv->hpr.jack = NULL;
1586 priv->mic.jack = NULL;
1529 1587
1530 /* cancel any work waiting to be queued. */ 1588 /* cancel any work waiting to be queued. */
1531 ret = cancel_delayed_work(&codec->delayed_work); 1589 ret = cancel_delayed_work(&codec->delayed_work);