diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5e1d8308faa9cf80893339f5ec0c469c4772928e..2cd7e10a8ca5bbf96ffdff69a0e32d1d36d071a3 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -419,16 +419,6 @@ static const struct ni_660x_board ni_660x_boards[] = { #define NI_660X_MAX_NUM_CHIPS 2 #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) -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} -}; - -MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); - struct ni_660x_private { struct mite_struct *mite; struct ni_gpct_device *counter_dev; @@ -449,64 +439,6 @@ static inline const struct ni_660x_board *board(struct comedi_device *dev) return dev->board_ptr; } -static int ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev); -static void ni_660x_detach(struct comedi_device *dev); -static void init_tio_chip(struct comedi_device *dev, int chipset); -static void ni_660x_select_pfi_output(struct comedi_device *dev, - unsigned pfi_channel, - unsigned output_select); - -static struct comedi_driver ni_660x_driver = { - .driver_name = "ni_660x", - .module = THIS_MODULE, - .attach_pci = ni_660x_attach_pci, - .detach = ni_660x_detach, -}; - -static int __devinit ni_660x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &ni_660x_driver); -} - -static void __devexit ni_660x_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver ni_660x_pci_driver = { - .name = "ni_660x", - .id_table = ni_660x_pci_table, - .probe = ni_660x_pci_probe, - .remove = __devexit_p(ni_660x_pci_remove) -}; -module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); - -static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, - unsigned source); - -/* Possible instructions for a GPCT */ -static int ni_660x_GPCT_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ni_660x_GPCT_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int ni_660x_GPCT_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Possible instructions for Digital IO */ -static int ni_660x_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int ni_660x_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - static inline unsigned ni_660x_num_counters(struct comedi_device *dev) { return board(dev)->n_chips * counters_per_chip; @@ -1055,150 +987,6 @@ ni_660x_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - struct ni_660x_private *devpriv; - struct comedi_subdevice *s; - int ret; - unsigned i; - unsigned global_interrupt_config_bits; - - 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; - devpriv->mite = mite_alloc(pcidev); - if (!devpriv->mite) - return -ENOMEM; - - dev->board_name = board(dev)->name; - - ret = mite_setup2(devpriv->mite, 1); - if (ret < 0) { - dev_warn(dev->class_dev, "error setting up mite\n"); - return ret; - } - - ret = ni_660x_alloc_mite_rings(dev); - if (ret < 0) - return ret; - - ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); - if (ret) - return ret; - - s = &dev->subdevices[0]; - /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ - s->type = COMEDI_SUBD_UNUSED; - - s = &dev->subdevices[NI_660X_DIO_SUBDEV]; - /* DIGITAL I/O SUBDEVICE */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = NUM_PFI_CHANNELS; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = ni_660x_dio_insn_bits; - s->insn_config = ni_660x_dio_insn_config; - s->io_bits = 0; /* all bits default to input */ - /* we use the ioconfig registers to control dio direction, so zero - output enables in stc dio control reg */ - ni_660x_write_register(dev, 0, 0, STCDIOControl); - - devpriv->counter_dev = ni_gpct_device_construct(dev, - &ni_gpct_write_register, - &ni_gpct_read_register, - ni_gpct_variant_660x, - ni_660x_num_counters - (dev)); - if (devpriv->counter_dev == NULL) - return -ENOMEM; - for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { - s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; - if (i < ni_660x_num_counters(dev)) { - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | - SDF_CMD_READ /* | SDF_CMD_WRITE */ ; - s->n_chan = 3; - s->maxdata = 0xffffffff; - s->insn_read = ni_660x_GPCT_rinsn; - s->insn_write = ni_660x_GPCT_winsn; - s->insn_config = ni_660x_GPCT_insn_config; - s->do_cmd = &ni_660x_cmd; - s->len_chanlist = 1; - s->do_cmdtest = &ni_660x_cmdtest; - s->cancel = &ni_660x_cancel; - s->poll = &ni_660x_input_poll; - s->async_dma_dir = DMA_BIDIRECTIONAL; - s->buf_change = &ni_660x_buf_change; - s->private = &devpriv->counter_dev->counters[i]; - - devpriv->counter_dev->counters[i].chip_index = - i / counters_per_chip; - devpriv->counter_dev->counters[i].counter_index = - i % counters_per_chip; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - } - for (i = 0; i < board(dev)->n_chips; ++i) - init_tio_chip(dev, i); - - for (i = 0; i < ni_660x_num_counters(dev); ++i) - ni_tio_init_counter(&devpriv->counter_dev->counters[i]); - - for (i = 0; i < NUM_PFI_CHANNELS; ++i) { - if (i < min_counter_pfi_chan) - ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); - else - ni_660x_set_pfi_routing(dev, i, - pfi_output_select_counter); - ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); - } - /* to be safe, set counterswap bits on tio chips after all the counter - outputs have been set to high impedance mode */ - for (i = 0; i < board(dev)->n_chips; ++i) - set_tio_counterswap(dev, i); - - ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt, - IRQF_SHARED, "ni_660x", dev); - if (ret < 0) { - dev_warn(dev->class_dev, " irq not available\n"); - return ret; - } - dev->irq = mite_irq(devpriv->mite); - global_interrupt_config_bits = Global_Int_Enable_Bit; - if (board(dev)->n_chips > 1) - global_interrupt_config_bits |= Cascade_Int_Enable_Bit; - ni_660x_write_register(dev, 0, global_interrupt_config_bits, - GlobalInterruptConfigRegister); - dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); - return 0; -} - -static void ni_660x_detach(struct comedi_device *dev) -{ - struct ni_660x_private *devpriv = dev->private; - - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv) { - if (devpriv->counter_dev) - ni_gpct_device_destroy(devpriv->counter_dev); - if (devpriv->mite) { - ni_660x_free_mite_rings(dev); - mite_unsetup(devpriv->mite); - mite_free(devpriv->mite); - } - } -} - static int ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1390,6 +1178,185 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, return 0; } +static int __devinit ni_660x_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + struct ni_660x_private *devpriv; + struct comedi_subdevice *s; + int ret; + unsigned i; + unsigned global_interrupt_config_bits; + + 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; + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) + return -ENOMEM; + + dev->board_name = board(dev)->name; + + ret = mite_setup2(devpriv->mite, 1); + if (ret < 0) { + dev_warn(dev->class_dev, "error setting up mite\n"); + return ret; + } + + ret = ni_660x_alloc_mite_rings(dev); + if (ret < 0) + return ret; + + ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); + if (ret) + return ret; + + s = &dev->subdevices[0]; + /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ + s->type = COMEDI_SUBD_UNUSED; + + s = &dev->subdevices[NI_660X_DIO_SUBDEV]; + /* DIGITAL I/O SUBDEVICE */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = NUM_PFI_CHANNELS; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = ni_660x_dio_insn_bits; + s->insn_config = ni_660x_dio_insn_config; + s->io_bits = 0; /* all bits default to input */ + /* we use the ioconfig registers to control dio direction, so zero + output enables in stc dio control reg */ + ni_660x_write_register(dev, 0, 0, STCDIOControl); + + devpriv->counter_dev = ni_gpct_device_construct(dev, + &ni_gpct_write_register, + &ni_gpct_read_register, + ni_gpct_variant_660x, + ni_660x_num_counters + (dev)); + if (devpriv->counter_dev == NULL) + return -ENOMEM; + for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { + s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; + if (i < ni_660x_num_counters(dev)) { + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | + SDF_CMD_READ /* | SDF_CMD_WRITE */ ; + s->n_chan = 3; + s->maxdata = 0xffffffff; + s->insn_read = ni_660x_GPCT_rinsn; + s->insn_write = ni_660x_GPCT_winsn; + s->insn_config = ni_660x_GPCT_insn_config; + s->do_cmd = &ni_660x_cmd; + s->len_chanlist = 1; + s->do_cmdtest = &ni_660x_cmdtest; + s->cancel = &ni_660x_cancel; + s->poll = &ni_660x_input_poll; + s->async_dma_dir = DMA_BIDIRECTIONAL; + s->buf_change = &ni_660x_buf_change; + s->private = &devpriv->counter_dev->counters[i]; + + devpriv->counter_dev->counters[i].chip_index = + i / counters_per_chip; + devpriv->counter_dev->counters[i].counter_index = + i % counters_per_chip; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + } + for (i = 0; i < board(dev)->n_chips; ++i) + init_tio_chip(dev, i); + + for (i = 0; i < ni_660x_num_counters(dev); ++i) + ni_tio_init_counter(&devpriv->counter_dev->counters[i]); + + for (i = 0; i < NUM_PFI_CHANNELS; ++i) { + if (i < min_counter_pfi_chan) + ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); + else + ni_660x_set_pfi_routing(dev, i, + pfi_output_select_counter); + ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); + } + /* to be safe, set counterswap bits on tio chips after all the counter + outputs have been set to high impedance mode */ + for (i = 0; i < board(dev)->n_chips; ++i) + set_tio_counterswap(dev, i); + + ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt, + IRQF_SHARED, "ni_660x", dev); + if (ret < 0) { + dev_warn(dev->class_dev, " irq not available\n"); + return ret; + } + dev->irq = mite_irq(devpriv->mite); + global_interrupt_config_bits = Global_Int_Enable_Bit; + if (board(dev)->n_chips > 1) + global_interrupt_config_bits |= Cascade_Int_Enable_Bit; + ni_660x_write_register(dev, 0, global_interrupt_config_bits, + GlobalInterruptConfigRegister); + dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); + return 0; +} + +static void ni_660x_detach(struct comedi_device *dev) +{ + struct ni_660x_private *devpriv = dev->private; + + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (devpriv->counter_dev) + ni_gpct_device_destroy(devpriv->counter_dev); + if (devpriv->mite) { + ni_660x_free_mite_rings(dev); + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } + } +} + +static struct comedi_driver ni_660x_driver = { + .driver_name = "ni_660x", + .module = THIS_MODULE, + .attach_pci = ni_660x_attach_pci, + .detach = ni_660x_detach, +}; + +static int __devinit ni_660x_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &ni_660x_driver); +} + +static void __devexit ni_660x_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +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} +}; +MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); + +static struct pci_driver ni_660x_pci_driver = { + .name = "ni_660x", + .id_table = ni_660x_pci_table, + .probe = ni_660x_pci_probe, + .remove = __devexit_p(ni_660x_pci_remove), +}; +module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL");