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.c105
1 files changed, 67 insertions, 38 deletions
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 7611add7f8c3..6d6dc9efe914 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -24,9 +24,9 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <trace/events/asoc.h>
30 30
31#include "wm8350.h" 31#include "wm8350.h"
32 32
@@ -54,6 +54,7 @@ struct wm8350_output {
54 54
55struct wm8350_jack_data { 55struct wm8350_jack_data {
56 struct snd_soc_jack *jack; 56 struct snd_soc_jack *jack;
57 struct delayed_work work;
57 int report; 58 int report;
58 int short_report; 59 int short_report;
59}; 60};
@@ -230,8 +231,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
230 */ 231 */
231static void wm8350_pga_work(struct work_struct *work) 232static void wm8350_pga_work(struct work_struct *work)
232{ 233{
233 struct snd_soc_codec *codec = 234 struct snd_soc_dapm_context *dapm =
234 container_of(work, struct snd_soc_codec, delayed_work.work); 235 container_of(work, struct snd_soc_dapm_context, delayed_work.work);
236 struct snd_soc_codec *codec = dapm->codec;
235 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); 237 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
236 struct wm8350_output *out1 = &wm8350_data->out1, 238 struct wm8350_output *out1 = &wm8350_data->out1,
237 *out2 = &wm8350_data->out2; 239 *out2 = &wm8350_data->out2;
@@ -302,8 +304,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
302 out->ramp = WM8350_RAMP_UP; 304 out->ramp = WM8350_RAMP_UP;
303 out->active = 1; 305 out->active = 1;
304 306
305 if (!delayed_work_pending(&codec->delayed_work)) 307 if (!delayed_work_pending(&codec->dapm.delayed_work))
306 schedule_delayed_work(&codec->delayed_work, 308 schedule_delayed_work(&codec->dapm.delayed_work,
307 msecs_to_jiffies(1)); 309 msecs_to_jiffies(1));
308 break; 310 break;
309 311
@@ -311,8 +313,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
311 out->ramp = WM8350_RAMP_DOWN; 313 out->ramp = WM8350_RAMP_DOWN;
312 out->active = 0; 314 out->active = 0;
313 315
314 if (!delayed_work_pending(&codec->delayed_work)) 316 if (!delayed_work_pending(&codec->dapm.delayed_work))
315 schedule_delayed_work(&codec->delayed_work, 317 schedule_delayed_work(&codec->dapm.delayed_work,
316 msecs_to_jiffies(1)); 318 msecs_to_jiffies(1));
317 break; 319 break;
318 } 320 }
@@ -786,9 +788,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
786 788
787static int wm8350_add_widgets(struct snd_soc_codec *codec) 789static int wm8350_add_widgets(struct snd_soc_codec *codec)
788{ 790{
791 struct snd_soc_dapm_context *dapm = &codec->dapm;
789 int ret; 792 int ret;
790 793
791 ret = snd_soc_dapm_new_controls(codec, 794 ret = snd_soc_dapm_new_controls(dapm,
792 wm8350_dapm_widgets, 795 wm8350_dapm_widgets,
793 ARRAY_SIZE(wm8350_dapm_widgets)); 796 ARRAY_SIZE(wm8350_dapm_widgets));
794 if (ret != 0) { 797 if (ret != 0) {
@@ -797,7 +800,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
797 } 800 }
798 801
799 /* set up audio paths */ 802 /* set up audio paths */
800 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 803 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
801 if (ret != 0) { 804 if (ret != 0) {
802 dev_err(codec->dev, "DAPM route register failed\n"); 805 dev_err(codec->dev, "DAPM route register failed\n");
803 return ret; 806 return ret;
@@ -1184,7 +1187,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1184 break; 1187 break;
1185 1188
1186 case SND_SOC_BIAS_STANDBY: 1189 case SND_SOC_BIAS_STANDBY:
1187 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1190 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1188 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), 1191 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
1189 priv->supplies); 1192 priv->supplies);
1190 if (ret != 0) 1193 if (ret != 0)
@@ -1317,7 +1320,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1317 priv->supplies); 1320 priv->supplies);
1318 break; 1321 break;
1319 } 1322 }
1320 codec->bias_level = level; 1323 codec->dapm.bias_level = level;
1321 return 0; 1324 return 0;
1322} 1325}
1323 1326
@@ -1334,45 +1337,69 @@ static int wm8350_resume(struct snd_soc_codec *codec)
1334 return 0; 1337 return 0;
1335} 1338}
1336 1339
1337static 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)
1338{ 1343{
1339 struct wm8350_data *priv = data;
1340 struct wm8350 *wm8350 = priv->codec.control_data; 1344 struct wm8350 *wm8350 = priv->codec.control_data;
1341 u16 reg; 1345 u16 reg;
1342 int report; 1346 int report;
1343 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;
1344 struct wm8350_jack_data *jack = NULL; 1378 struct wm8350_jack_data *jack = NULL;
1345 1379
1346 switch (irq - wm8350->irq_base) { 1380 switch (irq - wm8350->irq_base) {
1347 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
1348 jack = &priv->hpl; 1385 jack = &priv->hpl;
1349 mask = WM8350_JACK_L_LVL;
1350 break; 1386 break;
1351 1387
1352 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
1353 jack = &priv->hpr; 1392 jack = &priv->hpr;
1354 mask = WM8350_JACK_R_LVL;
1355 break; 1393 break;
1356 1394
1357 default: 1395 default:
1358 BUG(); 1396 BUG();
1359 } 1397 }
1360 1398
1361 if (!jack->jack) { 1399 if (device_may_wakeup(wm8350->dev))
1362 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); 1400 pm_wakeup_event(wm8350->dev, 250);
1363 return IRQ_NONE;
1364 }
1365
1366 /* Debounce */
1367 msleep(200);
1368
1369 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1370 if (reg & mask)
1371 report = jack->report;
1372 else
1373 report = 0;
1374 1401
1375 snd_soc_jack_report(jack->jack, report, jack->report); 1402 schedule_delayed_work(&jack->work, 200);
1376 1403
1377 return IRQ_HANDLED; 1404 return IRQ_HANDLED;
1378} 1405}
@@ -1436,6 +1463,10 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
1436 u16 reg; 1463 u16 reg;
1437 int report = 0; 1464 int report = 0;
1438 1465
1466#ifndef CONFIG_SND_SOC_WM8350_MODULE
1467 trace_snd_soc_jack_irq("WM8350 mic");
1468#endif
1469
1439 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); 1470 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1440 if (reg & WM8350_JACK_MICSCD_LVL) 1471 if (reg & WM8350_JACK_MICSCD_LVL)
1441 report |= priv->mic.short_report; 1472 report |= priv->mic.short_report;
@@ -1550,7 +1581,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1550 /* Put the codec into reset if it wasn't already */ 1581 /* Put the codec into reset if it wasn't already */
1551 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1582 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1552 1583
1553 INIT_DELAYED_WORK(&codec->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);
1554 1587
1555 /* Enable the codec */ 1588 /* Enable the codec */
1556 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1589 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1626,7 +1659,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1626{ 1659{
1627 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1660 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1628 struct wm8350 *wm8350 = dev_get_platdata(codec->dev); 1661 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1629 int ret;
1630 1662
1631 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1663 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1632 WM8350_JDL_ENA | WM8350_JDR_ENA); 1664 WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1641,15 +1673,12 @@ 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
1644 /* cancel any work waiting to be queued. */ 1676 cancel_delayed_work_sync(&priv->hpl.work);
1645 ret = cancel_delayed_work(&codec->delayed_work); 1677 cancel_delayed_work_sync(&priv->hpr.work);
1646 1678
1647 /* 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
1648 * wait for its completion */ 1680 * wait for its completion */
1649 if (ret) { 1681 flush_delayed_work_sync(&codec->dapm.delayed_work);
1650 schedule_delayed_work(&codec->delayed_work, 0);
1651 flush_scheduled_work();
1652 }
1653 1682
1654 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1683 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1655 1684