From fa3cb2191091657038ddb9207888b6cfb11fdf6e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 22 Apr 2013 12:33:09 -0700 Subject: [PATCH] staging: comedi: ni_labpc: split out PCI support Currently the ni_labpc driver is used by the legacy (ISA), PCI, and PCMCIA versions of the LabPC board. The driver is enabled under the COMEDI_PCI_DRIVERS section of the Kconfig. This means that PCI support must be enabled in order to use the ni_labpc driver for the PCI or PCMCIA drivers. Split the PCI support code out of the ni_labpc driver into a separate driver, ni_labpc_pci. The PCMCIA support is already slip out as ni_labpc_cs. Modify the Kconfig so that the common code in ni_labpc is enabled by the Kconfig option COMEDI_NI_LABPC. The ISA support code is currently still in the ni_labpc driver but is only compiled in if COMEDI_NI_LABPC_ISA is also enabled. This allows the PCI and PCMCIA drivers to be enabled without the need for the ISA stuff. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 35 +++-- drivers/staging/comedi/drivers/Makefile | 1 + drivers/staging/comedi/drivers/ni_labpc.c | 185 +++++--------------------- drivers/staging/comedi/drivers/ni_labpc_pci.c | 143 ++++++++++++++++++++ 4 files changed, 199 insertions(+), 165 deletions(-) create mode 100644 drivers/staging/comedi/drivers/ni_labpc_pci.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 9600225..7871579 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -484,6 +484,19 @@ 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" + select COMEDI_NI_LABPC + depends on VIRT_TO_BUS + ---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. + config COMEDI_PCMAD tristate "Winsystems PCM-A/D12 and PCM-A/D16 PC/104 board support" ---help--- @@ -1007,20 +1020,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_NI_LABPC select COMEDI_MITE - select COMEDI_8255 - select COMEDI_FC - depends on VIRT_TO_BUS ---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 +1150,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 @@ -1255,6 +1263,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 bb5634e..57e984f 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -106,6 +106,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 96a6837..e8fc6a1 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -24,7 +24,6 @@ * Devices: (National Instruments) Lab-PC-1200 [lab-pc-1200] * (National Instruments) Lab-PC-1200AI [lab-pc-1200ai] * (National Instruments) Lab-PC+ [lab-pc+] - * (National Instruments) PCI-1200 [pci-1200] * Author: Frank Mori Hess * Status: works * @@ -34,9 +33,6 @@ * conversions) * [2] - DMA channel (optional) * - * Configuration options - PCI boards: - * not applicable, uses PCI auto config - * * 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 @@ -62,11 +58,9 @@ * * NI manuals: * 341309a (labpc-1200 register manual) - * 340914a (pci-1200) * 320502b (lab-pc+) */ -#include #include #include #include @@ -78,7 +72,6 @@ #include "8253.h" #include "8255.h" -#include "mite.h" #include "comedi_fc.h" #include "ni_labpc.h" @@ -241,6 +234,7 @@ static inline void labpc_writeb(unsigned int byte, unsigned long address) writeb(byte, (void __iomem *)address); } +#ifdef CONFIG_COMEDI_NI_LABPC_ISA static const struct labpc_boardinfo labpc_boards[] = { { .name = "lab-pc-1200", @@ -268,21 +262,8 @@ static const struct labpc_boardinfo labpc_boards[] = { .ai_range_table = &range_labpc_plus_ai, .ai_range_code = labpc_plus_ai_gain_bits, }, -#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_scan_up = 1, - .has_mmio = 1, - }, -#endif }; +#endif /* size in bytes of dma buffer */ static const int dma_buffer_size = 0xff00; @@ -1754,12 +1735,19 @@ int labpc_common_attach(struct comedi_device *dev, } EXPORT_SYMBOL_GPL(labpc_common_attach); +void labpc_common_detach(struct comedi_device *dev) +{ + comedi_spriv_free(dev, 2); +} +EXPORT_SYMBOL_GPL(labpc_common_detach); + +#ifdef CONFIG_COMEDI_NI_LABPC_ISA static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct labpc_boardinfo *board = comedi_board(dev); struct labpc_private *devpriv; - unsigned int irq = 0; - unsigned int dma_chan = 0; + unsigned int irq = it->options[1]; + unsigned int dma_chan = it->options[2]; int ret; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); @@ -1767,161 +1755,50 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; dev->private = devpriv; - /* get base address, irq etc. based on bustype */ - switch (board->bustype) { - case isa_bustype: -#ifdef CONFIG_ISA_DMA_API - irq = it->options[1]; - dma_chan = it->options[2]; - ret = comedi_request_region(dev, it->options[0], LABPC_SIZE); - if (ret) - return ret; -#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", - board->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, 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); - const struct labpc_boardinfo *board; - struct labpc_private *devpriv; - unsigned int irq; - int ret; - - if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) - return -ENODEV; - - ret = comedi_pci_enable(dev); + ret = comedi_request_region(dev, it->options[0], LABPC_SIZE); if (ret) return ret; - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - board = labpc_pci_find_boardinfo(pcidev); - if (!board) - return -ENODEV; - dev->board_ptr = board; - dev->board_name = board->name; - 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; - irq = mite_irq(devpriv->mite); - return labpc_common_attach(dev, irq, 0); + return labpc_common_attach(dev, irq, dma_chan); } -void labpc_common_detach(struct comedi_device *dev) +void labpc_detach(struct comedi_device *dev) { - const struct labpc_boardinfo *board = comedi_board(dev); struct labpc_private *devpriv = dev->private; - if (!board) - return; - comedi_spriv_free(dev, 2); -#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 (board->bustype == isa_bustype) - comedi_legacy_detach(dev); -#ifdef CONFIG_COMEDI_PCI_DRIVERS - if (devpriv->mite) { - mite_unsetup(devpriv->mite); - mite_free(devpriv->mite); - } - if (board->bustype == pci_bustype) { - if (dev->irq) - free_irq(dev->irq, dev); - comedi_pci_disable(dev); + labpc_common_detach(dev); + + if (devpriv) { + kfree(devpriv->dma_buffer); + if (devpriv->dma_chan) + free_dma(devpriv->dma_chan); } -#endif + comedi_legacy_detach(dev); } -EXPORT_SYMBOL_GPL(labpc_common_detach); static struct comedi_driver labpc_driver = { .driver_name = "ni_labpc", .module = THIS_MODULE, .attach = labpc_attach, - .auto_attach = labpc_auto_attach, - .detach = labpc_common_detach, + .detach = labpc_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) +module_comedi_driver(labpc_driver); +#else +static int __init labpc_common_init(void) { - return comedi_pci_auto_config(dev, &labpc_driver, id->driver_data); + return 0; } +module_init(labpc_common_init); -static struct pci_driver labpc_pci_driver = { - .name = "ni_labpc", - .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); +static void __exit labpc_common_exit(void) +{ +} +module_exit(labpc_common_exit); #endif - 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..82e381f --- /dev/null +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -0,0 +1,143 @@ +/* + * comedi/drivers/ni_labpc_pci.c + * Driver for National Instruments Lab-PC PCI-1200 + * Copyright (C) 2001, 2002, 2003 Frank Mori Hess + * + * 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 + * Status: works + * + * This is the PCI-specific support split off from the ni_labpc driver. + * + * Configuration Options: not applicable, uses PCI auto config + * + * NI manuals: + * 340914a (pci-1200) + */ + +#include +#include +#include + +#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", + .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_scan_up = 1, + .has_mmio = 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), 0); +} + +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); + } + if (dev->irq) + free_irq(dev->irq, dev); + 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"); -- 2.7.4