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 | |
| 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>
| -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 | ||
