diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/quatech_daqp_cs.c')
-rw-r--r-- | drivers/staging/comedi/drivers/quatech_daqp_cs.c | 197 |
1 files changed, 36 insertions, 161 deletions
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index a91db6c42028..ebba9bb47777 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -14,7 +14,7 @@ Documentation for the DAQP PCMCIA cards can be found on Quatech's site: - ftp://ftp.quatech.com/Manuals/daqp-208.pdf + ftp://ftp.quatech.com/Manuals/daqp-208.pdf This manual is for both the DAQP-208 and the DAQP-308. @@ -50,8 +50,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #include "../comedidev.h" #include <linux/semaphore.h> -#include <pcmcia/cs_types.h> -#include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> @@ -195,7 +193,7 @@ static struct comedi_driver driver_daqp = { static void daqp_dump(struct comedi_device *dev) { - printk("DAQP: status %02x; aux status %02x\n", + printk(KERN_INFO "DAQP: status %02x; aux status %02x\n", inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX)); } @@ -207,9 +205,9 @@ static void hex_dump(char *str, void *ptr, int len) printk(str); for (i = 0; i < len; i++) { - if (i % 16 == 0) { - printk("\n0x%08x:", (unsigned int)cptr); - } + if (i % 16 == 0) + printk("\n%p:", cptr); + printk(" %02x", *(cptr++)); } printk("\n"); @@ -223,9 +221,9 @@ static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct local_info_t *local = (struct local_info_t *)s->private; - if (local->stop) { + if (local->stop) return -EIO; - } + outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND); @@ -355,9 +353,9 @@ static int daqp_ai_insn_read(struct comedi_device *dev, int v; int counter = 10000; - if (local->stop) { + if (local->stop) return -EIO; - } + /* Stop any running conversion */ daqp_ai_cancel(dev, s); @@ -372,9 +370,9 @@ static int daqp_ai_insn_read(struct comedi_device *dev, v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec)) | DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec)); - if (CR_AREF(insn->chanspec) == AREF_DIFF) { + if (CR_AREF(insn->chanspec) == AREF_DIFF) v |= DAQP_SCANLIST_DIFFERENTIAL; - } + v |= DAQP_SCANLIST_START; @@ -488,7 +486,10 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources + * are unique and mutually compatible + */ /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER && @@ -588,9 +589,9 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) int i; int v; - if (local->stop) { + if (local->stop) return -EIO; - } + /* Stop any running conversion */ daqp_ai_cancel(dev, s); @@ -640,13 +641,11 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec)) | DAQP_SCANLIST_GAIN(CR_RANGE(chanspec)); - if (CR_AREF(chanspec) == AREF_DIFF) { + if (CR_AREF(chanspec) == AREF_DIFF) v |= DAQP_SCANLIST_DIFFERENTIAL; - } - if (i == 0 || scanlist_start_on_every_entry) { + if (i == 0 || scanlist_start_on_every_entry) v |= DAQP_SCANLIST_START; - } outb(v & 0xff, dev->iobase + DAQP_SCANLIST); outb(v >> 8, dev->iobase + DAQP_SCANLIST); @@ -760,7 +759,8 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) while (--counter && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; if (!counter) { - printk("daqp: couldn't clear interrupts in status register\n"); + printk(KERN_ERR + "daqp: couldn't clear interrupts in status register\n"); return -1; } @@ -785,9 +785,8 @@ static int daqp_ao_insn_write(struct comedi_device *dev, int d; unsigned int chan; - if (local->stop) { + if (local->stop) return -EIO; - } chan = CR_CHAN(insn->chanspec); d = data[0]; @@ -811,9 +810,8 @@ static int daqp_di_insn_read(struct comedi_device *dev, { struct local_info_t *local = (struct local_info_t *)s->private; - if (local->stop) { + if (local->stop) return -EIO; - } data[0] = inb(dev->iobase + DAQP_DIGITAL_IO); @@ -828,9 +826,8 @@ static int daqp_do_insn_write(struct comedi_device *dev, { struct local_info_t *local = (struct local_info_t *)s->private; - if (local->stop) { + if (local->stop) return -EIO; - } outw(data[0] & 0xf, dev->iobase + DAQP_DIGITAL_IO); @@ -872,13 +869,13 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - dev->iobase = local->link->io.BasePort1; + dev->iobase = local->link->resource[0]->start; ret = alloc_subdevices(dev, 4); if (ret < 0) return ret; - printk("comedi%d: attaching daqp%d (io 0x%04lx)\n", + printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n", dev->minor, it->options[0], dev->iobase); s = dev->subdevices + 0; @@ -931,7 +928,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int daqp_detach(struct comedi_device *dev) { - printk("comedi%d: detaching daqp\n", dev->minor); + printk(KERN_INFO "comedi%d: detaching daqp\n", dev->minor); return 0; } @@ -971,51 +968,14 @@ static int daqp_detach(struct comedi_device *dev) ======================================================================*/ -/* - The event() function is this driver's Card Services event handler. - It will be called by Card Services when an appropriate card status - event is received. The config() and release() entry points are - used to configure or release a socket, in response to card - insertion and ejection events. - - Kernel version 2.6.16 upwards uses suspend() and resume() functions - instead of an event() function. -*/ - static void daqp_cs_config(struct pcmcia_device *link); static void daqp_cs_release(struct pcmcia_device *link); static int daqp_cs_suspend(struct pcmcia_device *p_dev); static int daqp_cs_resume(struct pcmcia_device *p_dev); -/* - The attach() and detach() entry points are used to create and destroy - "instances" of the driver, where each instance represents everything - needed to manage one actual PCMCIA card. -*/ - static int daqp_cs_attach(struct pcmcia_device *); static void daqp_cs_detach(struct pcmcia_device *); -/* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static const dev_info_t dev_info = "quatech_daqp_cs"; - -/*====================================================================== - - daqp_cs_attach() creates an "instance" of the driver, allocating - local data structures for one device. The device is registered - with Card Services. - - The dev_link structure is initialized, but we don't actually - configure the card at this point -- we wait until we receive a - card insertion event. - -======================================================================*/ - static int daqp_cs_attach(struct pcmcia_device *link) { struct local_info_t *local; @@ -1041,30 +1001,11 @@ static int daqp_cs_attach(struct pcmcia_device *link) local->link = link; link->priv = local; - /* - General socket configuration defaults can go here. In this - client, we assume very little, and rely on the CIS for almost - everything. In most clients, many details (i.e., number, sizes, - and attributes of IO windows) are fixed by the nature of the - device, and can be hard-wired here. - */ - link->conf.Attributes = 0; - link->conf.IntType = INT_MEMORY_AND_IO; - daqp_cs_config(link); return 0; } /* daqp_cs_attach */ -/*====================================================================== - - This deletes a driver "instance". The device is de-registered - with Card Services. If it has been released, all local data - structures are freed. Otherwise, the structures will be freed - when the device is released. - -======================================================================*/ - static void daqp_cs_detach(struct pcmcia_device *link) { struct local_info_t *dev = link->priv; @@ -1076,53 +1017,16 @@ static void daqp_cs_detach(struct pcmcia_device *link) /* Unlink device structure, and free it */ dev_table[dev->table_index] = NULL; - if (dev) - kfree(dev); + kfree(dev); } /* daqp_cs_detach */ -/*====================================================================== - - daqp_cs_config() is scheduled to run after a CARD_INSERTION event - is received, to configure the PCMCIA socket, and to make the - device available to the system. - -======================================================================*/ - - -static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data) +static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { - if (cfg->index == 0) - return -ENODEV; - - /* Do we need to allocate an interrupt? */ - p_dev->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; - if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - p_dev->io.BasePort1 = io->win[0].base; - p_dev->io.NumPorts1 = io->win[0].len; - if (io->nwin > 1) { - p_dev->io.Attributes2 = p_dev->io.Attributes1; - p_dev->io.BasePort2 = io->win[1].base; - p_dev->io.NumPorts2 = io->win[1].len; - } - } + if (p_dev->config_index == 0) + return -EINVAL; - /* This reserves IO space but doesn't actually enable it */ - return pcmcia_request_io(p_dev, &p_dev->io); + return pcmcia_request_io(p_dev); } static void daqp_cs_config(struct pcmcia_device *link) @@ -1131,6 +1035,8 @@ static void daqp_cs_config(struct pcmcia_device *link) dev_dbg(&link->dev, "daqp_cs_config\n"); + link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; + ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL); if (ret) { dev_warn(&link->dev, "no configuration found\n"); @@ -1141,27 +1047,10 @@ static void daqp_cs_config(struct pcmcia_device *link) if (ret) goto failed; - /* - This actually configures the PCMCIA socket -- setting up - the I/O windows and the interrupt mapping, and putting the - card and host interface into "Memory and IO" mode. - */ - ret = pcmcia_request_configuration(link, &link->conf); + ret = pcmcia_enable_device(link); if (ret) goto failed; - /* Finally, report what we've done */ - dev_info(&link->dev, "index 0x%02x", link->conf.ConfigIndex); - if (link->conf.Attributes & CONF_ENABLE_IRQ) - printk(", irq %u", link->irq); - if (link->io.NumPorts1) - printk(", io 0x%04x-0x%04x", link->io.BasePort1, - link->io.BasePort1 + link->io.NumPorts1 - 1); - if (link->io.NumPorts2) - printk(" & 0x%04x-0x%04x", link->io.BasePort2, - link->io.BasePort2 + link->io.NumPorts2 - 1); - printk("\n"); - return; failed: @@ -1176,18 +1065,6 @@ static void daqp_cs_release(struct pcmcia_device *link) pcmcia_disable_device(link); } /* daqp_cs_release */ -/*====================================================================== - - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. - - When a CARD_REMOVAL event is received, we immediately set a - private flag to block future accesses to this device. All the - functions that actually access the device should check this flag - to make sure the card is still present. - -======================================================================*/ - static int daqp_cs_suspend(struct pcmcia_device *link) { struct local_info_t *local = link->priv; @@ -1227,9 +1104,7 @@ static struct pcmcia_driver daqp_cs_driver = { .resume = daqp_cs_resume, .id_table = daqp_cs_id_table, .owner = THIS_MODULE, - .drv = { - .name = dev_info, - }, + .name = "quatech_daqp_cs", }; int __init init_module(void) |