summaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-02 16:49:41 +0200
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-04-02 17:34:37 +0200
commit0a11b16853b642a26eb248ac4db422e6dfa04ae5 (patch)
tree588bdfe3c248812ee9077bdf9a1c8c26d764a93c /sound/soc
parentASoC: Set parent for AC97 devices we register (diff)
downloadlinux-0a11b16853b642a26eb248ac4db422e6dfa04ae5.tar.xz
linux-0a11b16853b642a26eb248ac4db422e6dfa04ae5.zip
ASoC: Implement suspend and resume operations for WM9705
Without this the WM9705 driver fails badly when resuming. Tested-by: Russell King <linux@arm.linux.org.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/wm9705.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 3265817c5c26..6e23a81dba78 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -317,6 +317,41 @@ static int wm9705_reset(struct snd_soc_codec *codec)
return -EIO;
}
+#ifdef CONFIG_PM
+static int wm9705_soc_suspend(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+
+ soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
+
+ return 0;
+}
+
+static int wm9705_soc_resume(struct platform_device *pdev)
+{
+ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_codec *codec = socdev->card->codec;
+ int i, ret;
+ u16 *cache = codec->reg_cache;
+
+ ret = wm9705_reset(codec);
+ if (ret < 0) {
+ printk(KERN_ERR "could not reset AC97 codec\n");
+ return ret;
+ }
+
+ for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) {
+ soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
+ }
+
+ return 0;
+}
+#else
+#define wm9705_soc_suspend NULL
+#define wm9705_soc_resume NULL
+#endif
+
static int wm9705_soc_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -407,6 +442,8 @@ static int wm9705_soc_remove(struct platform_device *pdev)
struct snd_soc_codec_device soc_codec_dev_wm9705 = {
.probe = wm9705_soc_probe,
.remove = wm9705_soc_remove,
+ .suspend = wm9705_soc_suspend,
+ .resume = wm9705_soc_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705);