aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8350.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8350.c')
-rw-r--r--sound/soc/codecs/wm8350.c73
1 files changed, 54 insertions, 19 deletions
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 07ba7e3f6a8..6d6dc9efe91 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -26,6 +26,7 @@
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <trace/events/asoc.h>
29 30
30#include "wm8350.h" 31#include "wm8350.h"
31 32
@@ -53,6 +54,7 @@ struct wm8350_output {
53 54
54struct wm8350_jack_data { 55struct wm8350_jack_data {
55 struct snd_soc_jack *jack; 56 struct snd_soc_jack *jack;
57 struct delayed_work work;
56 int report; 58 int report;
57 int short_report; 59 int short_report;
58}; 60};
@@ -1335,45 +1337,69 @@ static int wm8350_resume(struct snd_soc_codec *codec)
1335 return 0; 1337 return 0;
1336} 1338}
1337 1339
1338static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) 1340static void wm8350_hp_work(struct wm8350_data *priv,
1341 struct wm8350_jack_data *jack,
1342 u16 mask)
1339{ 1343{
1340 struct wm8350_data *priv = data;
1341 struct wm8350 *wm8350 = priv->codec.control_data; 1344 struct wm8350 *wm8350 = priv->codec.control_data;
1342 u16 reg; 1345 u16 reg;
1343 int report; 1346 int report;
1344 int mask; 1347
1348 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1349 if (reg & mask)
1350 report = jack->report;
1351 else
1352 report = 0;
1353
1354 snd_soc_jack_report(jack->jack, report, jack->report);
1355
1356}
1357
1358static void wm8350_hpl_work(struct work_struct *work)
1359{
1360 struct wm8350_data *priv =
1361 container_of(work, struct wm8350_data, hpl.work.work);
1362
1363 wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL);
1364}
1365
1366static void wm8350_hpr_work(struct work_struct *work)
1367{
1368 struct wm8350_data *priv =
1369 container_of(work, struct wm8350_data, hpr.work.work);
1370
1371 wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
1372}
1373
1374static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1375{
1376 struct wm8350_data *priv = data;
1377 struct wm8350 *wm8350 = priv->codec.control_data;
1345 struct wm8350_jack_data *jack = NULL; 1378 struct wm8350_jack_data *jack = NULL;
1346 1379
1347 switch (irq - wm8350->irq_base) { 1380 switch (irq - wm8350->irq_base) {
1348 case WM8350_IRQ_CODEC_JCK_DET_L: 1381 case WM8350_IRQ_CODEC_JCK_DET_L:
1382#ifndef CONFIG_SND_SOC_WM8350_MODULE
1383 trace_snd_soc_jack_irq("WM8350 HPL");
1384#endif
1349 jack = &priv->hpl; 1385 jack = &priv->hpl;
1350 mask = WM8350_JACK_L_LVL;
1351 break; 1386 break;
1352 1387
1353 case WM8350_IRQ_CODEC_JCK_DET_R: 1388 case WM8350_IRQ_CODEC_JCK_DET_R:
1389#ifndef CONFIG_SND_SOC_WM8350_MODULE
1390 trace_snd_soc_jack_irq("WM8350 HPR");
1391#endif
1354 jack = &priv->hpr; 1392 jack = &priv->hpr;
1355 mask = WM8350_JACK_R_LVL;
1356 break; 1393 break;
1357 1394
1358 default: 1395 default:
1359 BUG(); 1396 BUG();
1360 } 1397 }
1361 1398
1362 if (!jack->jack) { 1399 if (device_may_wakeup(wm8350->dev))
1363 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); 1400 pm_wakeup_event(wm8350->dev, 250);
1364 return IRQ_NONE;
1365 }
1366 1401
1367 /* Debounce */ 1402 schedule_delayed_work(&jack->work, 200);
1368 msleep(200);
1369
1370 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1371 if (reg & mask)
1372 report = jack->report;
1373 else
1374 report = 0;
1375
1376 snd_soc_jack_report(jack->jack, report, jack->report);
1377 1403
1378 return IRQ_HANDLED; 1404 return IRQ_HANDLED;
1379} 1405}
@@ -1437,6 +1463,10 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
1437 u16 reg; 1463 u16 reg;
1438 int report = 0; 1464 int report = 0;
1439 1465
1466#ifndef CONFIG_SND_SOC_WM8350_MODULE
1467 trace_snd_soc_jack_irq("WM8350 mic");
1468#endif
1469
1440 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); 1470 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1441 if (reg & WM8350_JACK_MICSCD_LVL) 1471 if (reg & WM8350_JACK_MICSCD_LVL)
1442 report |= priv->mic.short_report; 1472 report |= priv->mic.short_report;
@@ -1552,6 +1582,8 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1552 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1582 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1553 1583
1554 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); 1584 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work);
1585 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
1586 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
1555 1587
1556 /* Enable the codec */ 1588 /* Enable the codec */
1557 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1589 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1641,6 +1673,9 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1641 priv->hpr.jack = NULL; 1673 priv->hpr.jack = NULL;
1642 priv->mic.jack = NULL; 1674 priv->mic.jack = NULL;
1643 1675
1676 cancel_delayed_work_sync(&priv->hpl.work);
1677 cancel_delayed_work_sync(&priv->hpr.work);
1678
1644 /* if there was any work waiting then we run it now and 1679 /* if there was any work waiting then we run it now and
1645 * wait for its completion */ 1680 * wait for its completion */
1646 flush_delayed_work_sync(&codec->dapm.delayed_work); 1681 flush_delayed_work_sync(&codec->dapm.delayed_work);