diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-16 11:54:12 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-17 05:27:19 -0400 |
commit | 2a0761a35b70f170a9c14ecbcb6a959fb6e7bdf3 (patch) | |
tree | 545aa27b2a00a3494c046e0856a5b30e4724475a /sound/soc/codecs/wm8350.c | |
parent | fbc2dae854da5fc44e2ce2f97446c8bd283c7e17 (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.c | 58 |
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 { | |||
54 | struct wm8350_jack_data { | 54 | struct 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 | ||
59 | struct wm8350_data { | 60 | struct 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 | } |
1431 | EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); | 1433 | EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); |
1432 | 1434 | ||
1435 | static 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 | */ | ||
1464 | int 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 | } | ||
1482 | EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); | ||
1483 | |||
1433 | static struct snd_soc_codec *wm8350_codec; | 1484 | static struct snd_soc_codec *wm8350_codec; |
1434 | 1485 | ||
1435 | static int wm8350_probe(struct platform_device *pdev) | 1486 | static 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); |