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>
unsigned int c_dma_size;
struct snd_timer *timer;
+#ifdef CONFIG_PM
+ unsigned short image[48];
+#endif
};
extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
struct snd_timer **rtimer);
+#ifdef CONFIG_PM
+extern void snd_ad1816a_suspend(struct snd_ad1816a *chip);
+extern void snd_ad1816a_resume(struct snd_ad1816a *chip);
+#endif
#endif /* __SOUND_AD1816A_H */
pnp_set_card_drvdata(pcard, NULL);
}
+#ifdef CONFIG_PM
+static int snd_ad1816a_pnp_suspend(struct pnp_card_link *pcard,
+ pm_message_t state)
+{
+ struct snd_card *card = pnp_get_card_drvdata(pcard);
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ snd_ad1816a_suspend(card->private_data);
+ return 0;
+}
+
+static int snd_ad1816a_pnp_resume(struct pnp_card_link *pcard)
+{
+ struct snd_card *card = pnp_get_card_drvdata(pcard);
+
+ snd_ad1816a_resume(card->private_data);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+#endif
+
static struct pnp_card_driver ad1816a_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "ad1816a",
.id_table = snd_ad1816a_pnpids,
.probe = snd_ad1816a_pnp_detect,
.remove = __devexit_p(snd_ad1816a_pnp_remove),
- /* FIXME: suspend/resume */
+#ifdef CONFIG_PM
+ .suspend = snd_ad1816a_pnp_suspend,
+ .resume = snd_ad1816a_pnp_resume,
+#endif
};
static int __init alsa_card_ad1816a_init(void)
}
-static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip)
+static void snd_ad1816a_init(struct snd_ad1816a *chip)
{
unsigned long flags;
spin_unlock_irqrestore(&chip->lock, flags);
}
+#ifdef CONFIG_PM
+void snd_ad1816a_suspend(struct snd_ad1816a *chip)
+{
+ int reg;
+ unsigned long flags;
+
+ snd_pcm_suspend_all(chip->pcm);
+ spin_lock_irqsave(&chip->lock, flags);
+ for (reg = 0; reg < 48; reg++)
+ chip->image[reg] = snd_ad1816a_read(chip, reg);
+ spin_unlock_irqrestore(&chip->lock, flags);
+}
+
+void snd_ad1816a_resume(struct snd_ad1816a *chip)
+{
+ int reg;
+ unsigned long flags;
+
+ snd_ad1816a_init(chip);
+ spin_lock_irqsave(&chip->lock, flags);
+ for (reg = 0; reg < 48; reg++)
+ snd_ad1816a_write(chip, reg, chip->image[reg]);
+ spin_unlock_irqrestore(&chip->lock, flags);
+}
+#endif
+
static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
{
unsigned long flags;