diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/ni_660x.c')
-rw-r--r-- | drivers/staging/comedi/drivers/ni_660x.c | 144 |
1 files changed, 70 insertions, 74 deletions
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index e46dd7a1a724..5cdda7fe97a7 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -18,27 +18,25 @@ */ /* -Driver: ni_660x -Description: National Instruments 660x counter/timer boards -Devices: -[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, - PXI-6608 -Author: J.P. Mellor <jpmellor@rose-hulman.edu>, - Herman.Bruyninckx@mech.kuleuven.ac.be, - Wim.Meeussen@mech.kuleuven.ac.be, - Klaas.Gadeyne@mech.kuleuven.ac.be, - Frank Mori Hess <fmhess@users.sourceforge.net> -Updated: Thu Oct 18 12:56:06 EDT 2007 -Status: experimental - -Encoders work. PulseGeneration (both single pulse and pulse train) -works. Buffered commands work for input but not output. - -References: -DAQ 660x Register-Level Programmer Manual (NI 370505A-01) -DAQ 6601/6602 User Manual (NI 322137B-01) - -*/ + * Driver: ni_660x + * Description: National Instruments 660x counter/timer boards + * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, + * PXI-6608, PXI-6624 + * Author: J.P. Mellor <jpmellor@rose-hulman.edu>, + * Herman.Bruyninckx@mech.kuleuven.ac.be, + * Wim.Meeussen@mech.kuleuven.ac.be, + * Klaas.Gadeyne@mech.kuleuven.ac.be, + * Frank Mori Hess <fmhess@users.sourceforge.net> + * Updated: Fri, 15 Mar 2013 10:47:56 +0000 + * Status: experimental + * + * Encoders work. PulseGeneration (both single pulse and pulse train) + * works. Buffered commands work for input but not output. + * + * References: + * DAQ 660x Register-Level Programmer Manual (NI 370505A-01) + * DAQ 6601/6602 User Manual (NI 322137B-01) + */ #include <linux/pci.h> #include <linux/interrupt.h> @@ -389,34 +387,40 @@ enum global_interrupt_config_register_bits { /* First chip is at base-address + 0x00, etc. */ static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; -/* Board description*/ +enum ni_660x_boardid { + BOARD_PCI6601, + BOARD_PCI6602, + BOARD_PXI6602, + BOARD_PXI6608, + BOARD_PXI6624 +}; + struct ni_660x_board { - unsigned short dev_id; /* `lspci` will show you this */ const char *name; unsigned n_chips; /* total number of TIO chips */ }; static const struct ni_660x_board ni_660x_boards[] = { - { - .dev_id = 0x2c60, - .name = "PCI-6601", - .n_chips = 1, - }, - { - .dev_id = 0x1310, - .name = "PCI-6602", - .n_chips = 2, - }, - { - .dev_id = 0x1360, - .name = "PXI-6602", - .n_chips = 2, - }, - { - .dev_id = 0x2cc0, - .name = "PXI-6608", - .n_chips = 2, - }, + [BOARD_PCI6601] = { + .name = "PCI-6601", + .n_chips = 1, + }, + [BOARD_PCI6602] = { + .name = "PCI-6602", + .n_chips = 2, + }, + [BOARD_PXI6602] = { + .name = "PXI-6602", + .n_chips = 2, + }, + [BOARD_PXI6608] = { + .name = "PXI-6608", + .n_chips = 2, + }, + [BOARD_PXI6624] = { + .name = "PXI-6624", + .n_chips = 2, + }, }; #define NI_660X_MAX_NUM_CHIPS 2 @@ -883,7 +887,7 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) unsigned i; unsigned long flags; - if (dev->attached == 0) + if (!dev->attached) return IRQ_NONE; /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&devpriv->interrupt_lock, flags); @@ -974,20 +978,6 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) } } -static const struct ni_660x_board * -ni_660x_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int dev_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(ni_660x_boards); n++) { - const struct ni_660x_board *board = &ni_660x_boards[n]; - if (board->dev_id == dev_id) - return board; - } - return NULL; -} - static int ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1170,32 +1160,36 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, } static int ni_660x_auto_attach(struct comedi_device *dev, - unsigned long context_unused) + unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct ni_660x_board *board; + const struct ni_660x_board *board = NULL; struct ni_660x_private *devpriv; struct comedi_subdevice *s; int ret; unsigned i; unsigned global_interrupt_config_bits; + if (context < ARRAY_SIZE(ni_660x_boards)) + board = &ni_660x_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + + ret = comedi_pci_enable(dev); + if (ret) + return ret; + ret = ni_660x_allocate_private(dev); if (ret < 0) return ret; devpriv = dev->private; - dev->board_ptr = ni_660x_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - board = comedi_board(dev); - devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; - dev->board_name = board->name; - ret = mite_setup2(devpriv->mite, 1); if (ret < 0) { dev_warn(dev->class_dev, "error setting up mite\n"); @@ -1315,6 +1309,7 @@ static void ni_660x_detach(struct comedi_device *dev) mite_free(devpriv->mite); } } + comedi_pci_disable(dev); } static struct comedi_driver ni_660x_driver = { @@ -1325,17 +1320,18 @@ static struct comedi_driver ni_660x_driver = { }; static int ni_660x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &ni_660x_driver); + return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data); } static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, - {0} + { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 }, + { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 }, + { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 }, + { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 }, + { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 }, + { 0 } }; MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); |