aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-01-02 08:15:56 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-01-04 16:51:13 -0500
commit53242c68333570631a15a69842851b458eca3d99 (patch)
tree256d4b739f523fe1b523189831fc72c3b1554d81
parent10505634bfa74871118a21eef8617acad00e4019 (diff)
ASoC: Implement suspend and resume for WM8993
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--sound/soc/codecs/wm8993.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 5e32f2ed5fc2..cd2bc05f78cc 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -227,6 +227,7 @@ struct wm8993_priv {
227 int class_w_users; 227 int class_w_users;
228 unsigned int fll_fref; 228 unsigned int fll_fref;
229 unsigned int fll_fout; 229 unsigned int fll_fout;
230 int fll_src;
230}; 231};
231 232
232static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg) 233static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
@@ -506,6 +507,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
506 507
507 wm8993->fll_fref = Fref; 508 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout; 509 wm8993->fll_fout = Fout;
510 wm8993->fll_src = source;
509 511
510 return 0; 512 return 0;
511} 513}
@@ -1480,9 +1482,74 @@ static int wm8993_remove(struct platform_device *pdev)
1480 return 0; 1482 return 0;
1481} 1483}
1482 1484
1485#ifdef CONFIG_PM
1486static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1487{
1488 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1489 struct snd_soc_codec *codec = socdev->card->codec;
1490 struct wm8993_priv *wm8993 = codec->private_data;
1491 int fll_fout = wm8993->fll_fout;
1492 int fll_fref = wm8993->fll_fref;
1493 int ret;
1494
1495 /* Stop the FLL in an orderly fashion */
1496 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1497 if (ret != 0) {
1498 dev_err(&pdev->dev, "Failed to stop FLL\n");
1499 return ret;
1500 }
1501
1502 wm8993->fll_fout = fll_fout;
1503 wm8993->fll_fref = fll_fref;
1504
1505 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1506
1507 return 0;
1508}
1509
1510static int wm8993_resume(struct platform_device *pdev)
1511{
1512 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1513 struct snd_soc_codec *codec = socdev->card->codec;
1514 struct wm8993_priv *wm8993 = codec->private_data;
1515 u16 *cache = wm8993->reg_cache;
1516 int i, ret;
1517
1518 /* Restore the register settings */
1519 for (i = 1; i < WM8993_MAX_REGISTER; i++) {
1520 if (cache[i] == wm8993_reg_defaults[i])
1521 continue;
1522 snd_soc_write(codec, i, cache[i]);
1523 }
1524
1525 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1526
1527 /* Restart the FLL? */
1528 if (wm8993->fll_fout) {
1529 int fll_fout = wm8993->fll_fout;
1530 int fll_fref = wm8993->fll_fref;
1531
1532 wm8993->fll_fref = 0;
1533 wm8993->fll_fout = 0;
1534
1535 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
1536 fll_fref, fll_fout);
1537 if (ret != 0)
1538 dev_err(codec->dev, "Failed to restart FLL\n");
1539 }
1540
1541 return 0;
1542}
1543#else
1544#define wm8993_suspend NULL
1545#define wm8993_resume NULL
1546#endif
1547
1483struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1548struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1484 .probe = wm8993_probe, 1549 .probe = wm8993_probe,
1485 .remove = wm8993_remove, 1550 .remove = wm8993_remove,
1551 .suspend = wm8993_suspend,
1552 .resume = wm8993_resume,
1486}; 1553};
1487EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); 1554EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1488 1555