+static int snd_es968_pnp_is_probed;
+
+#ifdef CONFIG_PNP
+static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
+ struct pnp_card_link *pcard,
+ const struct pnp_card_device_id *pid)
+{
+ struct snd_es1688 *chip = card->private_data;
+ struct pnp_dev *pdev;
+ int error;
+
+ pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
+ if (pdev == NULL)
+ return -ENODEV;
+
+ error = pnp_activate_dev(pdev);
+ if (error < 0) {
+ snd_printk(KERN_ERR "ES968 pnp configure failure\n");
+ return error;
+ }
+ port[n] = pnp_port_start(pdev, 0);
+ dma8[n] = pnp_dma(pdev, 0);
+ irq[n] = pnp_irq(pdev, 0);
+
+ return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
+ mpu_irq[n], dma8[n], ES1688_HW_AUTO);
+}
+
+static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
+ const struct pnp_card_device_id *pid)
+{
+ struct snd_card *card;
+ static unsigned int dev;
+ int error;
+ struct snd_es1688 *chip;
+
+ if (snd_es968_pnp_is_probed)
+ return -EBUSY;
+ for ( ; dev < SNDRV_CARDS; dev++) {
+ if (enable[dev] && isapnp[dev])
+ break;
+ }
+ if (dev == SNDRV_CARDS)
+ return -ENODEV;
+
+ error = snd_card_create(index[dev], id[dev], THIS_MODULE,
+ sizeof(struct snd_es1688), &card);
+ if (error < 0)
+ return error;
+ chip = card->private_data;
+
+ error = snd_card_es968_pnp(card, dev, pcard, pid);
+ if (error < 0) {
+ snd_card_free(card);
+ return error;
+ }
+ snd_card_set_dev(card, &pcard->card->dev);
+ error = snd_es1688_probe(card, dev);
+ if (error < 0)
+ return error;
+ pnp_set_card_drvdata(pcard, card);
+ snd_es968_pnp_is_probed = 1;
+ return 0;
+}
+
+static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
+{
+ snd_card_free(pnp_get_card_drvdata(pcard));
+ pnp_set_card_drvdata(pcard, NULL);
+ snd_es968_pnp_is_probed = 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
+ pm_message_t state)
+{
+ struct snd_card *card = pnp_get_card_drvdata(pcard);
+ struct snd_es1688 *chip = card->private_data;
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ snd_pcm_suspend_all(chip->pcm);
+ return 0;
+}
+
+static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
+{
+ struct snd_card *card = pnp_get_card_drvdata(pcard);
+ struct snd_es1688 *chip = card->private_data;
+
+ snd_es1688_reset(chip);
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+}
+#endif
+
+static struct pnp_card_device_id snd_es968_pnpids[] = {
+ { .id = "ESS0968", .devs = { { "@@@0968" }, } },
+ { .id = "ESS0968", .devs = { { "ESS0968" }, } },
+ { .id = "", } /* end */
+};
+
+MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
+
+static struct pnp_card_driver es968_pnpc_driver = {
+ .flags = PNP_DRIVER_RES_DISABLE,
+ .name = DEV_NAME " PnP",
+ .id_table = snd_es968_pnpids,
+ .probe = snd_es968_pnp_detect,
+ .remove = __devexit_p(snd_es968_pnp_remove),
+#ifdef CONFIG_PM
+ .suspend = snd_es968_pnp_suspend,
+ .resume = snd_es968_pnp_resume,
+#endif
+};
+#endif
+