diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-04-02 10:49:41 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2009-04-02 11:34:37 -0400 |
commit | 0a11b16853b642a26eb248ac4db422e6dfa04ae5 (patch) | |
tree | 588bdfe3c248812ee9077bdf9a1c8c26d764a93c /sound/soc/codecs/wm9705.c | |
parent | 4ac5c61f0fc9b01946911a52d827f67947ab01a8 (diff) |
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/codecs/wm9705.c')
-rw-r--r-- | sound/soc/codecs/wm9705.c | 37 |
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) | |||
317 | return -EIO; | 317 | return -EIO; |
318 | } | 318 | } |
319 | 319 | ||
320 | #ifdef CONFIG_PM | ||
321 | static int wm9705_soc_suspend(struct platform_device *pdev) | ||
322 | { | ||
323 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
324 | struct snd_soc_codec *codec = socdev->card->codec; | ||
325 | |||
326 | soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static int wm9705_soc_resume(struct platform_device *pdev) | ||
332 | { | ||
333 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
334 | struct snd_soc_codec *codec = socdev->card->codec; | ||
335 | int i, ret; | ||
336 | u16 *cache = codec->reg_cache; | ||
337 | |||
338 | ret = wm9705_reset(codec); | ||
339 | if (ret < 0) { | ||
340 | printk(KERN_ERR "could not reset AC97 codec\n"); | ||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { | ||
345 | soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | #else | ||
351 | #define wm9705_soc_suspend NULL | ||
352 | #define wm9705_soc_resume NULL | ||
353 | #endif | ||
354 | |||
320 | static int wm9705_soc_probe(struct platform_device *pdev) | 355 | static int wm9705_soc_probe(struct platform_device *pdev) |
321 | { | 356 | { |
322 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 357 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
@@ -407,6 +442,8 @@ static int wm9705_soc_remove(struct platform_device *pdev) | |||
407 | struct snd_soc_codec_device soc_codec_dev_wm9705 = { | 442 | struct snd_soc_codec_device soc_codec_dev_wm9705 = { |
408 | .probe = wm9705_soc_probe, | 443 | .probe = wm9705_soc_probe, |
409 | .remove = wm9705_soc_remove, | 444 | .remove = wm9705_soc_remove, |
445 | .suspend = wm9705_soc_suspend, | ||
446 | .resume = wm9705_soc_resume, | ||
410 | }; | 447 | }; |
411 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); | 448 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705); |
412 | 449 | ||