linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / sound / pcmcia / vx / vxpocket.c
index cafe664..66900d2 100644 (file)
@@ -59,9 +59,15 @@ static unsigned int card_alloc;
 
 /*
  */
-static void vxpocket_release(struct pcmcia_device *link)
+static void vxpocket_release(dev_link_t *link)
 {
-       pcmcia_disable_device(link);
+       if (link->state & DEV_CONFIG) {
+               /* release cs resources */
+               pcmcia_release_configuration(link->handle);
+               pcmcia_release_io(link->handle, &link->io);
+               pcmcia_release_irq(link->handle, &link->irq);
+               link->state &= ~DEV_CONFIG;
+       }
 }
 
 /*
@@ -126,9 +132,9 @@ static struct snd_vx_hardware vxp440_hw = {
 /*
  * create vxpocket instance
  */
-static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl,
-                                            struct pcmcia_device *link)
+static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
 {
+       dev_link_t *link;               /* Info for cardmgr */
        struct vx_core *chip;
        struct snd_vxpocket *vxp;
        static struct snd_device_ops ops = {
@@ -148,7 +154,7 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl,
 
        vxp = (struct snd_vxpocket *)chip;
 
-       vxp->p_dev = link;
+       link = &vxp->link;
        link->priv = chip;
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -161,6 +167,7 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl,
        link->irq.Instance = chip;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
+       link->conf.Vcc = 50;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
        link->conf.Present = PRESENT_OPTION;
@@ -208,8 +215,9 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
 #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)
+static void vxpocket_config(dev_link_t *link)
 {
+       client_handle_t handle = link->handle;
        struct vx_core *chip = link->priv;
        struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
        tuple_t tuple;
@@ -221,24 +229,24 @@ static int vxpocket_config(struct pcmcia_device *link)
        parse = kmalloc(sizeof(*parse), GFP_KERNEL);
        if (! parse) {
                snd_printk(KERN_ERR "vx: cannot allocate\n");
-               return -ENOMEM;
+               return;
        }
        tuple.Attributes = 0;
        tuple.TupleData = (cisdata_t *)buf;
        tuple.TupleDataMax = sizeof(buf);
        tuple.TupleOffset = 0;
        tuple.DesiredTuple = CISTPL_CONFIG;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-       CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse));
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse));
        link->conf.ConfigBase = parse->config.base;
        link->conf.Present = parse->config.rmask[0];
 
        /* redefine hardware record according to the VERSION1 string */
        tuple.DesiredTuple = CISTPL_VERS_1;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-       CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse));
+       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+       CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse));
        if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) {
                snd_printdd("VX-pocket is detected\n");
        } else {
@@ -249,50 +257,67 @@ static int vxpocket_config(struct pcmcia_device *link)
                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));
+       /* Configure card */
+       link->state |= DEV_CONFIG;
+
+       CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
+       CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
 
-       chip->dev = &handle_to_dev(link);
+       chip->dev = &handle_to_dev(link->handle);
        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;
+       link->dev = &vxp->node;
+       link->state &= ~DEV_CONFIG_PENDING;
        kfree(parse);
-       return 0;
+       return;
 
 cs_failed:
-       cs_error(link, last_fn, last_ret);
+       cs_error(link->handle, last_fn, last_ret);
 failed:
-       pcmcia_disable_device(link);
+       pcmcia_release_configuration(link->handle);
+       pcmcia_release_io(link->handle, &link->io);
+       pcmcia_release_irq(link->handle, &link->irq);
+       link->state &= ~DEV_CONFIG;
        kfree(parse);
-       return -ENODEV;
 }
 
 #ifdef CONFIG_PM
 
-static int vxp_suspend(struct pcmcia_device *link)
+static int vxp_suspend(struct pcmcia_device *dev)
 {
+       dev_link_t *link = dev_to_instance(dev);
        struct vx_core *chip = link->priv;
 
        snd_printdd(KERN_DEBUG "SUSPEND\n");
+       link->state |= DEV_SUSPEND;
        if (chip) {
                snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
                snd_vx_suspend(chip, PMSG_SUSPEND);
        }
+       snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
+       if (link->state & DEV_CONFIG)
+               pcmcia_release_configuration(link->handle);
 
        return 0;
 }
 
-static int vxp_resume(struct pcmcia_device *link)
+static int vxp_resume(struct pcmcia_device *dev)
 {
+       dev_link_t *link = dev_to_instance(dev);
        struct vx_core *chip = link->priv;
 
        snd_printdd(KERN_DEBUG "RESUME\n");
-       if (pcmcia_dev_present(link)) {
+       link->state &= ~DEV_SUSPEND;
+
+       snd_printdd(KERN_DEBUG "CARD_RESET\n");
+       if (DEV_OK(link)) {
                //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+               snd_printdd(KERN_DEBUG "requestconfig...\n");
+               pcmcia_request_configuration(link->handle, &link->conf);
                if (chip) {
                        snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
                        snd_vx_resume(chip);
@@ -308,7 +333,7 @@ static int vxp_resume(struct pcmcia_device *link)
 
 /*
  */
-static int vxpocket_probe(struct pcmcia_device *p_dev)
+static int vxpocket_attach(struct pcmcia_device *p_dev)
 {
        struct snd_card *card;
        struct snd_vxpocket *vxp;
@@ -333,7 +358,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev)
                return -ENOMEM;
        }
 
-       vxp = snd_vxpocket_new(card, ibl[i], p_dev);
+       vxp = snd_vxpocket_new(card, ibl[i]);
        if (! vxp) {
                snd_card_free(card);
                return -ENODEV;
@@ -343,13 +368,20 @@ static int vxpocket_probe(struct pcmcia_device *p_dev)
        vxp->index = i;
        card_alloc |= 1 << i;
 
-       vxp->p_dev = p_dev;
+       /* Chain drivers */
+       vxp->link.next = NULL;
 
-       return vxpocket_config(p_dev);
+       vxp->link.handle = p_dev;
+       vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+       p_dev->instance = &vxp->link;
+       vxpocket_config(&vxp->link);
+
+       return 0;
 }
 
-static void vxpocket_detach(struct pcmcia_device *link)
+static void vxpocket_detach(struct pcmcia_device *p_dev)
 {
+       dev_link_t *link = dev_to_instance(p_dev);
        struct snd_vxpocket *vxp;
        struct vx_core *chip;
 
@@ -381,7 +413,7 @@ static struct pcmcia_driver vxp_cs_driver = {
        .drv            = {
                .name   = "snd-vxpocket",
        },
-       .probe          = vxpocket_probe,
+       .probe          = vxpocket_attach,
        .remove         = vxpocket_detach,
        .id_table       = vxp_ids,
 #ifdef CONFIG_PM