snd_msnd_disable_irq(mpu->private_data);
}
+#ifdef CONFIG_PM
+static u8 snd_msnd_pm_recsrc(struct snd_msnd *chip)
+{
+ /* Convert recsrc to the Capture Source selector: 0=Analog, 1=MASS, 2=SPDIF. */
+ if (chip->recsrc & BIT(4))
+ return 1;
+ if ((chip->recsrc & BIT(17)) &&
+ test_bit(F_HAVEDIGITAL, &chip->flags))
+ return 2;
+ return 0;
+}
+#endif
+
static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
return 0;
}
+#ifdef CONFIG_PM
+static int snd_msnd_card_suspend(struct snd_card *card)
+{
+ struct snd_msnd *chip = card->private_data;
+ struct snd_mpu401 *mpu;
+ int err;
+
+ mpu = chip->rmidi ? chip->rmidi->private_data : NULL;
+ chip->pm_recsrc = snd_msnd_pm_recsrc(chip);
+ chip->pm_mpu_input = mpu && test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
+ if (chip->pm_mpu_input)
+ snd_msnd_send_dsp_cmd(chip, HDEX_MIDI_IN_STOP);
+
+ err = snd_msnd_force_irq(chip, false);
+ if (err < 0) {
+ if (chip->pm_mpu_input)
+ snd_msnd_send_dsp_cmd(chip, HDEX_MIDI_IN_START);
+ return err;
+ }
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ return 0;
+}
+
+static int snd_msnd_card_resume(struct snd_card *card)
+{
+ struct snd_msnd *chip = card->private_data;
+ int err;
+
+ err = snd_msnd_initialize(card);
+ if (err < 0)
+ return err;
+
+ snd_msnd_calibrate_adc(chip, chip->play_sample_rate);
+ snd_msndmix_force_recsrc(chip, chip->pm_recsrc);
+
+ err = snd_msnd_force_irq(chip, true);
+ if (err < 0)
+ return err;
+
+ if (chip->pm_mpu_input)
+ snd_msnd_send_dsp_cmd(chip, HDEX_MIDI_IN_START);
+
+ chip->nresets = 0;
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+
+static int snd_msnd_isa_suspend(struct device *dev, unsigned int idx,
+ pm_message_t state)
+{
+ return snd_msnd_card_suspend(dev_get_drvdata(dev));
+}
+
+static int snd_msnd_isa_resume(struct device *dev, unsigned int idx)
+{
+ return snd_msnd_card_resume(dev_get_drvdata(dev));
+}
+#endif
+
static struct isa_driver snd_msnd_driver = {
.match = snd_msnd_isa_match,
.probe = snd_msnd_isa_probe,
- /* FIXME: suspend, resume */
+#ifdef CONFIG_PM
+ .suspend = snd_msnd_isa_suspend,
+ .resume = snd_msnd_isa_resume,
+#endif
.driver = {
.name = DEV_NAME
},
return 0;
}
+#ifdef CONFIG_PM
+static int snd_msnd_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+ return snd_msnd_card_suspend(pnp_get_card_drvdata(pcard));
+}
+
+static int snd_msnd_pnp_resume(struct pnp_card_link *pcard)
+{
+ return snd_msnd_card_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
static int isa_registered;
static int pnp_registered;
.name = "msnd_pinnacle",
.id_table = msnd_pnpids,
.probe = snd_msnd_pnp_detect,
+#ifdef CONFIG_PM
+ .suspend = snd_msnd_pnp_suspend,
+ .resume = snd_msnd_pnp_resume,
+#endif
};
#endif /* CONFIG_PNP */
module_init(snd_msnd_init);
module_exit(snd_msnd_exit);
-