aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2012-08-19 17:27:26 -0400
committerTakashi Iwai <tiwai@suse.de>2012-08-20 05:12:56 -0400
commit6f0fa66051e92f361bd293432466f5e62832adbf (patch)
tree1eefb8c91a9d9551d0bb7e694ac9d0231de0e958
parentc86b6b452a6b2a80a2c9ffa3c8f7d80eea0fa196 (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.h7
-rw-r--r--sound/isa/ad1816a/ad1816a.c26
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c28
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
171extern int snd_ad1816a_mixer(struct snd_ad1816a *chip); 174extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
172extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device, 175extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
173 struct snd_timer **rtimer); 176 struct snd_timer **rtimer);
177#ifdef CONFIG_PM
178extern void snd_ad1816a_suspend(struct snd_ad1816a *chip);
179extern 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
248static 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
258static 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
247static struct pnp_card_driver ad1816a_pnpc_driver = { 268static 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
256static int __init alsa_card_ad1816a_init(void) 280static 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
494static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip) 494static 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
515void 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
527void 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
514static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip) 540static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
515{ 541{
516 unsigned long flags; 542 unsigned long flags;