+/*
+ * create vxpocket instance
+ */
+static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl,
+ struct pcmcia_device *link)
+{
+ struct vx_core *chip;
+ struct snd_vxpocket *vxp;
+ static struct snd_device_ops ops = {
+ .dev_free = snd_vxpocket_dev_free,
+ };
+
+ chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
+ sizeof(struct snd_vxpocket) - sizeof(struct vx_core));
+ if (! chip)
+ return NULL;
+
+ if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) {
+ kfree(chip);
+ return NULL;
+ }
+ chip->ibl.size = ibl;
+
+ vxp = (struct snd_vxpocket *)chip;
+
+ vxp->p_dev = link;
+ link->priv = chip;
+
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ link->io.NumPorts1 = 16;
+
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = &snd_vx_irq_handler;
+ link->irq.Instance = chip;
+
+ link->conf.Attributes = CONF_ENABLE_IRQ;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ link->conf.ConfigIndex = 1;
+ link->conf.Present = PRESENT_OPTION;
+
+ return vxp;
+}
+
+
+/**
+ * snd_vxpocket_assign_resources - initialize the hardware and card instance.
+ * @port: i/o port for the card
+ * @irq: irq number for the card
+ *
+ * this function assigns the specified port and irq, boot the card,
+ * create pcm and control instances, and initialize the rest hardware.
+ *
+ * returns 0 if successful, or a negative error code.
+ */
+static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq)
+{
+ int err;
+ struct snd_card *card = chip->card;
+ struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+
+ snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq);
+ vxp->port = port;
+
+ sprintf(card->shortname, "Digigram %s", card->driver);
+ sprintf(card->longname, "%s at 0x%x, irq %i",
+ card->shortname, port, irq);
+
+ chip->irq = irq;
+
+ if ((err = snd_vx_setup_firmware(chip)) < 0)
+ return err;
+
+ return 0;
+}
+
+
+/*
+ * configuration callback
+ */
+
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+static int vxpocket_config(struct pcmcia_device *link)
+{
+ struct vx_core *chip = link->priv;
+ struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+ int last_fn, last_ret;
+
+ snd_printdd(KERN_DEBUG "vxpocket_config called\n");
+
+ /* redefine hardware record according to the VERSION1 string */
+ if (!strcmp(link->prod_id[1], "VX-POCKET")) {
+ snd_printdd("VX-pocket is detected\n");
+ } else {
+ snd_printdd("VX-pocket 440 is detected\n");
+ /* overwrite the hardware information */
+ chip->hw = &vxp440_hw;
+ chip->type = vxp440_hw.type;
+ strcpy(chip->card->driver, vxp440_hw.name);
+ }
+
+ CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+
+ chip->dev = &handle_to_dev(link);
+ snd_card_set_dev(chip->card, chip->dev);
+
+ if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
+ goto failed;
+
+ link->dev_node = &vxp->node;
+ return 0;
+
+cs_failed:
+ cs_error(link, last_fn, last_ret);
+failed:
+ pcmcia_disable_device(link);
+ return -ENODEV;
+}
+
+#ifdef CONFIG_PM
+
+static int vxp_suspend(struct pcmcia_device *link)
+{
+ struct vx_core *chip = link->priv;
+
+ snd_printdd(KERN_DEBUG "SUSPEND\n");
+ if (chip) {
+ snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
+ snd_vx_suspend(chip, PMSG_SUSPEND);
+ }
+
+ return 0;
+}
+
+static int vxp_resume(struct pcmcia_device *link)
+{
+ struct vx_core *chip = link->priv;
+
+ snd_printdd(KERN_DEBUG "RESUME\n");
+ if (pcmcia_dev_present(link)) {
+ //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+ if (chip) {
+ snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
+ snd_vx_resume(chip);
+ }
+ }
+ snd_printdd(KERN_DEBUG "resume done!\n");
+
+ return 0;
+}
+
+#endif