diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/cb_pcimdas.c')
-rw-r--r-- | drivers/staging/comedi/drivers/cb_pcimdas.c | 156 |
1 files changed, 62 insertions, 94 deletions
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 5f834d02ec24..c632a89f3ae9 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -45,7 +45,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #include <linux/delay.h> #include <linux/interrupt.h> -#include "comedi_pci.h" #include "plx9052.h" #include "8255.h" @@ -57,11 +56,7 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. /* Registers for the PCIM-DAS1602/16 */ /* sizes of io regions (bytes) */ -#define BADR0_SIZE 2 /* ?? */ -#define BADR1_SIZE 4 -#define BADR2_SIZE 6 #define BADR3_SIZE 16 -#define BADR4_SIZE 4 /* DAC Offsets */ #define ADC_TRIG 0 @@ -123,8 +118,6 @@ static const struct cb_pcimdas_board cb_pcimdas_boards[] = { }, }; -#define N_BOARDS 1 /* Max number of boards supported */ - /* * Useful for shorthand access to the particular board structure */ @@ -137,27 +130,11 @@ static const struct cb_pcimdas_board cb_pcimdas_boards[] = { * struct. */ struct cb_pcimdas_private { - int data; - - /* would be useful for a PCI device */ - struct pci_dev *pci_dev; - /* base addresses */ - unsigned long BADR0; - unsigned long BADR1; - unsigned long BADR2; unsigned long BADR3; - unsigned long BADR4; /* Used for AO readback */ unsigned int ao_readback[2]; - - /* Used for DIO */ - unsigned short int port_a; /* copy of BADR4+0 */ - unsigned short int port_b; /* copy of BADR4+1 */ - unsigned short int port_c; /* copy of BADR4+2 */ - unsigned short int dio_mode; /* copy of BADR4+3 */ - }; /* @@ -176,6 +153,37 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); +static struct pci_dev *cb_pcimdas_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_COMPUTERBOARDS) + continue; + + for (i = 0; i < ARRAY_SIZE(cb_pcimdas_boards); i++) { + if (cb_pcimdas_boards[i].device_id != pcidev->device) + continue; + + dev->board_ptr = cb_pcimdas_boards + i; + return pcidev; + } + } + dev_err(dev->class_dev, + "No supported board found! (req. bus %d, slot %d)\n", + bus, slot); + return NULL; +} + /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -185,10 +193,10 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pci_dev *pcidev; struct comedi_subdevice *s; - struct pci_dev *pcidev = NULL; - int index; - /* int i; */ + unsigned long iobase_8255; + int ret; /* * Allocate the private structure area. @@ -196,86 +204,46 @@ static int cb_pcimdas_attach(struct comedi_device *dev, if (alloc_private(dev, sizeof(struct cb_pcimdas_private)) < 0) return -ENOMEM; -/* - * Probe the device to determine what device in the series it is. - */ - - for_each_pci_dev(pcidev) { - /* is it not a computer boards card? */ - if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) - continue; - /* loop through cards supported by this driver */ - for (index = 0; index < N_BOARDS; index++) { - if (cb_pcimdas_boards[index].device_id != - pcidev->device) - continue; - /* was a particular bus/slot requested? */ - if (it->options[0] || it->options[1]) { - /* are we on the wrong bus/slot? */ - if (pcidev->bus->number != it->options[0] || - PCI_SLOT(pcidev->devfn) != it->options[1]) { - continue; - } - } - devpriv->pci_dev = pcidev; - dev->board_ptr = cb_pcimdas_boards + index; - goto found; - } - } - - dev_err(dev->hw_dev, "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); - return -EIO; - -found: - - dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", - cb_pcimdas_boards[index].name, pcidev->bus->number, - PCI_SLOT(pcidev->devfn)); + pcidev = cb_pcimdas_find_pci_dev(dev, it); + if (!pcidev) + return -EIO; + comedi_set_hw_dev(dev, &pcidev->dev); /* Warn about non-tested features */ switch (thisboard->device_id) { case 0x56: break; default: - dev_dbg(dev->hw_dev, "THIS CARD IS UNSUPPORTED.\n" + dev_dbg(dev->class_dev, "THIS CARD IS UNSUPPORTED.\n"); + dev_dbg(dev->class_dev, "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n"); } if (comedi_pci_enable(pcidev, "cb_pcimdas")) { - dev_err(dev->hw_dev, "Failed to enable PCI device and request regions\n"); + dev_err(dev->class_dev, + "Failed to enable PCI device and request regions\n"); return -EIO; } - devpriv->BADR0 = pci_resource_start(devpriv->pci_dev, 0); - devpriv->BADR1 = pci_resource_start(devpriv->pci_dev, 1); - devpriv->BADR2 = pci_resource_start(devpriv->pci_dev, 2); - devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3); - devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4); - - dev_dbg(dev->hw_dev, "devpriv->BADR0 = 0x%lx\n", devpriv->BADR0); - dev_dbg(dev->hw_dev, "devpriv->BADR1 = 0x%lx\n", devpriv->BADR1); - dev_dbg(dev->hw_dev, "devpriv->BADR2 = 0x%lx\n", devpriv->BADR2); - dev_dbg(dev->hw_dev, "devpriv->BADR3 = 0x%lx\n", devpriv->BADR3); - dev_dbg(dev->hw_dev, "devpriv->BADR4 = 0x%lx\n", devpriv->BADR4); + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->BADR3 = pci_resource_start(pcidev, 3); + iobase_8255 = pci_resource_start(pcidev, 4); /* Dont support IRQ yet */ /* get irq */ -/* if(request_irq(devpriv->pci_dev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev )) */ +/* if(request_irq(pcidev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev )) */ /* { */ -/* printk(" unable to allocate irq %u\n", devpriv->pci_dev->irq); */ +/* printk(" unable to allocate irq %u\n", pcidev->irq); */ /* return -EINVAL; */ /* } */ -/* dev->irq = devpriv->pci_dev->irq; */ +/* dev->irq = pcidev->irq; */ /* Initialize dev->board_name */ dev->board_name = thisboard->name; -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_subdevices(dev, 3) < 0) - return -ENOMEM; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = dev->subdevices + 0; /* dev->read_subdev=s; */ @@ -303,7 +271,7 @@ found: s = dev->subdevices + 2; /* digital i/o subdevice */ if (thisboard->has_dio) - subdev_8255_init(dev, s, NULL, devpriv->BADR4); + subdev_8255_init(dev, s, NULL, iobase_8255); else s->type = COMEDI_SUBD_UNUSED; @@ -312,14 +280,14 @@ found: static void cb_pcimdas_detach(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + if (dev->irq) free_irq(dev->irq, dev); - if (devpriv) { - if (devpriv->pci_dev) { - if (devpriv->BADR0) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + pci_dev_put(pcidev); } } @@ -368,7 +336,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion */ - outw(0, devpriv->BADR2 + 0); + outw(0, dev->iobase + 0); #define TIMEOUT 1000 /* typically takes 5 loops on a lightly loaded Pentium 100MHz, */ /* this is likely to be 100 loops on a 2GHz machine, so set 1000 as the limit. */ @@ -384,7 +352,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, return -ETIMEDOUT; } /* read data */ - d = inw(devpriv->BADR2 + 0); + d = inw(dev->iobase + 0); /* mangle the data as necessary */ /* d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed. */ @@ -408,10 +376,10 @@ static int cb_pcimdas_ao_winsn(struct comedi_device *dev, for (i = 0; i < insn->n; i++) { switch (chan) { case 0: - outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC0_OFFSET); + outw(data[i] & 0x0FFF, dev->iobase + DAC0_OFFSET); break; case 1: - outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC1_OFFSET); + outw(data[i] & 0x0FFF, dev->iobase + DAC1_OFFSET); break; default: return -1; |