diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/dyna_pci10xx.c')
-rw-r--r-- | drivers/staging/comedi/drivers/dyna_pci10xx.c | 161 |
1 files changed, 36 insertions, 125 deletions
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 064be9aae3aa..6f612be1b0a5 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -41,7 +41,6 @@ #include <linux/mutex.h> #define PCI_VENDOR_ID_DYNALOG 0x10b5 -#define DRV_NAME "dyna_pci10xx" #define READ_TIMEOUT 50 @@ -54,59 +53,11 @@ static const struct comedi_lrange range_pci1050_ai = { 3, { static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 }; -static const struct comedi_lrange range_pci1050_ao = { 1, { - UNI_RANGE(10) - } -}; - -static const char range_codes_pci1050_ao[] = { 0x00 }; - -struct boardtype { - const char *name; - int device_id; - int ai_chans; - int ai_bits; - int ao_chans; - int ao_bits; - int di_chans; - int di_bits; - int do_chans; - int do_bits; - const struct comedi_lrange *range_ai; - const char *range_codes_ai; - const struct comedi_lrange *range_ao; - const char *range_codes_ao; -}; - -static const struct boardtype boardtypes[] = { - { - .name = "dyna_pci1050", - .device_id = 0x1050, - .ai_chans = 16, - .ai_bits = 12, - .ao_chans = 16, - .ao_bits = 12, - .di_chans = 16, - .di_bits = 16, - .do_chans = 16, - .do_bits = 16, - .range_ai = &range_pci1050_ai, - .range_codes_ai = range_codes_pci1050_ai, - .range_ao = &range_pci1050_ao, - .range_codes_ao = range_codes_pci1050_ao, - }, - /* dummy entry corresponding to driver name */ - {.name = DRV_NAME}, -}; - struct dyna_pci10xx_private { struct mutex mutex; unsigned long BADR3; }; -#define thisboard ((const struct boardtype *)dev->board_ptr) -#define devpriv ((struct dyna_pci10xx_private *)dev->private) - /******************************************************************************/ /************************** READ WRITE FUNCTIONS ******************************/ /******************************************************************************/ @@ -116,13 +67,14 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dyna_pci10xx_private *devpriv = dev->private; int n, counter; u16 d = 0; unsigned int chan, range; /* get the channel number and range */ chan = CR_CHAN(insn->chanspec); - range = thisboard->range_codes_ai[CR_RANGE((insn->chanspec))]; + range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))]; mutex_lock(&devpriv->mutex); /* convert n samples */ @@ -159,11 +111,12 @@ static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dyna_pci10xx_private *devpriv = dev->private; int n; unsigned int chan, range; chan = CR_CHAN(insn->chanspec); - range = thisboard->range_codes_ai[CR_RANGE((insn->chanspec))]; + range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))]; mutex_lock(&devpriv->mutex); for (n = 0; n < insn->n; n++) { @@ -181,6 +134,7 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dyna_pci10xx_private *devpriv = dev->private; u16 d = 0; mutex_lock(&devpriv->mutex); @@ -200,6 +154,8 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dyna_pci10xx_private *devpriv = dev->private; + /* The insn data is a mask in data[0] and the new data * in data[1], each channel cooresponding to a bit. * s->state contains the previous write data @@ -223,143 +179,98 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, return insn->n; } -static struct pci_dev *dyna_pci10xx_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]; - int i; - - 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_DYNALOG) - continue; - - for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { - if (pcidev->device != boardtypes[i].device_id) - continue; - - dev->board_ptr = &boardtypes[i]; - return pcidev; - } - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - -static int dyna_pci10xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int dyna_pci10xx_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev; + struct dyna_pci10xx_private *devpriv; struct comedi_subdevice *s; int ret; - if (alloc_private(dev, sizeof(struct dyna_pci10xx_private)) < 0) { - printk(KERN_ERR "comedi: dyna_pci10xx: " - "failed to allocate memory!\n"); - return -ENOMEM; - } - - pcidev = dyna_pci10xx_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = thisboard->name; - dev->irq = 0; - - if (comedi_pci_enable(pcidev, DRV_NAME)) { - printk(KERN_ERR "comedi: dyna_pci10xx: " - "failed to enable PCI device and request regions!"); - return -EIO; - } - - mutex_init(&devpriv->mutex); + dev->board_name = dev->driver->driver_name; - printk(KERN_INFO "comedi: dyna_pci10xx: device found!\n"); + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = pci_resource_start(pcidev, 2); devpriv->BADR3 = pci_resource_start(pcidev, 3); + mutex_init(&devpriv->mutex); + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; /* analog input */ - s = dev->subdevices + 0; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai_chans; + s->n_chan = 16; s->maxdata = 0x0FFF; - s->range_table = thisboard->range_ai; + s->range_table = &range_pci1050_ai; s->len_chanlist = 16; s->insn_read = dyna_pci10xx_insn_read_ai; /* analog output */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_chans; + s->n_chan = 16; s->maxdata = 0x0FFF; - s->range_table = thisboard->range_ao; + s->range_table = &range_unipolar10; s->len_chanlist = 16; s->insn_write = dyna_pci10xx_insn_write_ao; /* digital input */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = thisboard->di_chans; + s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->len_chanlist = thisboard->di_chans; + s->len_chanlist = 16; s->insn_bits = dyna_pci10xx_di_insn_bits; /* digital output */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = thisboard->do_chans; + s->n_chan = 16; s->maxdata = 1; s->range_table = &range_digital; - s->len_chanlist = thisboard->do_chans; + s->len_chanlist = 16; s->state = 0; s->insn_bits = dyna_pci10xx_do_insn_bits; - printk(KERN_INFO "comedi: dyna_pci10xx: %s - device setup completed!\n", - thisboard->name); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); - return 1; + return 0; } static void dyna_pci10xx_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct dyna_pci10xx_private *devpriv = dev->private; if (devpriv) mutex_destroy(&devpriv->mutex); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver dyna_pci10xx_driver = { .driver_name = "dyna_pci10xx", .module = THIS_MODULE, - .attach = dyna_pci10xx_attach, + .attach_pci = dyna_pci10xx_attach_pci, .detach = dyna_pci10xx_detach, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), - .num_names = ARRAY_SIZE(boardtypes), }; static int __devinit dyna_pci10xx_pci_probe(struct pci_dev *dev, |