diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/contec_pci_dio.c')
-rw-r--r-- | drivers/staging/comedi/drivers/contec_pci_dio.c | 146 |
1 files changed, 45 insertions, 101 deletions
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 944cfeeb2b2..178a6a4bb7d 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -27,51 +27,35 @@ Author: Stefano Rivoir <s.rivoir@gts.it> Updated: Wed, 27 Jun 2007 13:00:06 +0100 Status: works -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration Options: not applicable, uses comedi PCI auto config */ #include "../comedidev.h" -enum contec_model { - PIO1616L = 0, -}; - -struct contec_board { - const char *name; - int model; - int in_ports; - int out_ports; - int in_offs; - int out_offs; - int out_boffs; -}; -static const struct contec_board contec_boards[] = { - {"PIO1616L", PIO1616L, 16, 16, 0, 2, 10}, -}; - #define PCI_DEVICE_ID_PIO1616L 0x8172 -#define thisboard ((const struct contec_board *)dev->board_ptr) +/* + * Register map + */ +#define PIO1616L_DI_REG 0x00 +#define PIO1616L_DO_REG 0x02 static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + unsigned int mask = data[0]; + unsigned int bits = data[1]; - dev_dbg(dev->class_dev, "contec_do_insn_bits called\n"); - dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - dev_dbg(dev->class_dev, "out: %d on %lx\n", s->state, - dev->iobase + thisboard->out_offs); - outw(s->state, dev->iobase + thisboard->out_offs); + outw(s->state, dev->iobase + PIO1616L_DO_REG); } + + data[1] = s->state; + return insn->n; } @@ -79,87 +63,49 @@ static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - - dev_dbg(dev->class_dev, "contec_di_insn_bits called\n"); - dev_dbg(dev->class_dev, "data: %d %d\n", data[0], data[1]); - - data[1] = inw(dev->iobase + thisboard->in_offs); + data[1] = inw(dev->iobase + PIO1616L_DI_REG); return insn->n; } -static struct pci_dev *contec_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_CONTEC || - pcidev->device != PCI_DEVICE_ID_PIO1616L) - continue; - - dev->board_ptr = contec_boards + 0; - return pcidev; - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - -static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int contec_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; - printk("comedi%d: contec: ", dev->minor); + comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = thisboard->name; + dev->board_name = dev->driver->driver_name; - ret = comedi_alloc_subdevices(dev, 2); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - - pcidev = contec_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - - if (comedi_pci_enable(pcidev, "contec_pci_dio")) { - printk("error enabling PCI device and request regions!\n"); - return -EIO; - } dev->iobase = pci_resource_start(pcidev, 0); - printk(" base addr %lx ", dev->iobase); - s = dev->subdevices + 0; - - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = contec_di_insn_bits; - - s = dev->subdevices + 1; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = contec_do_insn_bits; - - printk("attached\n"); + ret = comedi_alloc_subdevices(dev, 2); + if (ret) + return ret; - return 1; + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = contec_di_insn_bits; + + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = contec_do_insn_bits; + + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + + return 0; } static void contec_detach(struct comedi_device *dev) @@ -169,14 +115,13 @@ static void contec_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver contec_pci_dio_driver = { .driver_name = "contec_pci_dio", .module = THIS_MODULE, - .attach = contec_attach, + .attach_pci = contec_attach_pci, .detach = contec_detach, }; @@ -192,8 +137,7 @@ static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L), - .driver_data = PIO1616L }, + { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) }, { 0 } }; MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table); |