X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=sound%2Fpcmcia%2Fvx%2Fvxpocket.c;fp=sound%2Fpcmcia%2Fvx%2Fvxpocket.c;h=66900d20a42f37c88b9e6c9a4c7e185a46ccc077;hp=cafe6640cc1a6abdca63a2e5c1fc2cd985bfd9ad;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index cafe6640c..66900d20a 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -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