diff options
Diffstat (limited to 'sound/pcmcia/vx/vxpocket.c')
| -rw-r--r-- | sound/pcmcia/vx/vxpocket.c | 206 |
1 files changed, 70 insertions, 136 deletions
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 66900d20a42..786e7e139c9 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -2,7 +2,7 @@ * Driver for Digigram VXpocket V2/440 soundcards * * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de> - * + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,14 +19,15 @@ */ -#include <sound/driver.h> #include <linux/init.h> -#include <linux/moduleparam.h> +#include <linux/module.h> +#include <linux/slab.h> #include <sound/core.h> #include "vxpocket.h" #include <pcmcia/ciscode.h> #include <pcmcia/cisreg.h> #include <sound/initval.h> +#include <sound/tlv.h> /* */ @@ -38,7 +39,7 @@ MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static int ibl[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); @@ -59,19 +60,13 @@ static unsigned int card_alloc; /* */ -static void vxpocket_release(dev_link_t *link) +static void vxpocket_release(struct pcmcia_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; - } + pcmcia_disable_device(link); } /* - * destructor, called from snd_card_free_in_thread() + * destructor, called from snd_card_free_when_closed() */ static int snd_vxpocket_dev_free(struct snd_device *device) { @@ -96,6 +91,8 @@ static int snd_vxpocket_dev_free(struct snd_device *device) * Only output levels can be modified */ +static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); + static struct snd_vx_hardware vxpocket_hw = { .name = "VXPocket", .type = VX_TYPE_VXPOCKET, @@ -105,6 +102,7 @@ static struct snd_vx_hardware vxpocket_hw = { .num_ins = 1, .num_outs = 1, .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, + .output_level_db_scale = db_scale_old_vol, }; /* VX-pocket 440 @@ -126,53 +124,50 @@ static struct snd_vx_hardware vxp440_hw = { .num_ins = 2, .num_outs = 2, .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, + .output_level_db_scale = db_scale_old_vol, }; /* * create vxpocket instance */ -static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl) +static int snd_vxpocket_new(struct snd_card *card, int ibl, + struct pcmcia_device *link, + struct snd_vxpocket **chip_ret) { - dev_link_t *link; /* Info for cardmgr */ struct vx_core *chip; struct snd_vxpocket *vxp; static struct snd_device_ops ops = { .dev_free = snd_vxpocket_dev_free, }; + int err; chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, sizeof(struct snd_vxpocket) - sizeof(struct vx_core)); - if (! chip) - return NULL; + if (!chip) + return -ENOMEM; - if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) { kfree(chip); - return NULL; + return err; } chip->ibl.size = ibl; vxp = (struct snd_vxpocket *)chip; - link = &vxp->link; + 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->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; + link->resource[0]->end = 16; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; - link->irq.Handler = &snd_vx_irq_handler; - link->irq.Instance = chip; + link->config_flags |= CONF_ENABLE_IRQ; + link->config_index = 1; + link->config_regs = PRESENT_OPTION; - 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; - - return vxp; + *chip_ret = vxp; + return 0; } @@ -212,42 +207,15 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq * configuration callback */ -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - -static void vxpocket_config(dev_link_t *link) +static int vxpocket_config(struct pcmcia_device *link) { - client_handle_t handle = link->handle; struct vx_core *chip = link->priv; - struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; - tuple_t tuple; - cisparse_t *parse; - u_short buf[32]; - int last_fn, last_ret; + int ret; snd_printdd(KERN_DEBUG "vxpocket_config called\n"); - parse = kmalloc(sizeof(*parse), GFP_KERNEL); - if (! parse) { - snd_printk(KERN_ERR "vx: cannot allocate\n"); - 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(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(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")) { + if (!strcmp(link->prod_id[1], "VX-POCKET")) { snd_printdd("VX-pocket is detected\n"); } else { snd_printdd("VX-pocket 440 is detected\n"); @@ -257,67 +225,53 @@ static void vxpocket_config(dev_link_t *link) strcpy(chip->card->driver, vxp440_hw.name); } - /* Configure card */ - link->state |= DEV_CONFIG; + ret = pcmcia_request_io(link); + if (ret) + goto failed; + + ret = pcmcia_request_irq(link, snd_vx_irq_handler); + if (ret) + goto failed; - 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)); + ret = pcmcia_enable_device(link); + if (ret) + goto failed; - chip->dev = &handle_to_dev(link->handle); - snd_card_set_dev(chip->card, chip->dev); + chip->dev = &link->dev; - if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) + if (snd_vxpocket_assign_resources(chip, link->resource[0]->start, + link->irq) < 0) goto failed; - link->dev = &vxp->node; - link->state &= ~DEV_CONFIG_PENDING; - kfree(parse); - return; + return 0; -cs_failed: - cs_error(link->handle, last_fn, last_ret); failed: - 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); + pcmcia_disable_device(link); + return -ENODEV; } #ifdef CONFIG_PM -static int vxp_suspend(struct pcmcia_device *dev) +static int vxp_suspend(struct pcmcia_device *link) { - 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_vx_suspend(chip); } - 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 *dev) +static int vxp_resume(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(dev); struct vx_core *chip = link->priv; snd_printdd(KERN_DEBUG "RESUME\n"); - link->state &= ~DEV_SUSPEND; - - snd_printdd(KERN_DEBUG "CARD_RESET\n"); - if (DEV_OK(link)) { + if (pcmcia_dev_present(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); @@ -333,15 +287,15 @@ static int vxp_resume(struct pcmcia_device *dev) /* */ -static int vxpocket_attach(struct pcmcia_device *p_dev) +static int vxpocket_probe(struct pcmcia_device *p_dev) { struct snd_card *card; struct snd_vxpocket *vxp; - int i; + int i, err; /* find an empty slot from the card list */ for (i = 0; i < SNDRV_CARDS; i++) { - if (! card_alloc & (1 << i)) + if (!(card_alloc & (1 << i))) break; } if (i >= SNDRV_CARDS) { @@ -352,36 +306,30 @@ static int vxpocket_attach(struct pcmcia_device *p_dev) return -ENODEV; /* disabled explicitly */ /* ok, create a card instance */ - card = snd_card_new(index[i], id[i], THIS_MODULE, 0); - if (card == NULL) { + err = snd_card_new(&p_dev->dev, index[i], id[i], THIS_MODULE, + 0, &card); + if (err < 0) { snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); - return -ENOMEM; + return err; } - vxp = snd_vxpocket_new(card, ibl[i]); - if (! vxp) { + err = snd_vxpocket_new(card, ibl[i], p_dev, &vxp); + if (err < 0) { snd_card_free(card); - return -ENODEV; + return err; } card->private_data = vxp; vxp->index = i; card_alloc |= 1 << i; - /* Chain drivers */ - vxp->link.next = NULL; - - vxp->link.handle = p_dev; - vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING; - p_dev->instance = &vxp->link; - vxpocket_config(&vxp->link); + vxp->p_dev = p_dev; - return 0; + return vxpocket_config(p_dev); } -static void vxpocket_detach(struct pcmcia_device *p_dev) +static void vxpocket_detach(struct pcmcia_device *link) { - dev_link_t *link = dev_to_instance(p_dev); struct snd_vxpocket *vxp; struct vx_core *chip; @@ -395,14 +343,14 @@ static void vxpocket_detach(struct pcmcia_device *p_dev) chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ snd_card_disconnect(chip->card); vxpocket_release(link); - snd_card_free_in_thread(chip->card); + snd_card_free_when_closed(chip->card); } /* * Module entry points */ -static struct pcmcia_device_id vxp_ids[] = { +static const struct pcmcia_device_id vxp_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x01f1, 0x0100), PCMCIA_DEVICE_NULL }; @@ -410,10 +358,8 @@ MODULE_DEVICE_TABLE(pcmcia, vxp_ids); static struct pcmcia_driver vxp_cs_driver = { .owner = THIS_MODULE, - .drv = { - .name = "snd-vxpocket", - }, - .probe = vxpocket_attach, + .name = "snd-vxpocket", + .probe = vxpocket_probe, .remove = vxpocket_detach, .id_table = vxp_ids, #ifdef CONFIG_PM @@ -421,16 +367,4 @@ static struct pcmcia_driver vxp_cs_driver = { .resume = vxp_resume, #endif }; - -static int __init init_vxpocket(void) -{ - return pcmcia_register_driver(&vxp_cs_driver); -} - -static void __exit exit_vxpocket(void) -{ - pcmcia_unregister_driver(&vxp_cs_driver); -} - -module_init(init_vxpocket); -module_exit(exit_vxpocket); +module_pcmcia_driver(vxp_cs_driver); |
