The PCMCIA support for the National Instruments Lab-PC DAQCard-1200 is already handled by a separate module, ni_labpc_cs. Split the bus specific ISA and PCI code out of this driver and create two new drivers, ni_labpc_isa and ni_labpc_pci. This allows the ni_labpc module to be a standalone module with all the "common" code. This allows removing all the #ifdef'ery in the comedi_driver (*attach), (*auto_attach), and (*detach) functions. All the bus specific operations are now handled in the bus specific drivers. Modify the parameters passed to labpc_common_attach(). The bus specific drivers now handle setting dev->iobase as appropriate for the bus. The ISA driver is the only one that uses dma so the allocation of the dma channel has been moved to it's private (*attach) function. Pass the appropriate irq flags to labpc_common_attach() so it does not have to deal with the bus type. Cleanup the multi-line comments at the beginning of each file so they follow the coding style and are appropriate for the new configuration of the drivers. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/Kconfig | 36 ++- drivers/staging/comedi/drivers/Makefile | 2 + drivers/staging/comedi/drivers/ni_labpc.c | 441 ++++---------------------- drivers/staging/comedi/drivers/ni_labpc.h | 9 +- drivers/staging/comedi/drivers/ni_labpc_cs.c | 119 +++---- drivers/staging/comedi/drivers/ni_labpc_isa.c | 194 +++++++++++ drivers/staging/comedi/drivers/ni_labpc_pci.c | 140 ++++++++ 7 files changed, 482 insertions(+), 459 deletions(-) create mode 100644 drivers/staging/comedi/drivers/ni_labpc_isa.c create mode 100644 drivers/staging/comedi/drivers/ni_labpc_pci.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 7841399..150f407 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -484,6 +484,20 @@ config COMEDI_NI_ATMIO16D To compile this driver as a module, choose M here: the module will be called ni_atmio16d. +config COMEDI_NI_LABPC_ISA + tristate "NI Lab-PC and compatibles ISA support" + depends on VIRT_TO_BUS + depends on ISA_DMA_API + select COMEDI_NI_LABPC + ---help--- + Enable support for National Instruments Lab-PC and compatibles + Lab-PC-1200, Lab-PC-1200AI, Lab-PC+. + Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has + not yet been added to the driver. + + To compile this driver as a module, choose M here: the module will be + called ni_labpc_isa. + config COMEDI_PCMAD tristate "Winsystems PCM-A/D12 and PCM-A/D16 PC/104 board support" ---help--- @@ -1007,20 +1021,15 @@ config COMEDI_NI_670X To compile this driver as a module, choose M here: the module will be called ni_670x. -config COMEDI_NI_LABPC - tristate "NI Lab-PC and compatibles ISA and PCI support" +config COMEDI_NI_LABPC_PCI + tristate "NI Lab-PC PCI-1200 support" select COMEDI_MITE - select COMEDI_8255 - select COMEDI_FC - depends on VIRT_TO_BUS + select COMEDI_NI_LABPC ---help--- - Enable support for National Instruments Lab-PC and compatibles - Lab-PC-1200, Lab-PC-1200AI, Lab-PC+ and PCI-1200. - Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has - not yet been added to the driver. + Enable support for National Instruments Lab-PC PCI-1200. To compile this driver as a module, choose M here: the module will be - called ni_labpc. + called ni_labpc_pci. config COMEDI_NI_PCIDIO tristate "NI PCI-DIO32HS, PCI-6533, PCI-6534 support" @@ -1142,7 +1151,7 @@ config COMEDI_NI_DAQ_DIO24_CS config COMEDI_NI_LABPC_CS tristate "NI DAQCard-1200 PCMCIA support" - depends on COMEDI_NI_LABPC + select COMEDI_NI_LABPC ---help--- Enable support for the National Instruments PCMCIA DAQCard-1200 @@ -1258,6 +1267,11 @@ config COMEDI_DAS08 tristate select COMEDI_8255 +config COMEDI_NI_LABPC + tristate + select COMEDI_8255 + select COMEDI_FC + config COMEDI_NI_TIO tristate diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 6cdef45..7786bac 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_COMEDI_NI_AT_A2150) += ni_at_a2150.o obj-$(CONFIG_COMEDI_NI_AT_AO) += ni_at_ao.o obj-$(CONFIG_COMEDI_NI_ATMIO) += ni_atmio.o obj-$(CONFIG_COMEDI_NI_ATMIO16D) += ni_atmio16d.o +obj-$(CONFIG_COMEDI_NI_LABPC_ISA) += ni_labpc_isa.o obj-$(CONFIG_COMEDI_PCMAD) += pcmad.o obj-$(CONFIG_COMEDI_PCMDA12) += pcmda12.o obj-$(CONFIG_COMEDI_PCMMIO) += pcmmio.o @@ -104,6 +105,7 @@ obj-$(CONFIG_COMEDI_NI_6527) += ni_6527.o obj-$(CONFIG_COMEDI_NI_65XX) += ni_65xx.o obj-$(CONFIG_COMEDI_NI_660X) += ni_660x.o obj-$(CONFIG_COMEDI_NI_670X) += ni_670x.o +obj-$(CONFIG_COMEDI_NI_LABPC_PCI) += ni_labpc_pci.o obj-$(CONFIG_COMEDI_NI_PCIDIO) += ni_pcidio.o obj-$(CONFIG_COMEDI_NI_PCIMIO) += ni_pcimio.o obj-$(CONFIG_COMEDI_RTD520) += rtd520.o diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 39ac88b..7ef36f7 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1,79 +1,54 @@ /* - comedi/drivers/ni_labpc.c - Driver for National Instruments Lab-PC series boards and compatibles - Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -************************************************************************ -*/ -/* -Driver: ni_labpc -Description: National Instruments Lab-PC (& compatibles) -Author: Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> -Devices: [National Instruments] Lab-PC-1200 (labpc-1200), - Lab-PC-1200AI (labpc-1200ai), Lab-PC+ (lab-pc+), PCI-1200 (ni_labpc) -Status: works - -Tested with lab-pc-1200. For the older Lab-PC+, not all input ranges -and analog references will work, the available ranges/arefs will -depend on how you have configured the jumpers on your board -(see your owner's manual). - -Kernel-level ISA plug-and-play support for the lab-pc-1200 -boards has not -yet been added to the driver, mainly due to the fact that -I don't know the device id numbers. If you have one -of these boards, -please file a bug report at http://comedi.org/ -so I can get the necessary information from you. - -The 1200 series boards have onboard calibration dacs for correcting -analog input/output offsets and gains. The proper settings for these -caldacs are stored on the board's eeprom. To read the caldac values -from the eeprom and store them into a file that can be then be used by -comedilib, use the comedi_calibrate program. - -Configuration options - ISA boards: - [0] - I/O port base address - [1] - IRQ (optional, required for timed or externally triggered conversions) - [2] - DMA channel (optional) - -Configuration options - PCI boards: - [0] - bus (optional) - [1] - slot (optional) - -The Lab-pc+ has quirky chanlist requirements -when scanning multiple channels. Multiple channel scan -sequence must start at highest channel, then decrement down to -channel 0. The rest of the cards can scan down like lab-pc+ or scan -up from channel zero. Chanlists consisting of all one channel -are also legal, and allow you to pace conversions in bursts. - -*/ + * comedi/drivers/ni_labpc.c + * Common module for National Instruments Lab-PC series boards and compatibles + * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* + * Driver: ni_labpc + * Description: Common module for National Instruments Lab-PC drivers + * Devices: various, see ni_labpc_isa, ni_labpc_cs, and ni_labpc_pci + * Author: Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * Status: works + * + * Tested with lab-pc-1200. For the older Lab-PC+, not all input ranges + * and analog references will work, the available ranges/arefs will + * depend on how you have configured the jumpers on your board (see your + * owner's manual). + * + * The 1200 series boards have onboard calibration dacs for correcting + * analog input/output offsets and gains. The proper settings for these + * caldacs are stored on the board's eeprom. To read the caldac values + * from the eeprom and store them into a file that can be then be used by + * comedilib, use the comedi_calibrate program. + * + * The Lab-pc+ has quirky chanlist requirements when scanning multiple + * channels. Multiple channel scan sequence must start at highest channel, + * then decrement down to channel 0. The rest of the cards can scan down + * like lab-pc+ or scan up from channel zero. Chanlists consisting of all + * one channel are also legal, and allow you to pace conversions in bursts. + * + * NI manuals: + * 341309a (labpc-1200 register manual) + * 340914a (pci-1200) + * 320502b (lab-pc+) + * 340988a (daqcard-1200) + */ -NI manuals: -341309a (labpc-1200 register manual) -340914a (pci-1200) -320502b (lab-pc+) - -*/ - -#include <linux/pci.h> #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/io.h> @@ -85,14 +60,9 @@ NI manuals: #include "8253.h" #include "8255.h" -#include "mite.h" #include "comedi_fc.h" #include "ni_labpc.h" -#define DRV_NAME "ni_labpc" - -/* size of io region used by board */ -#define LABPC_SIZE 32 /* 2 MHz master clock */ #define LABPC_TIMER_BASE 500 @@ -215,37 +185,6 @@ enum scan_mode { MODE_MULT_CHAN_DOWN, }; -static const int labpc_plus_is_unipolar[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const int labpc_plus_ai_gain_bits[] = { - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, -}; - -static const struct comedi_lrange range_labpc_plus_ai = { - 16, { - BIP_RANGE(5), - BIP_RANGE(4), - BIP_RANGE(2.5), - BIP_RANGE(1), - BIP_RANGE(0.5), - BIP_RANGE(0.25), - BIP_RANGE(0.1), - BIP_RANGE(0.05), - UNI_RANGE(10), - UNI_RANGE(8), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1), - UNI_RANGE(0.5), - UNI_RANGE(0.2), - UNI_RANGE(0.1) - } -}; - const int labpc_1200_is_unipolar[] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, @@ -308,55 +247,6 @@ static inline void labpc_writeb(unsigned int byte, unsigned long address) writeb(byte, (void __iomem *)address); } -static const struct labpc_boardinfo labpc_boards[] = { - { - .name = "lab-pc-1200", - .ai_speed = 10000, - .bustype = isa_bustype, - .register_layout = labpc_1200_layout, - .has_ao = 1, - .ai_range_table = &range_labpc_1200_ai, - .ai_range_code = labpc_1200_ai_gain_bits, - .ai_range_is_unipolar = labpc_1200_is_unipolar, - .ai_scan_up = 1, - }, { - .name = "lab-pc-1200ai", - .ai_speed = 10000, - .bustype = isa_bustype, - .register_layout = labpc_1200_layout, - .ai_range_table = &range_labpc_1200_ai, - .ai_range_code = labpc_1200_ai_gain_bits, - .ai_range_is_unipolar = labpc_1200_is_unipolar, - .ai_scan_up = 1, - }, { - .name = "lab-pc+", - .ai_speed = 12000, - .bustype = isa_bustype, - .register_layout = labpc_plus_layout, - .has_ao = 1, - .ai_range_table = &range_labpc_plus_ai, - .ai_range_code = labpc_plus_ai_gain_bits, - .ai_range_is_unipolar = labpc_plus_is_unipolar, - }, -#ifdef CONFIG_COMEDI_PCI_DRIVERS - { - .name = "pci-1200", - .device_id = 0x161, - .ai_speed = 10000, - .bustype = pci_bustype, - .register_layout = labpc_1200_layout, - .has_ao = 1, - .ai_range_table = &range_labpc_1200_ai, - .ai_range_code = labpc_1200_ai_gain_bits, - .ai_range_is_unipolar = labpc_1200_is_unipolar, - .ai_scan_up = 1, - .memory_mapped_io = 1, - }, -#endif -}; - -/* size in bytes of dma buffer */ -static const int dma_buffer_size = 0xff00; /* 2 bytes per sample */ static const int sample_size = 2; @@ -476,8 +366,8 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd) size = (freq / 3) * sample_size; /* set a minimum and maximum size allowed */ - if (size > dma_buffer_size) - size = dma_buffer_size - dma_buffer_size % sample_size; + if (size > LABPC_DMA_BUF_SZ) + size = LABPC_DMA_BUF_SZ - LABPC_DMA_BUF_SZ % sample_size; else if (size < sample_size) size = sample_size; @@ -1669,35 +1559,16 @@ static int labpc_eeprom_read_insn(struct comedi_device *dev, return 1; } -int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, - unsigned int irq, unsigned int dma_chan) +int labpc_common_attach(struct comedi_device *dev, + unsigned int irq, unsigned long irq_flags) { const struct labpc_boardinfo *thisboard = comedi_board(dev); struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s; int i; - unsigned long isr_flags; -#ifdef CONFIG_ISA_DMA_API - unsigned long dma_flags; -#endif short lsb, msb; int ret; - dev_info(dev->class_dev, "ni_labpc: %s\n", thisboard->name); - if (iobase == 0) { - dev_err(dev->class_dev, "io base address is zero!\n"); - return -EINVAL; - } - /* request io regions for isa boards */ - if (thisboard->bustype == isa_bustype) { - /* check if io addresses are available */ - if (!request_region(iobase, LABPC_SIZE, DRV_NAME)) { - dev_err(dev->class_dev, "I/O port conflict\n"); - return -EIO; - } - } - dev->iobase = iobase; - if (thisboard->memory_mapped_io) { devpriv->read_byte = labpc_readb; devpriv->write_byte = labpc_writeb; @@ -1717,48 +1588,13 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, dev->iobase + COMMAND6_REG); } - /* grab our IRQ */ if (irq) { - isr_flags = 0; - if (thisboard->bustype == pci_bustype - || thisboard->bustype == pcmcia_bustype) - isr_flags |= IRQF_SHARED; - if (request_irq(irq, labpc_interrupt, isr_flags, - DRV_NAME, dev)) { - dev_err(dev->class_dev, "unable to allocate irq %u\n", - irq); - return -EINVAL; - } - } - dev->irq = irq; - -#ifdef CONFIG_ISA_DMA_API - /* grab dma channel */ - if (dma_chan > 3) { - dev_err(dev->class_dev, "invalid dma channel %u\n", dma_chan); - return -EINVAL; - } else if (dma_chan) { - /* allocate dma buffer */ - devpriv->dma_buffer = kmalloc(dma_buffer_size, - GFP_KERNEL | GFP_DMA); - if (devpriv->dma_buffer == NULL) - return -ENOMEM; - - if (request_dma(dma_chan, DRV_NAME)) { - dev_err(dev->class_dev, - "failed to allocate dma channel %u\n", - dma_chan); - return -EINVAL; - } - devpriv->dma_chan = dma_chan; - dma_flags = claim_dma_lock(); - disable_dma(devpriv->dma_chan); - set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); - release_dma_lock(dma_flags); + ret = request_irq(irq, labpc_interrupt, irq_flags, + dev->board_name, dev); + if (ret) + return ret; + dev->irq = irq; } -#endif - - dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, 5); if (ret) @@ -1850,172 +1686,25 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, } EXPORT_SYMBOL_GPL(labpc_common_attach); -static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - const struct labpc_boardinfo *thisboard = comedi_board(dev); - struct labpc_private *devpriv; - unsigned long iobase = 0; - unsigned int irq = 0; - unsigned int dma_chan = 0; - - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - /* get base address, irq etc. based on bustype */ - switch (thisboard->bustype) { - case isa_bustype: -#ifdef CONFIG_ISA_DMA_API - iobase = it->options[0]; - irq = it->options[1]; - dma_chan = it->options[2]; -#else - dev_err(dev->class_dev, - "ni_labpc driver has not been built with ISA DMA support.\n"); - return -EINVAL; -#endif - break; - case pci_bustype: -#ifdef CONFIG_COMEDI_PCI_DRIVERS - dev_err(dev->class_dev, - "manual configuration of PCI board '%s' is not supported\n", - thisboard->name); - return -EINVAL; -#else - dev_err(dev->class_dev, - "ni_labpc driver has not been built with PCI support.\n"); - return -EINVAL; -#endif - break; - default: - dev_err(dev->class_dev, - "ni_labpc: bug! couldn't determine board type\n"); - return -EINVAL; - break; - } - - return labpc_common_attach(dev, iobase, irq, dma_chan); -} - -static const struct labpc_boardinfo * -labpc_pci_find_boardinfo(struct pci_dev *pcidev) -{ - unsigned int device_id = pcidev->device; - unsigned int n; - - for (n = 0; n < ARRAY_SIZE(labpc_boards); n++) { - const struct labpc_boardinfo *board = &labpc_boards[n]; - if (board->bustype == pci_bustype && - board->device_id == device_id) - return board; - } - return NULL; -} - -static int labpc_auto_attach(struct comedi_device *dev, - unsigned long context_unused) -{ - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct labpc_private *devpriv; - unsigned long iobase; - unsigned int irq; - int ret; - - if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) - return -ENODEV; - - ret = comedi_pci_enable(dev); - if (ret) - return ret; - - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - dev->board_ptr = labpc_pci_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - devpriv->mite = mite_alloc(pcidev); - if (!devpriv->mite) - return -ENOMEM; - ret = mite_setup(devpriv->mite); - if (ret < 0) - return ret; - iobase = (unsigned long)devpriv->mite->daq_io_addr; - irq = mite_irq(devpriv->mite); - return labpc_common_attach(dev, iobase, irq, 0); -} - void labpc_common_detach(struct comedi_device *dev) { - const struct labpc_boardinfo *thisboard = comedi_board(dev); - struct labpc_private *devpriv = dev->private; - struct comedi_subdevice *s; - - if (!thisboard) - return; - if (dev->subdevices) { - s = &dev->subdevices[2]; - subdev_8255_cleanup(dev, s); - } -#ifdef CONFIG_ISA_DMA_API - /* only free stuff if it has been allocated by _attach */ - kfree(devpriv->dma_buffer); - if (devpriv->dma_chan) - free_dma(devpriv->dma_chan); -#endif + if (dev->subdevices) + subdev_8255_cleanup(dev, &dev->subdevices[2]); if (dev->irq) free_irq(dev->irq, dev); - if (thisboard->bustype == isa_bustype && dev->iobase) - release_region(dev->iobase, LABPC_SIZE); -#ifdef CONFIG_COMEDI_PCI_DRIVERS - if (devpriv->mite) { - mite_unsetup(devpriv->mite); - mite_free(devpriv->mite); - } - if (thisboard->bustype == pci_bustype) - comedi_pci_disable(dev); -#endif } EXPORT_SYMBOL_GPL(labpc_common_detach); -static struct comedi_driver labpc_driver = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = labpc_attach, - .auto_attach = labpc_auto_attach, - .detach = labpc_common_detach, - .num_names = ARRAY_SIZE(labpc_boards), - .board_name = &labpc_boards[0].name, - .offset = sizeof(struct labpc_boardinfo), -}; - -#ifdef CONFIG_COMEDI_PCI_DRIVERS -static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x161) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, labpc_pci_table); - -static int labpc_pci_probe(struct pci_dev *dev, - const struct pci_device_id *id) +static int __init labpc_init(void) { - return comedi_pci_auto_config(dev, &labpc_driver, id->driver_data); + return 0; } +module_init(labpc_init); -static struct pci_driver labpc_pci_driver = { - .name = DRV_NAME, - .id_table = labpc_pci_table, - .probe = labpc_pci_probe, - .remove = comedi_pci_auto_unconfig, -}; -module_comedi_pci_driver(labpc_driver, labpc_pci_driver); -#else -module_comedi_driver(labpc_driver); -#endif - +static void __exit labpc_exit(void) +{ +} +module_exit(labpc_exit); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index 6be3a11..1a78948 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -24,8 +24,9 @@ #ifndef _NI_LABPC_H #define _NI_LABPC_H -#define EEPROM_SIZE 256 /* 256 byte eeprom */ -#define NUM_AO_CHAN 2 /* boards have two analog output channels */ +#define LABPC_DMA_BUF_SZ 0xff00 /* size in bytes of dma buffer */ +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define NUM_AO_CHAN 2 /* two analog output channels */ enum labpc_bustype { isa_bustype, pci_bustype, pcmcia_bustype }; enum labpc_register_layout { labpc_plus_layout, labpc_1200_layout }; @@ -101,8 +102,8 @@ struct labpc_private { void (*write_byte) (unsigned int byte, unsigned long address); }; -int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, - unsigned int irq, unsigned int dma); +int labpc_common_attach(struct comedi_device *dev, + unsigned int irq, unsigned long irq_flags); void labpc_common_detach(struct comedi_device *dev); extern const int labpc_1200_is_unipolar[]; diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 5da87ee..40b771a 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -1,78 +1,59 @@ /* - comedi/drivers/ni_labpc_cs.c - Driver for National Instruments daqcard-1200 boards - Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> - - PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13 - from the pcmcia package. - The initial developer of the pcmcia dummy_cs.c code is David A. Hinds - <dahinds@xxxxxxxxxxxxxxxxxxxxx>. Portions created by David A. Hinds - are Copyright (C) 1999 David A. Hinds. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -************************************************************************ -*/ -/* -Driver: ni_labpc_cs -Description: National Instruments Lab-PC (& compatibles) -Author: Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> -Devices: [National Instruments] DAQCard-1200 (daqcard-1200) -Status: works - -Thanks go to Fredrik Lingvall for much testing and perseverance in -helping to debug daqcard-1200 support. - -The 1200 series boards have onboard calibration dacs for correcting -analog input/output offsets and gains. The proper settings for these -caldacs are stored on the board's eeprom. To read the caldac values -from the eeprom and store them into a file that can be then be used by -comedilib, use the comedi_calibrate program. - -Configuration options: - none - -The daqcard-1200 has quirky chanlist requirements -when scanning multiple channels. Multiple channel scan -sequence must start at highest channel, then decrement down to -channel 0. Chanlists consisting of all one channel -are also legal, and allow you to pace conversions in bursts. - -*/ + * comedi/drivers/ni_labpc_cs.c + * Driver for National Instruments daqcard-1200 boards + * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * + * PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13 + * from the pcmcia package. + * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds + * <dahinds@xxxxxxxxxxxxxxxxxxxxx>. Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* - -NI manuals: -340988a (daqcard-1200) - -*/ - -#include "../comedidev.h" - -#include <linux/delay.h> + * Driver: ni_labpc_cs + * Description: National Instruments Lab-PC (& compatibles) + * Devices: (National Instruments) DAQCard-1200 [daqcard-1200] + * Author: Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * Status: works + * + * Configuration Options: not applicable, uses PCMCIA auto config + * + * Thanks go to Fredrik Lingvall for much testing and perseverance in + * helping to debug daqcard-1200 support. + * + * The daqcard-1200 has quirky chanlist requirements when scanning + * multiple channels. Multiple channel scan sequence must start at + * highest channel, then decrement down to channel 0. Chanlists + * consisting of all one channel are also legal, and allow you to + * pace conversions in bursts. + */ + +#include <linux/interrupt.h> #include <linux/slab.h> -#include "8253.h" -#include "8255.h" -#include "comedi_fc.h" -#include "ni_labpc.h" - #include <pcmcia/cistpl.h> #include <pcmcia/cisreg.h> #include <pcmcia/ds.h> +#include "../comedidev.h" + +#include "ni_labpc.h" + static const struct labpc_boardinfo labpc_cs_boards[] = { { .name = "daqcard-1200", @@ -91,11 +72,13 @@ static int labpc_auto_attach(struct comedi_device *dev, unsigned long context) { struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); + const struct labpc_boardinfo *board = &labpc_cs_boards[0]; struct labpc_private *devpriv; int ret; /* The ni_labpc driver needs the board_ptr */ - dev->board_ptr = &labpc_cs_boards[0]; + dev->board_ptr = board; + dev->board_name = board->name; link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ; @@ -112,7 +95,7 @@ static int labpc_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - return labpc_common_attach(dev, dev->iobase, link->irq, 0); + return labpc_common_attach(dev, link->irq, IRQF_SHARED); } static void labpc_detach(struct comedi_device *dev) diff --git a/drivers/staging/comedi/drivers/ni_labpc_isa.c b/drivers/staging/comedi/drivers/ni_labpc_isa.c new file mode 100644 index 0000000..fc9dae6 --- /dev/null +++ b/drivers/staging/comedi/drivers/ni_labpc_isa.c @@ -0,0 +1,194 @@ +/* + * comedi/drivers/ni_labpc_isa.c + * Driver for National Instruments Lab-PC series boards and compatibles + * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Driver: ni_labpc_isa + * Description: National Instruments Lab-PC compatible boards + * Devices: (National Instruments) Lab-PC-1200 [lab-pc-1200] + * (National Instruments) Lab-PC-1200AI [lab-pc-1200ai] + * (National Instruments) Lab-PC+ [lab-pc+] + * Author: Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * Status: works + * + * Kernel-level ISA plug-and-play support for the lab-pc-1200 boards has + * not yet been added to the driver, mainly due to the fact that I don't + * know the device id numbers. If you have one of these boards, please + * file a bug report at http://comedi.org/ so I can get the necessary + * information from you. + * + * Configuration options - ISA boards: + * [0] - I/O port base address + * [1] - IRQ (optional, required for timed or externally triggered conversions) + * [2] - DMA channel (optional) + */ + +#include <linux/interrupt.h> +#include <linux/dma-mapping.h> + +#include "../comedidev.h" + +#include <asm/dma.h> + +#include "ni_labpc.h" + +#define LABPC_SIZE 32 /* size of io region used by board */ + +static const int labpc_plus_is_unipolar[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const int labpc_plus_ai_gain_bits[] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, +}; + +static const struct comedi_lrange range_labpc_plus_ai = { + 16, { + BIP_RANGE(5), + BIP_RANGE(4), + BIP_RANGE(2.5), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.25), + BIP_RANGE(0.1), + BIP_RANGE(0.05), + UNI_RANGE(10), + UNI_RANGE(8), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1), + UNI_RANGE(0.5), + UNI_RANGE(0.2), + UNI_RANGE(0.1) + } +}; + +static const struct labpc_boardinfo labpc_boards[] = { + { + .name = "lab-pc-1200", + .ai_speed = 10000, + .bustype = isa_bustype, + .register_layout = labpc_1200_layout, + .has_ao = 1, + .ai_range_table = &range_labpc_1200_ai, + .ai_range_code = labpc_1200_ai_gain_bits, + .ai_range_is_unipolar = labpc_1200_is_unipolar, + .ai_scan_up = 1, + }, { + .name = "lab-pc-1200ai", + .ai_speed = 10000, + .bustype = isa_bustype, + .register_layout = labpc_1200_layout, + .ai_range_table = &range_labpc_1200_ai, + .ai_range_code = labpc_1200_ai_gain_bits, + .ai_range_is_unipolar = labpc_1200_is_unipolar, + .ai_scan_up = 1, + }, { + .name = "lab-pc+", + .ai_speed = 12000, + .bustype = isa_bustype, + .register_layout = labpc_plus_layout, + .has_ao = 1, + .ai_range_table = &range_labpc_plus_ai, + .ai_range_code = labpc_plus_ai_gain_bits, + .ai_range_is_unipolar = labpc_plus_is_unipolar, + }, +}; + +static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct labpc_boardinfo *thisboard = comedi_board(dev); + struct labpc_private *devpriv; + unsigned long iobase = it->options[0]; + unsigned int irq = it->options[1]; + unsigned int dma_chan = it->options[2]; + unsigned long dma_flags; + int ret; + + dev->board_name = thisboard->name; + + if (!request_region(iobase, LABPC_SIZE, dev->board_name)) + return -EIO; + dev->iobase = iobase; + + if (dma_chan > 3) + return -EINVAL; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = labpc_common_attach(dev, irq, 0); + if (ret) + return ret; + + if (dma_chan) { + devpriv->dma_buffer = kmalloc(LABPC_DMA_BUF_SZ, + GFP_KERNEL | GFP_DMA); + if (!devpriv->dma_buffer) + return -ENOMEM; + + if (request_dma(dma_chan, dev->board_name)) { + dev_err(dev->class_dev, + "failed to allocate dma channel %u\n", + dma_chan); + return -EINVAL; + } + devpriv->dma_chan = dma_chan; + dma_flags = claim_dma_lock(); + disable_dma(devpriv->dma_chan); + set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); + release_dma_lock(dma_flags); + } + + return 0; +} + +static void labpc_detach(struct comedi_device *dev) +{ + struct labpc_private *devpriv = dev->private; + + labpc_common_detach(dev); + + if (devpriv) { + kfree(devpriv->dma_buffer); + if (devpriv->dma_chan) + free_dma(devpriv->dma_chan); + } + if (dev->iobase) + release_region(dev->iobase, LABPC_SIZE); +} + +static struct comedi_driver labpc_driver = { + .driver_name = "ni_labpc", + .module = THIS_MODULE, + .attach = labpc_attach, + .detach = labpc_detach, + .num_names = ARRAY_SIZE(labpc_boards), + .board_name = &labpc_boards[0].name, + .offset = sizeof(struct labpc_boardinfo), +}; +module_comedi_driver(labpc_driver); + +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c new file mode 100644 index 0000000..e1a62a5 --- /dev/null +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -0,0 +1,140 @@ +/* + * comedi/drivers/ni_labpc_pci.c + * Driver for National Instruments Lab-PC PCI-1200 + * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Driver: ni_labpc_pci + * Description: National Instruments Lab-PC PCI-1200 + * Devices: (National Instruments) PCI-1200 [ni_pci-1200] + * Author: Frank Mori Hess <fmhess@xxxxxxxxxxxxxxxxxxxxx> + * Status: works + * + * This is the PCI-specific support split off from the ni_labpc driver. + * + * Configuration Options: not applicable, uses PCI auto config + */ + +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/pci.h> + +#include "../comedidev.h" + +#include "mite.h" +#include "ni_labpc.h" + +enum labpc_pci_boardid { + BOARD_NI_PCI1200, +}; + +static const struct labpc_boardinfo labpc_pci_boards[] = { + [BOARD_NI_PCI1200] = { + .name = "ni_pci-1200", + .device_id = 0x161, + .ai_speed = 10000, + .bustype = pci_bustype, + .register_layout = labpc_1200_layout, + .has_ao = 1, + .ai_range_table = &range_labpc_1200_ai, + .ai_range_code = labpc_1200_ai_gain_bits, + .ai_range_is_unipolar = labpc_1200_is_unipolar, + .ai_scan_up = 1, + .memory_mapped_io = 1, + }, +}; + +static int labpc_pci_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct labpc_boardinfo *board = NULL; + struct labpc_private *devpriv; + int ret; + + if (context < ARRAY_SIZE(labpc_pci_boards)) + board = &labpc_pci_boards[context]; + if (!board) + return -ENODEV; + dev->board_ptr = board; + dev->board_name = board->name; + + ret = comedi_pci_enable(dev); + if (ret) + return ret; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) + return -ENOMEM; + ret = mite_setup(devpriv->mite); + if (ret < 0) + return ret; + dev->iobase = (unsigned long)devpriv->mite->daq_io_addr; + + return labpc_common_attach(dev, mite_irq(devpriv->mite), IRQF_SHARED); +} + +static void labpc_pci_detach(struct comedi_device *dev) +{ + struct labpc_private *devpriv = dev->private; + + labpc_common_detach(dev); + + if (devpriv && devpriv->mite) { + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } + comedi_pci_disable(dev); +} + +static struct comedi_driver labpc_pci_comedi_driver = { + .driver_name = "labpc_pci", + .module = THIS_MODULE, + .auto_attach = labpc_pci_auto_attach, + .detach = labpc_pci_detach, +}; + +static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { + { PCI_VDEVICE(NI, 0x161), BOARD_NI_PCI1200 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, labpc_pci_table); + +static int labpc_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + return comedi_pci_auto_config(dev, &labpc_pci_comedi_driver, + id->driver_data); +} + +static struct pci_driver labpc_pci_driver = { + .name = "labpc_pci", + .id_table = labpc_pci_table, + .probe = labpc_pci_probe, + .remove = comedi_pci_auto_unconfig, +}; +module_comedi_pci_driver(labpc_pci_comedi_driver, labpc_pci_driver); + +MODULE_DESCRIPTION("Comedi: National Instruments Lab-PC PCI-1200 driver"); +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_LICENSE("GPL"); -- 1.8.1.4 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel