diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2012-08-19 17:27:26 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-08-20 05:12:56 -0400 |
commit | 6f0fa66051e92f361bd293432466f5e62832adbf (patch) | |
tree | 1eefb8c91a9d9551d0bb7e694ac9d0231de0e958 | |
parent | c86b6b452a6b2a80a2c9ffa3c8f7d80eea0fa196 (diff) |
ALSA: snd-ad1816a: Implement suspend/resume
Implement suspend/resume support for AD1816 chips.
Tested with Terratec SoundSystem Base-1.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | include/sound/ad1816a.h | 7 | ||||
-rw-r--r-- | sound/isa/ad1816a/ad1816a.c | 26 | ||||
-rw-r--r-- | sound/isa/ad1816a/ad1816a_lib.c | 28 |
3 files changed, 59 insertions, 2 deletions
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h index 62da41e508e1..2a89f0d71440 100644 --- a/include/sound/ad1816a.h +++ b/include/sound/ad1816a.h | |||
@@ -147,6 +147,9 @@ struct snd_ad1816a { | |||
147 | unsigned int c_dma_size; | 147 | unsigned int c_dma_size; |
148 | 148 | ||
149 | struct snd_timer *timer; | 149 | struct snd_timer *timer; |
150 | #ifdef CONFIG_PM | ||
151 | unsigned short image[48]; | ||
152 | #endif | ||
150 | }; | 153 | }; |
151 | 154 | ||
152 | 155 | ||
@@ -171,5 +174,9 @@ extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm | |||
171 | extern int snd_ad1816a_mixer(struct snd_ad1816a *chip); | 174 | extern int snd_ad1816a_mixer(struct snd_ad1816a *chip); |
172 | extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, | 175 | extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, |
173 | struct snd_timer **rtimer); | 176 | struct snd_timer **rtimer); |
177 | #ifdef CONFIG_PM | ||
178 | extern void snd_ad1816a_suspend(struct snd_ad1816a *chip); | ||
179 | extern void snd_ad1816a_resume(struct snd_ad1816a *chip); | ||
180 | #endif | ||
174 | 181 | ||
175 | #endif /* __SOUND_AD1816A_H */ | 182 | #endif /* __SOUND_AD1816A_H */ |
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 1a374e61ab2b..2c2f829c3fd7 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
@@ -244,13 +244,37 @@ static void __devexit snd_ad1816a_pnp_remove(struct pnp_card_link * pcard) | |||
244 | pnp_set_card_drvdata(pcard, NULL); | 244 | pnp_set_card_drvdata(pcard, NULL); |
245 | } | 245 | } |
246 | 246 | ||
247 | #ifdef CONFIG_PM | ||
248 | static int snd_ad1816a_pnp_suspend(struct pnp_card_link *pcard, | ||
249 | pm_message_t state) | ||
250 | { | ||
251 | struct snd_card *card = pnp_get_card_drvdata(pcard); | ||
252 | |||
253 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
254 | snd_ad1816a_suspend(card->private_data); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int snd_ad1816a_pnp_resume(struct pnp_card_link *pcard) | ||
259 | { | ||
260 | struct snd_card *card = pnp_get_card_drvdata(pcard); | ||
261 | |||
262 | snd_ad1816a_resume(card->private_data); | ||
263 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
264 | return 0; | ||
265 | } | ||
266 | #endif | ||
267 | |||
247 | static struct pnp_card_driver ad1816a_pnpc_driver = { | 268 | static struct pnp_card_driver ad1816a_pnpc_driver = { |
248 | .flags = PNP_DRIVER_RES_DISABLE, | 269 | .flags = PNP_DRIVER_RES_DISABLE, |
249 | .name = "ad1816a", | 270 | .name = "ad1816a", |
250 | .id_table = snd_ad1816a_pnpids, | 271 | .id_table = snd_ad1816a_pnpids, |
251 | .probe = snd_ad1816a_pnp_detect, | 272 | .probe = snd_ad1816a_pnp_detect, |
252 | .remove = __devexit_p(snd_ad1816a_pnp_remove), | 273 | .remove = __devexit_p(snd_ad1816a_pnp_remove), |
253 | /* FIXME: suspend/resume */ | 274 | #ifdef CONFIG_PM |
275 | .suspend = snd_ad1816a_pnp_suspend, | ||
276 | .resume = snd_ad1816a_pnp_resume, | ||
277 | #endif | ||
254 | }; | 278 | }; |
255 | 279 | ||
256 | static int __init alsa_card_ad1816a_init(void) | 280 | static int __init alsa_card_ad1816a_init(void) |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index de5cc1c26279..db64df6023e0 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
@@ -491,7 +491,7 @@ static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream) | |||
491 | } | 491 | } |
492 | 492 | ||
493 | 493 | ||
494 | static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip) | 494 | static void snd_ad1816a_init(struct snd_ad1816a *chip) |
495 | { | 495 | { |
496 | unsigned long flags; | 496 | unsigned long flags; |
497 | 497 | ||
@@ -511,6 +511,32 @@ static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip) | |||
511 | spin_unlock_irqrestore(&chip->lock, flags); | 511 | spin_unlock_irqrestore(&chip->lock, flags); |
512 | } | 512 | } |
513 | 513 | ||
514 | #ifdef CONFIG_PM | ||
515 | void snd_ad1816a_suspend(struct snd_ad1816a *chip) | ||
516 | { | ||
517 | int reg; | ||
518 | unsigned long flags; | ||
519 | |||
520 | snd_pcm_suspend_all(chip->pcm); | ||
521 | spin_lock_irqsave(&chip->lock, flags); | ||
522 | for (reg = 0; reg < 48; reg++) | ||
523 | chip->image[reg] = snd_ad1816a_read(chip, reg); | ||
524 | spin_unlock_irqrestore(&chip->lock, flags); | ||
525 | } | ||
526 | |||
527 | void snd_ad1816a_resume(struct snd_ad1816a *chip) | ||
528 | { | ||
529 | int reg; | ||
530 | unsigned long flags; | ||
531 | |||
532 | snd_ad1816a_init(chip); | ||
533 | spin_lock_irqsave(&chip->lock, flags); | ||
534 | for (reg = 0; reg < 48; reg++) | ||
535 | snd_ad1816a_write(chip, reg, chip->image[reg]); | ||
536 | spin_unlock_irqrestore(&chip->lock, flags); | ||
537 | } | ||
538 | #endif | ||
539 | |||
514 | static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip) | 540 | static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip) |
515 | { | 541 | { |
516 | unsigned long flags; | 542 | unsigned long flags; |