diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/cb_pcidas.c')
-rw-r--r-- | drivers/staging/comedi/drivers/cb_pcidas.c | 202 |
1 files changed, 66 insertions, 136 deletions
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 2b6a637c349..de21a261ff4 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -45,11 +45,7 @@ Status: The boards may be autocalibrated using the comedi_calibrate utility. -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 PCI auto config For commands, the scanned channels must be consecutive (i.e. 4-5-6-7, 2-3-4,...), and must all have the same @@ -807,58 +803,35 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, int tmp; int i, gain, start_chan; - /* step 1: trigger sources are trivially valid */ + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->start_src; - cmd->start_src &= TRIG_NOW | TRIG_EXT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; - - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, + TRIG_TIMER | TRIG_NOW | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) - err++; - if (cmd->scan_begin_src != TRIG_FOLLOW && - cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->convert_src != TRIG_TIMER && - cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->convert_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ - /* make sure trigger sources are compatible with each other */ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) - err++; + err |= -EINVAL; if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) - err++; + err |= -EINVAL; if (cmd->start_src == TRIG_EXT && (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) - err++; + err |= -EINVAL; if (err) return 2; @@ -1083,43 +1056,24 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, int err = 0; int tmp; - /* step 1: trigger sources are trivially valid */ - - tmp = cmd->start_src; - cmd->start_src &= TRIG_INT; - if (!cmd->start_src || tmp != cmd->start_src) - err++; - - tmp = cmd->scan_begin_src; - cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; - if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) - err++; + /* Step 1 : check if triggers are trivially valid */ - tmp = cmd->convert_src; - cmd->convert_src &= TRIG_NOW; - if (!cmd->convert_src || tmp != cmd->convert_src) - err++; - - tmp = cmd->scan_end_src; - cmd->scan_end_src &= TRIG_COUNT; - if (!cmd->scan_end_src || tmp != cmd->scan_end_src) - err++; - - tmp = cmd->stop_src; - cmd->stop_src &= TRIG_COUNT | TRIG_NONE; - if (!cmd->stop_src || tmp != cmd->stop_src) - err++; + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, + TRIG_TIMER | TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); if (err) return 1; - /* step 2: trigger sources are unique and mutually compatible */ + /* Step 2a : make sure trigger sources are unique */ - if (cmd->scan_begin_src != TRIG_TIMER && - cmd->scan_begin_src != TRIG_EXT) - err++; - if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) - err++; + err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ if (err) return 2; @@ -1501,69 +1455,45 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) return IRQ_HANDLED; } -static struct pci_dev *cb_pcidas_find_pci_device(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cb_pcidas_board *thisboard; - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; int i; - for_each_pci_dev(pcidev) { - /* is it not a computer boards card? */ - if (pcidev->vendor != PCI_VENDOR_ID_CB) - continue; - /* loop through cards supported by this driver */ - for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) { - thisboard = &cb_pcidas_boards[i]; - if (thisboard->device_id != pcidev->device) - continue; - /* was a particular bus/slot requested? */ - if (bus || slot) { - /* are we on the wrong bus/slot? */ - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) { - continue; - } - } - dev_dbg(dev->class_dev, - "Found %s on bus %i, slot %i\n", - thisboard->name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn)); - dev->board_ptr = thisboard; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) { + thisboard = &cb_pcidas_boards[i]; + if (thisboard->device_id == pcidev->device) + return thisboard; } - dev_err(dev->class_dev, "No supported card found\n"); return NULL; } -static int cb_pcidas_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int cb_pcidas_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct cb_pcidas_board *thisboard; struct cb_pcidas_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int i; int ret; - if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0) - return -ENOMEM; - devpriv = dev->private; - - pcidev = cb_pcidas_find_pci_device(dev, it); - if (!pcidev) - return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "Failed to enable PCI device and request regions\n"); - return -EIO; - } + thisboard = cb_pcidas_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + + 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; devpriv->s5933_config = pci_resource_start(pcidev, 0); devpriv->control_status = pci_resource_start(pcidev, 1); @@ -1584,13 +1514,11 @@ static int cb_pcidas_attach(struct comedi_device *dev, } dev->irq = pcidev->irq; - dev->board_name = thisboard->name; - ret = comedi_alloc_subdevices(dev, 7); if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ dev->read_subdev = s; s->type = COMEDI_SUBD_AI; @@ -1607,7 +1535,7 @@ static int cb_pcidas_attach(struct comedi_device *dev, s->cancel = cb_pcidas_cancel; /* analog output subdevice */ - s = dev->subdevices + 1; + s = &dev->subdevices[1]; if (thisboard->ao_nchan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; @@ -1634,14 +1562,14 @@ static int cb_pcidas_attach(struct comedi_device *dev, } /* 8255 */ - s = dev->subdevices + 2; + s = &dev->subdevices[2]; ret = subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255); if (ret) return ret; /* serial EEPROM, */ - s = dev->subdevices + 3; + s = &dev->subdevices[3]; s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; s->n_chan = 256; @@ -1649,7 +1577,7 @@ static int cb_pcidas_attach(struct comedi_device *dev, s->insn_read = eeprom_read_insn; /* 8800 caldac */ - s = dev->subdevices + 4; + s = &dev->subdevices[4]; s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = NUM_CHANNELS_8800; @@ -1660,7 +1588,7 @@ static int cb_pcidas_attach(struct comedi_device *dev, caldac_8800_write(dev, i, s->maxdata / 2); /* trim potentiometer */ - s = dev->subdevices + 5; + s = &dev->subdevices[5]; s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; if (thisboard->trimpot == AD7376) { @@ -1676,7 +1604,7 @@ static int cb_pcidas_attach(struct comedi_device *dev, cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); /* dac08 caldac */ - s = dev->subdevices + 6; + s = &dev->subdevices[6]; if (thisboard->has_dac08) { s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; @@ -1698,7 +1626,10 @@ static int cb_pcidas_attach(struct comedi_device *dev, outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, devpriv->s5933_config + AMCC_OP_REG_INTCSR); - return 1; + dev_info(dev->class_dev, "%s: %s attached\n", + dev->driver->driver_name, dev->board_name); + + return 0; } static void cb_pcidas_detach(struct comedi_device *dev) @@ -1715,18 +1646,17 @@ static void cb_pcidas_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) - subdev_8255_cleanup(dev, dev->subdevices + 2); + subdev_8255_cleanup(dev, &dev->subdevices[2]); if (pcidev) { if (devpriv->s5933_config) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver cb_pcidas_driver = { .driver_name = "cb_pcidas", .module = THIS_MODULE, - .attach = cb_pcidas_attach, + .attach_pci = cb_pcidas_attach_pci, .detach = cb_pcidas_detach, }; |