+}
+
+#ifdef CONFIG_PM
+static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
+{
+ struct snd_card *card = pci_get_drvdata(pci);
+ struct ensoniq *ensoniq = card->private_data;
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+
+ snd_pcm_suspend_all(ensoniq->pcm1);
+ snd_pcm_suspend_all(ensoniq->pcm2);
+
+#ifdef CHIP1371
+ snd_ac97_suspend(ensoniq->u.es1371.ac97);
+#else
+ /* try to reset AK4531 */
+ outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC));
+ inw(ES_REG(ensoniq, 1370_CODEC));
+ udelay(100);
+ outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC));
+ inw(ES_REG(ensoniq, 1370_CODEC));
+ udelay(100);
+ snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
+#endif
+ pci_set_power_state(pci, PCI_D3hot);
+ pci_disable_device(pci);
+ pci_save_state(pci);
+ return 0;
+}
+
+static int snd_ensoniq_resume(struct pci_dev *pci)
+{
+ struct snd_card *card = pci_get_drvdata(pci);
+ struct ensoniq *ensoniq = card->private_data;
+
+ pci_restore_state(pci);
+ pci_enable_device(pci);
+ pci_set_power_state(pci, PCI_D0);
+ pci_set_master(pci);
+
+ snd_ensoniq_chip_init(ensoniq);
+
+#ifdef CHIP1371
+ snd_ac97_resume(ensoniq->u.es1371.ac97);
+#else
+ snd_ak4531_resume(ensoniq->u.es1370.ak4531);
+#endif
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+
+static int __devinit snd_ensoniq_create(struct snd_card *card,
+ struct pci_dev *pci,
+ struct ensoniq ** rensoniq)
+{
+ struct ensoniq *ensoniq;
+ unsigned short cmdw;
+ unsigned char cmdb;
+#ifdef CHIP1371
+ int idx;
+#endif
+ int err;
+ static struct snd_device_ops ops = {
+ .dev_free = snd_ensoniq_dev_free,
+ };
+
+ *rensoniq = NULL;
+ if ((err = pci_enable_device(pci)) < 0)
+ return err;
+ ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
+ if (ensoniq == NULL) {
+ pci_disable_device(pci);
+ return -ENOMEM;
+ }
+ spin_lock_init(&ensoniq->reg_lock);
+ mutex_init(&ensoniq->src_mutex);
+ ensoniq->card = card;
+ ensoniq->pci = pci;
+ ensoniq->irq = -1;
+ if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
+ kfree(ensoniq);
+ pci_disable_device(pci);
+ return err;
+ }
+ ensoniq->port = pci_resource_start(pci, 0);
+ if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ,
+ "Ensoniq AudioPCI", ensoniq)) {
+ snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+ snd_ensoniq_free(ensoniq);
+ return -EBUSY;
+ }
+ ensoniq->irq = pci->irq;
+#ifdef CHIP1370
+ if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+ 16, &ensoniq->dma_bug) < 0) {
+ snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
+ snd_ensoniq_free(ensoniq);
+ return -EBUSY;
+ }
+#endif
+ pci_set_master(pci);
+ pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb);
+ ensoniq->rev = cmdb;
+ pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw);
+ ensoniq->subsystem_vendor_id = cmdw;
+ pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw);
+ ensoniq->subsystem_device_id = cmdw;
+#ifdef CHIP1370
+#if 0
+ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE |
+ ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
+#else /* get microphone working */
+ ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
+#endif
+ ensoniq->sctrl = 0;
+#else
+ ensoniq->ctrl = 0;
+ ensoniq->sctrl = 0;
+ ensoniq->cssr = 0;
+ for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++)
+ if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid &&
+ ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) {
+ ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */
+ break;
+ }
+ for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++)
+ if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
+ pci->device == es1371_ac97_reset_hack[idx].did &&
+ ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
+ ensoniq->cssr |= ES_1371_ST_AC97_RST;
+ break;
+ }
+#endif
+
+ snd_ensoniq_chip_init(ensoniq);