aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/comedi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi')
-rw-r--r--drivers/staging/comedi/Kconfig60
-rw-r--r--drivers/staging/comedi/comedi_buf.c18
-rw-r--r--drivers/staging/comedi/comedi_fops.c545
-rw-r--r--drivers/staging/comedi/comedi_internal.h5
-rw-r--r--drivers/staging/comedi/comedi_pci.c34
-rw-r--r--drivers/staging/comedi/comedidev.h31
-rw-r--r--drivers/staging/comedi/drivers.c182
-rw-r--r--drivers/staging/comedi/drivers/8255.c23
-rw-r--r--drivers/staging/comedi/drivers/8255.h1
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c210
-rw-r--r--drivers/staging/comedi/drivers/Makefile9
-rw-r--r--drivers/staging/comedi/drivers/acl7225b.c141
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c34
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h5
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c20
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c15
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c23
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c66
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c20
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c69
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1710.c64
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c18
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c18
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c52
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c55
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c15
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c300
-rw-r--r--drivers/staging/comedi/drivers/addi_watchdog.c6
-rw-r--r--drivers/staging/comedi/drivers/addi_watchdog.h1
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c63
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7x3x.c95
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c346
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c64
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c19
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c48
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c142
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c20
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1724.c409
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c178
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c22
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c26
-rw-r--r--drivers/staging/comedi/drivers/am9513.h79
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c1980
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.h95
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_common.c1271
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_pci.c486
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c91
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c303
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c21
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c26
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci263.c127
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c39
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c98
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c970
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c96
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c16
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c19
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.c6
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c29
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c2
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c21
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c40
-rw-r--r--drivers/staging/comedi/drivers/das08.c3
-rw-r--r--drivers/staging/comedi/drivers/das08.h1
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c1
-rw-r--r--drivers/staging/comedi/drivers/das08_isa.c14
-rw-r--r--drivers/staging/comedi/drivers/das08_pci.c13
-rw-r--r--drivers/staging/comedi/drivers/das16.c67
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c46
-rw-r--r--drivers/staging/comedi/drivers/das1800.c92
-rw-r--r--drivers/staging/comedi/drivers/das6402.c27
-rw-r--r--drivers/staging/comedi/drivers/das800.c999
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c28
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c36
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c29
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c22
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c29
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c22
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c59
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c103
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c46
-rw-r--r--drivers/staging/comedi/drivers/dyna_pci10xx.c15
-rw-r--r--drivers/staging/comedi/drivers/fl512.c31
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c30
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c23
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c4
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c18
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c21
-rw-r--r--drivers/staging/comedi/drivers/me4000.c213
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c84
-rw-r--r--drivers/staging/comedi/drivers/mite.c76
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c39
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c45
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c82
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c394
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c144
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c64
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c47
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c24
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c29
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c30
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c5
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c2448
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h30
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c6
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_pci.c142
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c355
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c68
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c2056
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h4
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c30
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c37
-rw-r--r--drivers/staging/comedi/drivers/pcl725.c21
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c36
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c26
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c65
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c180
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c481
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c31
-rw-r--r--drivers/staging/comedi/drivers/pcm3730.c22
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c26
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c26
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c26
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c26
-rw-r--r--drivers/staging/comedi/drivers/plx9052.h106
-rw-r--r--drivers/staging/comedi/drivers/poc.c34
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c716
-rw-r--r--drivers/staging/comedi/drivers/rtd520.h381
-rw-r--r--drivers/staging/comedi/drivers/rti800.c575
-rw-r--r--drivers/staging/comedi/drivers/rti802.c21
-rw-r--r--drivers/staging/comedi/drivers/s526.c22
-rw-r--r--drivers/staging/comedi/drivers/s626.c1211
-rw-r--r--drivers/staging/comedi/drivers/s626.h101
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c895
-rw-r--r--drivers/staging/comedi/drivers/skel.c136
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c2
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c64
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c439
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c32
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c39
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c12
-rw-r--r--drivers/staging/comedi/range.c22
145 files changed, 10330 insertions, 12970 deletions
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 1967852eeb1..7871579bb83 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -230,9 +230,9 @@ config COMEDI_AMPLC_PC236_ISA
config COMEDI_AMPLC_PC263_ISA
tristate "Amplicon PC263 relay board support"
- select COMEDI_AMPLC_PC263
---help---
- Enable support for Amplicon PC263 ISA relay board.
+ Enable support for Amplicon PC263 ISA relay board. This board has
+ 16 reed relay output channels.
To compile this driver as a module, choose M here: the module will be
called amplc_pc263.
@@ -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---
@@ -728,6 +741,16 @@ config COMEDI_ADV_PCI1723
To compile this driver as a module, choose M here: the module will be
called adv_pci1723.
+config COMEDI_ADV_PCI1724
+ tristate "Advantech PCI-1724U support"
+ ---help---
+ Enable support for Advantech PCI-1724U cards. These are 32-channel
+ analog output cards with voltage and current loop output ranges and
+ 14-bit resolution.
+
+ To compile this driver as a module, choose M here: the module will be
+ called adv_pci1724.
+
config COMEDI_ADV_PCI_DIO
tristate "Advantech PCI DIO card support"
select COMEDI_8255
@@ -748,7 +771,7 @@ config COMEDI_AMPLC_DIO200_PCI
and PCIe296 DIO boards.
To compile this driver as a module, choose M here: the module will be
- called amplc_dio200.
+ called amplc_dio200_pci.
config COMEDI_AMPLC_PC236_PCI
tristate "Amplicon PCI236 DIO board support"
@@ -761,12 +784,12 @@ config COMEDI_AMPLC_PC236_PCI
config COMEDI_AMPLC_PC263_PCI
tristate "Amplicon PCI263 relay board support"
- select COMEDI_AMPLC_PC263
---help---
- Enable support for Amplicon PCI263 relay board.
+ Enable support for Amplicon PCI263 relay board. This is a PCI board
+ with 16 reed relay output channels.
To compile this driver as a module, choose M here: the module will be
- called amplc_pc263.
+ called amplc_pci263.
config COMEDI_AMPLC_PCI224
tristate "Amplicon PCI224 and PCI234 support"
@@ -983,7 +1006,7 @@ config COMEDI_NI_660X
select COMEDI_NI_TIOCMD
---help---
Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602,
- PXI-6602 and PXI-6608.
+ PXI-6602, PXI-6608 and PXI-6624.
To compile this driver as a module, choose M here: the module will be
called ni_660x.
@@ -997,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"
@@ -1132,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
@@ -1241,12 +1259,14 @@ config COMEDI_AMPLC_PC236
tristate
select COMEDI_8255
-config COMEDI_AMPLC_PC263
+config COMEDI_DAS08
tristate
+ select COMEDI_8255
-config COMEDI_DAS08
+config COMEDI_NI_LABPC
tristate
select COMEDI_8255
+ select COMEDI_FC
config COMEDI_NI_TIO
tristate
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c
index 9b997ae6779..ca709901fb3 100644
--- a/drivers/staging/comedi/comedi_buf.c
+++ b/drivers/staging/comedi/comedi_buf.c
@@ -192,7 +192,7 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async,
{
return __comedi_buf_write_alloc(async, nbytes, 0);
}
-EXPORT_SYMBOL(comedi_buf_write_alloc);
+EXPORT_SYMBOL_GPL(comedi_buf_write_alloc);
/*
* munging is applied to data by core as it passes between user
@@ -263,7 +263,7 @@ unsigned int comedi_buf_write_free(struct comedi_async *async,
return nbytes;
}
-EXPORT_SYMBOL(comedi_buf_write_free);
+EXPORT_SYMBOL_GPL(comedi_buf_write_free);
unsigned int comedi_buf_read_n_available(struct comedi_async *async)
{
@@ -282,7 +282,7 @@ unsigned int comedi_buf_read_n_available(struct comedi_async *async)
return num_bytes;
}
-EXPORT_SYMBOL(comedi_buf_read_n_available);
+EXPORT_SYMBOL_GPL(comedi_buf_read_n_available);
/* allocates a chunk for the reader from filled (and munged) buffer space */
unsigned int comedi_buf_read_alloc(struct comedi_async *async,
@@ -304,7 +304,7 @@ unsigned int comedi_buf_read_alloc(struct comedi_async *async,
return nbytes;
}
-EXPORT_SYMBOL(comedi_buf_read_alloc);
+EXPORT_SYMBOL_GPL(comedi_buf_read_alloc);
static unsigned int comedi_buf_read_n_allocated(struct comedi_async *async)
{
@@ -332,7 +332,7 @@ unsigned int comedi_buf_read_free(struct comedi_async *async,
async->buf_read_ptr %= async->prealloc_bufsz;
return nbytes;
}
-EXPORT_SYMBOL(comedi_buf_read_free);
+EXPORT_SYMBOL_GPL(comedi_buf_read_free);
int comedi_buf_put(struct comedi_async *async, short x)
{
@@ -346,7 +346,7 @@ int comedi_buf_put(struct comedi_async *async, short x)
comedi_buf_write_free(async, sizeof(short));
return 1;
}
-EXPORT_SYMBOL(comedi_buf_put);
+EXPORT_SYMBOL_GPL(comedi_buf_put);
int comedi_buf_get(struct comedi_async *async, short *x)
{
@@ -359,7 +359,7 @@ int comedi_buf_get(struct comedi_async *async, short *x)
comedi_buf_read_free(async, sizeof(short));
return 1;
}
-EXPORT_SYMBOL(comedi_buf_get);
+EXPORT_SYMBOL_GPL(comedi_buf_get);
void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
const void *data, unsigned int num_bytes)
@@ -385,7 +385,7 @@ void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
write_ptr = 0;
}
}
-EXPORT_SYMBOL(comedi_buf_memcpy_to);
+EXPORT_SYMBOL_GPL(comedi_buf_memcpy_to);
void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
void *dest, unsigned int nbytes)
@@ -412,4 +412,4 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
read_ptr = 0;
}
}
-EXPORT_SYMBOL(comedi_buf_memcpy_from);
+EXPORT_SYMBOL_GPL(comedi_buf_memcpy_from);
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index e336b281b84..00f2547024e 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -49,9 +49,13 @@
#include "comedi_internal.h"
+#define COMEDI_NUM_MINORS 0x100
+#define COMEDI_NUM_SUBDEVICE_MINORS \
+ (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS)
+
#ifdef CONFIG_COMEDI_DEBUG
int comedi_debug;
-EXPORT_SYMBOL(comedi_debug);
+EXPORT_SYMBOL_GPL(comedi_debug);
module_param(comedi_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(comedi_debug,
"enable comedi core and driver debugging if non-zero (default 0)"
@@ -77,57 +81,151 @@ MODULE_PARM_DESC(comedi_default_buf_maxsize_kb,
"default maximum size of asynchronous buffer in KiB (default "
__MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB) ")");
-struct comedi_file_info {
- struct comedi_device *device;
- struct comedi_subdevice *read_subdevice;
- struct comedi_subdevice *write_subdevice;
- struct device *hardware_device;
-};
+static DEFINE_MUTEX(comedi_board_minor_table_lock);
+static struct comedi_device
+*comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS];
+
+static DEFINE_MUTEX(comedi_subdevice_minor_table_lock);
+/* Note: indexed by minor - COMEDI_NUM_BOARD_MINORS. */
+static struct comedi_subdevice
+*comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS];
+
+static struct class *comedi_class;
+static struct cdev comedi_cdev;
+
+static void comedi_device_init(struct comedi_device *dev)
+{
+ spin_lock_init(&dev->spinlock);
+ mutex_init(&dev->mutex);
+ dev->minor = -1;
+}
+
+static void comedi_device_cleanup(struct comedi_device *dev)
+{
+ struct module *driver_module = NULL;
+
+ if (dev == NULL)
+ return;
+ mutex_lock(&dev->mutex);
+ if (dev->attached)
+ driver_module = dev->driver->module;
+ comedi_device_detach(dev);
+ while (dev->use_count > 0) {
+ if (driver_module)
+ module_put(driver_module);
+ module_put(THIS_MODULE);
+ dev->use_count--;
+ }
+ mutex_unlock(&dev->mutex);
+ mutex_destroy(&dev->mutex);
+}
+
+static bool comedi_clear_board_dev(struct comedi_device *dev)
+{
+ unsigned int i = dev->minor;
+ bool cleared = false;
+
+ mutex_lock(&comedi_board_minor_table_lock);
+ if (dev == comedi_board_minor_table[i]) {
+ comedi_board_minor_table[i] = NULL;
+ cleared = true;
+ }
+ mutex_unlock(&comedi_board_minor_table_lock);
+ return cleared;
+}
+
+static struct comedi_device *comedi_clear_board_minor(unsigned minor)
+{
+ struct comedi_device *dev;
+
+ mutex_lock(&comedi_board_minor_table_lock);
+ dev = comedi_board_minor_table[minor];
+ comedi_board_minor_table[minor] = NULL;
+ mutex_unlock(&comedi_board_minor_table_lock);
+ return dev;
+}
+
+static void comedi_free_board_dev(struct comedi_device *dev)
+{
+ if (dev) {
+ if (dev->class_dev) {
+ device_destroy(comedi_class,
+ MKDEV(COMEDI_MAJOR, dev->minor));
+ }
+ comedi_device_cleanup(dev);
+ kfree(dev);
+ }
+}
-static DEFINE_SPINLOCK(comedi_file_info_table_lock);
-static struct comedi_file_info *comedi_file_info_table[COMEDI_NUM_MINORS];
+static struct comedi_subdevice
+*comedi_subdevice_from_minor(unsigned minor)
+{
+ struct comedi_subdevice *s;
+ unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
+
+ BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
+ mutex_lock(&comedi_subdevice_minor_table_lock);
+ s = comedi_subdevice_minor_table[i];
+ mutex_unlock(&comedi_subdevice_minor_table_lock);
+ return s;
+}
-static struct comedi_file_info *comedi_file_info_from_minor(unsigned minor)
+static struct comedi_device *comedi_dev_from_board_minor(unsigned minor)
{
- struct comedi_file_info *info;
+ struct comedi_device *dev;
- BUG_ON(minor >= COMEDI_NUM_MINORS);
- spin_lock(&comedi_file_info_table_lock);
- info = comedi_file_info_table[minor];
- spin_unlock(&comedi_file_info_table_lock);
- return info;
+ BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
+ mutex_lock(&comedi_board_minor_table_lock);
+ dev = comedi_board_minor_table[minor];
+ mutex_unlock(&comedi_board_minor_table_lock);
+ return dev;
}
-static struct comedi_device *
-comedi_dev_from_file_info(struct comedi_file_info *info)
+static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor)
{
- return info ? info->device : NULL;
+ struct comedi_subdevice *s;
+
+ s = comedi_subdevice_from_minor(minor);
+ return s ? s->device : NULL;
}
struct comedi_device *comedi_dev_from_minor(unsigned minor)
{
- return comedi_dev_from_file_info(comedi_file_info_from_minor(minor));
+ if (minor < COMEDI_NUM_BOARD_MINORS)
+ return comedi_dev_from_board_minor(minor);
+ else
+ return comedi_dev_from_subdevice_minor(minor);
}
EXPORT_SYMBOL_GPL(comedi_dev_from_minor);
static struct comedi_subdevice *
-comedi_read_subdevice(const struct comedi_file_info *info)
+comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
{
- if (info->read_subdevice)
- return info->read_subdevice;
- if (info->device)
- return info->device->read_subdev;
- return NULL;
+ struct comedi_subdevice *s;
+
+ if (minor >= COMEDI_NUM_BOARD_MINORS) {
+ s = comedi_subdevice_from_minor(minor);
+ if (!s || s->device != dev)
+ return NULL;
+ if (s->subdev_flags & SDF_CMD_READ)
+ return s;
+ }
+ return dev->read_subdev;
}
static struct comedi_subdevice *
-comedi_write_subdevice(const struct comedi_file_info *info)
+comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
{
- if (info->write_subdevice)
- return info->write_subdevice;
- if (info->device)
- return info->device->write_subdev;
- return NULL;
+ struct comedi_subdevice *s;
+
+ if (minor >= COMEDI_NUM_BOARD_MINORS) {
+ s = comedi_subdevice_from_minor(minor);
+ if (!s || s->device != dev)
+ return NULL;
+ if (s->subdev_flags & SDF_CMD_WRITE)
+ return s;
+ }
+ return dev->write_subdev;
}
static int resize_async_buffer(struct comedi_device *dev,
@@ -172,27 +270,34 @@ static int resize_async_buffer(struct comedi_device *dev,
/* sysfs attribute files */
-static ssize_t show_max_read_buffer_kb(struct device *dev,
+static ssize_t show_max_read_buffer_kb(struct device *csdev,
struct device_attribute *attr, char *buf)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_read_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size = 0;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_read_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
size = s->async->max_bufsize / 1024;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_max_read_buffer_kb(struct device *dev,
+static ssize_t store_max_read_buffer_kb(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_read_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size;
int err;
@@ -203,37 +308,49 @@ static ssize_t store_max_read_buffer_kb(struct device *dev,
return -EINVAL;
size *= 1024;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_read_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
s->async->max_bufsize = size;
else
err = -EINVAL;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return err ? err : count;
}
-static ssize_t show_read_buffer_kb(struct device *dev,
+static ssize_t show_read_buffer_kb(struct device *csdev,
struct device_attribute *attr, char *buf)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_read_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size = 0;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_read_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
size = s->async->prealloc_bufsz / 1024;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_read_buffer_kb(struct device *dev,
+static ssize_t store_read_buffer_kb(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_read_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size;
int err;
@@ -244,38 +361,50 @@ static ssize_t store_read_buffer_kb(struct device *dev,
return -EINVAL;
size *= 1024;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_read_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
- err = resize_async_buffer(info->device, s, s->async, size);
+ err = resize_async_buffer(dev, s, s->async, size);
else
err = -EINVAL;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return err ? err : count;
}
-static ssize_t show_max_write_buffer_kb(struct device *dev,
+static ssize_t show_max_write_buffer_kb(struct device *csdev,
struct device_attribute *attr,
char *buf)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_write_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size = 0;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_write_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
size = s->async->max_bufsize / 1024;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_max_write_buffer_kb(struct device *dev,
+static ssize_t store_max_write_buffer_kb(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_write_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size;
int err;
@@ -286,37 +415,49 @@ static ssize_t store_max_write_buffer_kb(struct device *dev,
return -EINVAL;
size *= 1024;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_write_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
s->async->max_bufsize = size;
else
err = -EINVAL;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return err ? err : count;
}
-static ssize_t show_write_buffer_kb(struct device *dev,
+static ssize_t show_write_buffer_kb(struct device *csdev,
struct device_attribute *attr, char *buf)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_write_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size = 0;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_write_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
size = s->async->prealloc_bufsz / 1024;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return snprintf(buf, PAGE_SIZE, "%i\n", size);
}
-static ssize_t store_write_buffer_kb(struct device *dev,
+static ssize_t store_write_buffer_kb(struct device *csdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct comedi_file_info *info = dev_get_drvdata(dev);
- struct comedi_subdevice *s = comedi_write_subdevice(info);
+ unsigned int minor = MINOR(csdev->devt);
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
unsigned int size;
int err;
@@ -327,12 +468,17 @@ static ssize_t store_write_buffer_kb(struct device *dev,
return -EINVAL;
size *= 1024;
- mutex_lock(&info->device->mutex);
+ dev = comedi_dev_from_minor(minor);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ s = comedi_write_subdevice(dev, minor);
if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
- err = resize_async_buffer(info->device, s, s->async, size);
+ err = resize_async_buffer(dev, s, s->async, size);
else
err = -EINVAL;
- mutex_unlock(&info->device->mutex);
+ mutex_unlock(&dev->mutex);
return err ? err : count;
}
@@ -463,7 +609,6 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
struct comedi_devconfig __user *arg)
{
struct comedi_devconfig it;
- int ret;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -490,15 +635,12 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
return -EINVAL;
}
- ret = comedi_device_attach(dev, &it);
- if (ret == 0) {
- if (!try_module_get(dev->driver->module)) {
- comedi_device_detach(dev);
- ret = -ENOSYS;
- }
- }
+ if (dev->minor >= comedi_num_legacy_minors)
+ /* don't re-use dynamically allocated comedi devices */
+ return -EBUSY;
- return ret;
+ /* This increments the driver module count on success. */
+ return comedi_device_attach(dev, &it);
}
/*
@@ -581,7 +723,6 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
struct file *file)
{
const unsigned minor = iminor(file_inode(file));
- struct comedi_file_info *info = comedi_file_info_from_minor(minor);
struct comedi_subdevice *s;
struct comedi_devinfo devinfo;
@@ -593,13 +734,13 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
- s = comedi_read_subdevice(info);
+ s = comedi_read_subdevice(dev, minor);
if (s)
devinfo.read_subdevice = s->index;
else
devinfo.read_subdevice = -1;
- s = comedi_write_subdevice(info);
+ s = comedi_write_subdevice(dev, minor);
if (s)
devinfo.write_subdevice = s->index;
else
@@ -1616,8 +1757,7 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
const unsigned minor = iminor(file_inode(file));
- struct comedi_file_info *info = comedi_file_info_from_minor(minor);
- struct comedi_device *dev = comedi_dev_from_file_info(info);
+ struct comedi_device *dev = comedi_dev_from_minor(minor);
int rc;
if (!dev)
@@ -1635,9 +1775,18 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
}
rc = do_devconfig_ioctl(dev,
(struct comedi_devconfig __user *)arg);
- if (rc == 0)
- /* Evade comedi_auto_unconfig(). */
- info->hardware_device = NULL;
+ if (rc == 0) {
+ if (arg == 0 &&
+ dev->minor >= comedi_num_legacy_minors) {
+ /* Successfully unconfigured a dynamically
+ * allocated device. Try and remove it. */
+ if (comedi_clear_board_dev(dev)) {
+ mutex_unlock(&dev->mutex);
+ comedi_free_board_dev(dev);
+ return rc;
+ }
+ }
+ }
goto done;
}
@@ -1744,8 +1893,7 @@ static struct vm_operations_struct comedi_vm_ops = {
static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
{
const unsigned minor = iminor(file_inode(file));
- struct comedi_file_info *info = comedi_file_info_from_minor(minor);
- struct comedi_device *dev = comedi_dev_from_file_info(info);
+ struct comedi_device *dev = comedi_dev_from_minor(minor);
struct comedi_subdevice *s;
struct comedi_async *async;
unsigned long start = vma->vm_start;
@@ -1766,9 +1914,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
}
if (vma->vm_flags & VM_WRITE)
- s = comedi_write_subdevice(info);
+ s = comedi_write_subdevice(dev, minor);
else
- s = comedi_read_subdevice(info);
+ s = comedi_read_subdevice(dev, minor);
if (!s) {
retval = -EINVAL;
goto done;
@@ -1824,8 +1972,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
{
unsigned int mask = 0;
const unsigned minor = iminor(file_inode(file));
- struct comedi_file_info *info = comedi_file_info_from_minor(minor);
- struct comedi_device *dev = comedi_dev_from_file_info(info);
+ struct comedi_device *dev = comedi_dev_from_minor(minor);
struct comedi_subdevice *s;
if (!dev)
@@ -1838,7 +1985,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
goto done;
}
- s = comedi_read_subdevice(info);
+ s = comedi_read_subdevice(dev, minor);
if (s && s->async) {
poll_wait(file, &s->async->wait_head, wait);
if (!s->busy || !comedi_is_subdevice_running(s) ||
@@ -1846,7 +1993,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
mask |= POLLIN | POLLRDNORM;
}
- s = comedi_write_subdevice(info);
+ s = comedi_write_subdevice(dev, minor);
if (s && s->async) {
unsigned int bps = bytes_per_sample(s->async->subdevice);
@@ -1870,8 +2017,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file_inode(file));
- struct comedi_file_info *info = comedi_file_info_from_minor(minor);
- struct comedi_device *dev = comedi_dev_from_file_info(info);
+ struct comedi_device *dev = comedi_dev_from_minor(minor);
if (!dev)
return -ENODEV;
@@ -1881,7 +2027,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
return -ENODEV;
}
- s = comedi_write_subdevice(info);
+ s = comedi_write_subdevice(dev, minor);
if (!s || !s->async)
return -EIO;
@@ -1965,8 +2111,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file_inode(file));
- struct comedi_file_info *info = comedi_file_info_from_minor(minor);
- struct comedi_device *dev = comedi_dev_from_file_info(info);
+ struct comedi_device *dev = comedi_dev_from_minor(minor);
if (!dev)
return -ENODEV;
@@ -1976,7 +2121,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
return -ENODEV;
}
- s = comedi_read_subdevice(info);
+ s = comedi_read_subdevice(dev, minor);
if (!s || !s->async)
return -EIO;
@@ -2067,12 +2212,12 @@ static int comedi_open(struct inode *inode, struct file *file)
/* This is slightly hacky, but we want module autoloading
* to work for root.
* case: user opens device, attached -> ok
- * case: user opens device, unattached, in_request_module=0 -> autoload
- * case: user opens device, unattached, in_request_module=1 -> fail
+ * case: user opens device, unattached, !in_request_module -> autoload
+ * case: user opens device, unattached, in_request_module -> fail
* case: root opens device, attached -> ok
- * case: root opens device, unattached, in_request_module=1 -> ok
+ * case: root opens device, unattached, in_request_module -> ok
* (typically called from modprobe)
- * case: root opens device, unattached, in_request_module=0 -> autoload
+ * case: root opens device, unattached, !in_request_module -> autoload
*
* The last could be changed to "-> ok", which would deny root
* autoloading.
@@ -2088,7 +2233,7 @@ static int comedi_open(struct inode *inode, struct file *file)
if (capable(CAP_NET_ADMIN) && dev->in_request_module)
goto ok;
- dev->in_request_module = 1;
+ dev->in_request_module = true;
#ifdef CONFIG_KMOD
mutex_unlock(&dev->mutex);
@@ -2096,7 +2241,7 @@ static int comedi_open(struct inode *inode, struct file *file)
mutex_lock(&dev->mutex);
#endif
- dev->in_request_module = 0;
+ dev->in_request_module = false;
if (!dev->attached && !capable(CAP_NET_ADMIN)) {
DPRINTK("not attached and not CAP_NET_ADMIN\n");
@@ -2195,14 +2340,11 @@ static const struct file_operations comedi_fops = {
.llseek = noop_llseek,
};
-static struct class *comedi_class;
-static struct cdev comedi_cdev;
-
void comedi_error(const struct comedi_device *dev, const char *s)
{
dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s);
}
-EXPORT_SYMBOL(comedi_error);
+EXPORT_SYMBOL_GPL(comedi_error);
void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
{
@@ -2245,150 +2387,104 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
}
s->async->events = 0;
}
-EXPORT_SYMBOL(comedi_event);
-
-static void comedi_device_init(struct comedi_device *dev)
-{
- memset(dev, 0, sizeof(*dev));
- spin_lock_init(&dev->spinlock);
- mutex_init(&dev->mutex);
- dev->minor = -1;
-}
-
-static void comedi_device_cleanup(struct comedi_device *dev)
-{
- if (dev == NULL)
- return;
- mutex_lock(&dev->mutex);
- comedi_device_detach(dev);
- mutex_unlock(&dev->mutex);
- mutex_destroy(&dev->mutex);
-}
+EXPORT_SYMBOL_GPL(comedi_event);
-int comedi_alloc_board_minor(struct device *hardware_device)
+/* Note: the ->mutex is pre-locked on successful return */
+struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
{
- struct comedi_file_info *info;
+ struct comedi_device *dev;
struct device *csdev;
unsigned i;
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (info == NULL)
- return -ENOMEM;
- info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
- if (info->device == NULL) {
- kfree(info);
- return -ENOMEM;
- }
- info->hardware_device = hardware_device;
- comedi_device_init(info->device);
- spin_lock(&comedi_file_info_table_lock);
- for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) {
- if (comedi_file_info_table[i] == NULL) {
- comedi_file_info_table[i] = info;
+ dev = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
+ if (dev == NULL)
+ return ERR_PTR(-ENOMEM);
+ comedi_device_init(dev);
+ comedi_set_hw_dev(dev, hardware_device);
+ mutex_lock(&dev->mutex);
+ mutex_lock(&comedi_board_minor_table_lock);
+ for (i = hardware_device ? comedi_num_legacy_minors : 0;
+ i < COMEDI_NUM_BOARD_MINORS; ++i) {
+ if (comedi_board_minor_table[i] == NULL) {
+ comedi_board_minor_table[i] = dev;
break;
}
}
- spin_unlock(&comedi_file_info_table_lock);
+ mutex_unlock(&comedi_board_minor_table_lock);
if (i == COMEDI_NUM_BOARD_MINORS) {
- comedi_device_cleanup(info->device);
- kfree(info->device);
- kfree(info);
+ mutex_unlock(&dev->mutex);
+ comedi_device_cleanup(dev);
+ kfree(dev);
pr_err("comedi: error: ran out of minor numbers for board device files.\n");
- return -EBUSY;
+ return ERR_PTR(-EBUSY);
}
- info->device->minor = i;
+ dev->minor = i;
csdev = device_create(comedi_class, hardware_device,
MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i);
if (!IS_ERR(csdev))
- info->device->class_dev = csdev;
- dev_set_drvdata(csdev, info);
+ dev->class_dev = csdev;
- return i;
+ /* Note: dev->mutex needs to be unlocked by the caller. */
+ return dev;
}
-void comedi_free_board_minor(unsigned minor)
+static void comedi_free_board_minor(unsigned minor)
{
- struct comedi_file_info *info;
-
BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
- spin_lock(&comedi_file_info_table_lock);
- info = comedi_file_info_table[minor];
- comedi_file_info_table[minor] = NULL;
- spin_unlock(&comedi_file_info_table_lock);
-
- if (info) {
- struct comedi_device *dev = info->device;
- if (dev) {
- if (dev->class_dev) {
- device_destroy(comedi_class,
- MKDEV(COMEDI_MAJOR, dev->minor));
- }
- comedi_device_cleanup(dev);
- kfree(dev);
- }
- kfree(info);
- }
+ comedi_free_board_dev(comedi_clear_board_minor(minor));
}
-int comedi_find_board_minor(struct device *hardware_device)
+void comedi_release_hardware_device(struct device *hardware_device)
{
int minor;
- struct comedi_file_info *info;
-
- for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) {
- spin_lock(&comedi_file_info_table_lock);
- info = comedi_file_info_table[minor];
- if (info && info->hardware_device == hardware_device) {
- spin_unlock(&comedi_file_info_table_lock);
- return minor;
+ struct comedi_device *dev;
+
+ for (minor = comedi_num_legacy_minors; minor < COMEDI_NUM_BOARD_MINORS;
+ minor++) {
+ mutex_lock(&comedi_board_minor_table_lock);
+ dev = comedi_board_minor_table[minor];
+ if (dev && dev->hw_dev == hardware_device) {
+ comedi_board_minor_table[minor] = NULL;
+ mutex_unlock(&comedi_board_minor_table_lock);
+ comedi_free_board_dev(dev);
+ break;
}
- spin_unlock(&comedi_file_info_table_lock);
+ mutex_unlock(&comedi_board_minor_table_lock);
}
- return -ENODEV;
}
int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
{
struct comedi_device *dev = s->device;
- struct comedi_file_info *info;
struct device *csdev;
unsigned i;
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
- info->device = dev;
- if (s->subdev_flags & SDF_CMD_READ)
- info->read_subdevice = s;
- if (s->subdev_flags & SDF_CMD_WRITE)
- info->write_subdevice = s;
- spin_lock(&comedi_file_info_table_lock);
- for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) {
- if (comedi_file_info_table[i] == NULL) {
- comedi_file_info_table[i] = info;
+ mutex_lock(&comedi_subdevice_minor_table_lock);
+ for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
+ if (comedi_subdevice_minor_table[i] == NULL) {
+ comedi_subdevice_minor_table[i] = s;
break;
}
}
- spin_unlock(&comedi_file_info_table_lock);
- if (i == COMEDI_NUM_MINORS) {
- kfree(info);
+ mutex_unlock(&comedi_subdevice_minor_table_lock);
+ if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
return -EBUSY;
}
+ i += COMEDI_NUM_BOARD_MINORS;
s->minor = i;
csdev = device_create(comedi_class, dev->class_dev,
MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i",
dev->minor, s->index);
if (!IS_ERR(csdev))
s->class_dev = csdev;
- dev_set_drvdata(csdev, info);
return 0;
}
void comedi_free_subdevice_minor(struct comedi_subdevice *s)
{
- struct comedi_file_info *info;
+ unsigned int i;
if (s == NULL)
return;
@@ -2396,18 +2492,17 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s)
return;
BUG_ON(s->minor >= COMEDI_NUM_MINORS);
- BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR);
-
- spin_lock(&comedi_file_info_table_lock);
- info = comedi_file_info_table[s->minor];
- comedi_file_info_table[s->minor] = NULL;
- spin_unlock(&comedi_file_info_table_lock);
+ BUG_ON(s->minor < COMEDI_NUM_BOARD_MINORS);
+ i = s->minor - COMEDI_NUM_BOARD_MINORS;
+ mutex_lock(&comedi_subdevice_minor_table_lock);
+ if (s == comedi_subdevice_minor_table[i])
+ comedi_subdevice_minor_table[i] = NULL;
+ mutex_unlock(&comedi_subdevice_minor_table_lock);
if (s->class_dev) {
device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
s->class_dev = NULL;
}
- kfree(info);
}
static void comedi_cleanup_board_minors(void)
@@ -2432,9 +2527,6 @@ static int __init comedi_init(void)
return -EINVAL;
}
- memset(comedi_file_info_table, 0,
- sizeof(struct comedi_file_info *) * COMEDI_NUM_MINORS);
-
retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
COMEDI_NUM_MINORS, "comedi");
if (retval)
@@ -2463,14 +2555,17 @@ static int __init comedi_init(void)
/* create devices files for legacy/manual use */
for (i = 0; i < comedi_num_legacy_minors; i++) {
- int minor;
- minor = comedi_alloc_board_minor(NULL);
- if (minor < 0) {
+ struct comedi_device *dev;
+ dev = comedi_alloc_board_minor(NULL);
+ if (IS_ERR(dev)) {
comedi_cleanup_board_minors();
cdev_del(&comedi_cdev);
unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
COMEDI_NUM_MINORS);
- return minor;
+ return PTR_ERR(dev);
+ } else {
+ /* comedi_alloc_board_minor() locked the mutex */
+ mutex_unlock(&dev->mutex);
}
}
@@ -2483,8 +2578,10 @@ static void __exit comedi_cleanup(void)
int i;
comedi_cleanup_board_minors();
- for (i = 0; i < COMEDI_NUM_MINORS; ++i)
- BUG_ON(comedi_file_info_table[i]);
+ for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i)
+ BUG_ON(comedi_board_minor_table[i]);
+ for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i)
+ BUG_ON(comedi_subdevice_minor_table[i]);
class_destroy(comedi_class);
cdev_del(&comedi_cdev);
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index b3743135f4a..d5e03e558b3 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -8,9 +8,8 @@
*/
int do_rangeinfo_ioctl(struct comedi_device *dev,
struct comedi_rangeinfo __user *arg);
-int comedi_alloc_board_minor(struct device *hardware_device);
-void comedi_free_board_minor(unsigned minor);
-int comedi_find_board_minor(struct device *hardware_device);
+struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device);
+void comedi_release_hardware_device(struct device *hardware_device);
int comedi_alloc_subdevice_minor(struct comedi_subdevice *s);
void comedi_free_subdevice_minor(struct comedi_subdevice *s);
diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c
index 37d2e467736..5fad084cfbd 100644
--- a/drivers/staging/comedi/comedi_pci.c
+++ b/drivers/staging/comedi/comedi_pci.c
@@ -36,20 +36,25 @@ EXPORT_SYMBOL_GPL(comedi_to_pci_dev);
/**
* comedi_pci_enable() - Enable the PCI device and request the regions.
- * @pcidev: pci_dev struct
- * @res_name: name for the requested reqource
+ * @dev: comedi_device struct
*/
-int comedi_pci_enable(struct pci_dev *pcidev, const char *res_name)
+int comedi_pci_enable(struct comedi_device *dev)
{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
int rc;
+ if (!pcidev)
+ return -ENODEV;
+
rc = pci_enable_device(pcidev);
if (rc < 0)
return rc;
- rc = pci_request_regions(pcidev, res_name);
+ rc = pci_request_regions(pcidev, dev->board_name);
if (rc < 0)
pci_disable_device(pcidev);
+ else
+ dev->ioenabled = true;
return rc;
}
@@ -57,14 +62,17 @@ EXPORT_SYMBOL_GPL(comedi_pci_enable);
/**
* comedi_pci_disable() - Release the regions and disable the PCI device.
- * @pcidev: pci_dev struct
- *
- * This must be matched with a previous successful call to comedi_pci_enable().
+ * @dev: comedi_device struct
*/
-void comedi_pci_disable(struct pci_dev *pcidev)
+void comedi_pci_disable(struct comedi_device *dev)
{
- pci_release_regions(pcidev);
- pci_disable_device(pcidev);
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+
+ if (pcidev && dev->ioenabled) {
+ pci_release_regions(pcidev);
+ pci_disable_device(pcidev);
+ }
+ dev->ioenabled = false;
}
EXPORT_SYMBOL_GPL(comedi_pci_disable);
@@ -72,13 +80,15 @@ EXPORT_SYMBOL_GPL(comedi_pci_disable);
* comedi_pci_auto_config() - Configure/probe a comedi PCI driver.
* @pcidev: pci_dev struct
* @driver: comedi_driver struct
+ * @context: driver specific data, passed to comedi_auto_config()
*
* Typically called from the pci_driver (*probe) function.
*/
int comedi_pci_auto_config(struct pci_dev *pcidev,
- struct comedi_driver *driver)
+ struct comedi_driver *driver,
+ unsigned long context)
{
- return comedi_auto_config(&pcidev->dev, driver, 0);
+ return comedi_auto_config(&pcidev->dev, driver, context);
}
EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index f3a990b45df..cdd472094ce 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -53,9 +53,7 @@
COMEDI_MINORVERSION, COMEDI_MICROVERSION)
#define COMEDI_RELEASE VERSION
-#define COMEDI_NUM_MINORS 0x100
#define COMEDI_NUM_BOARD_MINORS 0x30
-#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
struct comedi_subdevice {
struct comedi_device *device;
@@ -207,16 +205,18 @@ struct comedi_device {
const char *board_name;
const void *board_ptr;
- int attached;
+ bool attached:1;
+ bool in_request_module:1;
+ bool ioenabled:1;
spinlock_t spinlock;
struct mutex mutex;
- int in_request_module;
int n_subdevices;
struct comedi_subdevice *subdevices;
/* dumb */
unsigned long iobase;
+ unsigned long iolen;
unsigned int irq;
struct comedi_subdevice *read_subdev;
@@ -293,6 +293,10 @@ extern const struct comedi_lrange range_bipolar5;
extern const struct comedi_lrange range_bipolar2_5;
extern const struct comedi_lrange range_unipolar10;
extern const struct comedi_lrange range_unipolar5;
+extern const struct comedi_lrange range_unipolar2_5;
+extern const struct comedi_lrange range_0_20mA;
+extern const struct comedi_lrange range_4_20mA;
+extern const struct comedi_lrange range_0_32mA;
extern const struct comedi_lrange range_unknown;
#define range_digital range_unipolar5
@@ -345,6 +349,14 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
int comedi_alloc_subdevices(struct comedi_device *, int);
+void comedi_spriv_free(struct comedi_device *, int subdev_num);
+
+int __comedi_request_region(struct comedi_device *,
+ unsigned long start, unsigned long len);
+int comedi_request_region(struct comedi_device *,
+ unsigned long start, unsigned long len);
+void comedi_legacy_detach(struct comedi_device *);
+
int comedi_auto_config(struct device *, struct comedi_driver *,
unsigned long context);
void comedi_auto_unconfig(struct device *);
@@ -384,10 +396,11 @@ struct pci_driver;
struct pci_dev *comedi_to_pci_dev(struct comedi_device *);
-int comedi_pci_enable(struct pci_dev *, const char *);
-void comedi_pci_disable(struct pci_dev *);
+int comedi_pci_enable(struct comedi_device *);
+void comedi_pci_disable(struct comedi_device *);
-int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *);
+int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *,
+ unsigned long context);
void comedi_pci_auto_unconfig(struct pci_dev *);
int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *);
@@ -420,12 +433,12 @@ static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev)
return NULL;
}
-static inline int comedi_pci_enable(struct pci_dev *dev, const char *name)
+static inline int comedi_pci_enable(struct comedi_device *dev)
{
return -ENOSYS;
}
-static inline void comedi_pci_disable(struct pci_dev *dev)
+static inline void comedi_pci_disable(struct comedi_device *dev)
{
}
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 64be7c5e891..06d190f8fd3 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -37,6 +37,7 @@
#include <linux/cdev.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
#include "comedidev.h"
#include "comedi_internal.h"
@@ -86,6 +87,18 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices)
}
EXPORT_SYMBOL_GPL(comedi_alloc_subdevices);
+void comedi_spriv_free(struct comedi_device *dev, int subdev_num)
+{
+ struct comedi_subdevice *s;
+
+ if (dev->subdevices && subdev_num < dev->n_subdevices) {
+ s = &dev->subdevices[subdev_num];
+ kfree(s->private);
+ s->private = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(comedi_spriv_free);
+
static void cleanup_device(struct comedi_device *dev)
{
int i;
@@ -110,6 +123,8 @@ static void cleanup_device(struct comedi_device *dev)
dev->board_name = NULL;
dev->board_ptr = NULL;
dev->iobase = 0;
+ dev->iolen = 0;
+ dev->ioenabled = false;
dev->irq = 0;
dev->read_subdev = NULL;
dev->write_subdev = NULL;
@@ -118,24 +133,14 @@ static void cleanup_device(struct comedi_device *dev)
comedi_clear_hw_dev(dev);
}
-static void __comedi_device_detach(struct comedi_device *dev)
+void comedi_device_detach(struct comedi_device *dev)
{
- dev->attached = 0;
+ dev->attached = false;
if (dev->driver)
dev->driver->detach(dev);
- else
- dev_warn(dev->class_dev,
- "BUG: dev->driver=NULL in comedi_device_detach()\n");
cleanup_device(dev);
}
-void comedi_device_detach(struct comedi_device *dev)
-{
- if (!dev->attached)
- return;
- __comedi_device_detach(dev);
-}
-
static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
{
return -EINVAL;
@@ -276,21 +281,15 @@ static int __comedi_device_postconfig(struct comedi_device *dev)
}
/* do a little post-config cleanup */
-/* called with module refcount incremented, decrements it */
static int comedi_device_postconfig(struct comedi_device *dev)
{
- int ret = __comedi_device_postconfig(dev);
- module_put(dev->driver->module);
- if (ret < 0) {
- __comedi_device_detach(dev);
+ int ret;
+
+ ret = __comedi_device_postconfig(dev);
+ if (ret < 0)
return ret;
- }
- if (!dev->board_name) {
- dev_warn(dev->class_dev, "BUG: dev->board_name=NULL\n");
- dev->board_name = "BUG";
- }
smp_wmb();
- dev->attached = 1;
+ dev->attached = true;
return 0;
}
@@ -352,6 +351,71 @@ static void comedi_report_boards(struct comedi_driver *driv)
pr_info(" %s\n", driv->driver_name);
}
+/**
+ * __comedi_request_region() - Request an I/O reqion for a legacy driver.
+ * @dev: comedi_device struct
+ * @start: base address of the I/O reqion
+ * @len: length of the I/O region
+ */
+int __comedi_request_region(struct comedi_device *dev,
+ unsigned long start, unsigned long len)
+{
+ if (!start) {
+ dev_warn(dev->class_dev,
+ "%s: a I/O base address must be specified\n",
+ dev->board_name);
+ return -EINVAL;
+ }
+
+ if (!request_region(start, len, dev->board_name)) {
+ dev_warn(dev->class_dev, "%s: I/O port conflict (%#lx,%lu)\n",
+ dev->board_name, start, len);
+ return -EIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__comedi_request_region);
+
+/**
+ * comedi_request_region() - Request an I/O reqion for a legacy driver.
+ * @dev: comedi_device struct
+ * @start: base address of the I/O reqion
+ * @len: length of the I/O region
+ */
+int comedi_request_region(struct comedi_device *dev,
+ unsigned long start, unsigned long len)
+{
+ int ret;
+
+ ret = __comedi_request_region(dev, start, len);
+ if (ret == 0) {
+ dev->iobase = start;
+ dev->iolen = len;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(comedi_request_region);
+
+/**
+ * comedi_legacy_detach() - A generic (*detach) function for legacy drivers.
+ * @dev: comedi_device struct
+ */
+void comedi_legacy_detach(struct comedi_device *dev)
+{
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ dev->irq = 0;
+ }
+ if (dev->iobase && dev->iolen) {
+ release_region(dev->iobase, dev->iolen);
+ dev->iobase = 0;
+ dev->iolen = 0;
+ }
+}
+EXPORT_SYMBOL_GPL(comedi_legacy_detach);
+
int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct comedi_driver *driv;
@@ -393,22 +457,35 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* initialize dev->driver here so
* comedi_error() can be called from attach */
dev->driver = driv;
+ dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr
+ : dev->driver->driver_name;
ret = driv->attach(dev, it);
+ if (ret >= 0)
+ ret = comedi_device_postconfig(dev);
if (ret < 0) {
+ comedi_device_detach(dev);
module_put(dev->driver->module);
- __comedi_device_detach(dev);
- return ret;
}
- return comedi_device_postconfig(dev);
+ /* On success, the driver module count has been incremented. */
+ return ret;
}
int comedi_auto_config(struct device *hardware_device,
struct comedi_driver *driver, unsigned long context)
{
- int minor;
- struct comedi_device *comedi_dev;
+ struct comedi_device *dev;
int ret;
+ if (!hardware_device) {
+ pr_warn("BUG! comedi_auto_config called with NULL hardware_device\n");
+ return -EINVAL;
+ }
+ if (!driver) {
+ dev_warn(hardware_device,
+ "BUG! comedi_auto_config called with NULL comedi driver\n");
+ return -EINVAL;
+ }
+
if (!driver->auto_attach) {
dev_warn(hardware_device,
"BUG! comedi driver '%s' has no auto_attach handler\n",
@@ -416,46 +493,31 @@ int comedi_auto_config(struct device *hardware_device,
return -EINVAL;
}
- minor = comedi_alloc_board_minor(hardware_device);
- if (minor < 0)
- return minor;
-
- comedi_dev = comedi_dev_from_minor(minor);
-
- mutex_lock(&comedi_dev->mutex);
- if (comedi_dev->attached)
- ret = -EBUSY;
- else if (!try_module_get(driver->module))
- ret = -EIO;
- else {
- comedi_set_hw_dev(comedi_dev, hardware_device);
- comedi_dev->driver = driver;
- ret = driver->auto_attach(comedi_dev, context);
- if (ret < 0) {
- module_put(driver->module);
- __comedi_device_detach(comedi_dev);
- } else {
- ret = comedi_device_postconfig(comedi_dev);
- }
- }
- mutex_unlock(&comedi_dev->mutex);
+ dev = comedi_alloc_board_minor(hardware_device);
+ if (IS_ERR(dev))
+ return PTR_ERR(dev);
+ /* Note: comedi_alloc_board_minor() locked dev->mutex. */
+ dev->driver = driver;
+ dev->board_name = dev->driver->driver_name;
+ ret = driver->auto_attach(dev, context);
+ if (ret >= 0)
+ ret = comedi_device_postconfig(dev);
if (ret < 0)
- comedi_free_board_minor(minor);
+ comedi_device_detach(dev);
+ mutex_unlock(&dev->mutex);
+
+ if (ret < 0)
+ comedi_release_hardware_device(hardware_device);
return ret;
}
EXPORT_SYMBOL_GPL(comedi_auto_config);
void comedi_auto_unconfig(struct device *hardware_device)
{
- int minor;
-
if (hardware_device == NULL)
return;
- minor = comedi_find_board_minor(hardware_device);
- if (minor < 0)
- return;
- comedi_free_board_minor(minor);
+ comedi_release_hardware_device(hardware_device);
}
EXPORT_SYMBOL_GPL(comedi_auto_unconfig);
@@ -466,7 +528,7 @@ int comedi_driver_register(struct comedi_driver *driver)
return 0;
}
-EXPORT_SYMBOL(comedi_driver_register);
+EXPORT_SYMBOL_GPL(comedi_driver_register);
int comedi_driver_unregister(struct comedi_driver *driver)
{
@@ -504,4 +566,4 @@ int comedi_driver_unregister(struct comedi_driver *driver)
}
return -EINVAL;
}
-EXPORT_SYMBOL(comedi_driver_unregister);
+EXPORT_SYMBOL_GPL(comedi_driver_unregister);
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index c7aa41ad842..1d48aa602ec 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -129,7 +129,7 @@ void subdev_8255_interrupt(struct comedi_device *dev,
comedi_event(dev, s);
}
-EXPORT_SYMBOL(subdev_8255_interrupt);
+EXPORT_SYMBOL_GPL(subdev_8255_interrupt);
static int subdev_8255_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -314,7 +314,7 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
return 0;
}
-EXPORT_SYMBOL(subdev_8255_init);
+EXPORT_SYMBOL_GPL(subdev_8255_init);
int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
int (*io) (int, int, int, unsigned long),
@@ -332,13 +332,7 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
return 0;
}
-EXPORT_SYMBOL(subdev_8255_init_irq);
-
-void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- kfree(s->private);
-}
-EXPORT_SYMBOL(subdev_8255_cleanup);
+EXPORT_SYMBOL_GPL(subdev_8255_init_irq);
/*
@@ -354,8 +348,6 @@ static int dev_8255_attach(struct comedi_device *dev,
unsigned long iobase;
int i;
- dev->board_name = "8255";
-
for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
iobase = it->options[i];
if (!iobase)
@@ -374,16 +366,13 @@ static int dev_8255_attach(struct comedi_device *dev,
s = &dev->subdevices[i];
iobase = it->options[i];
- if (!request_region(iobase, _8255_SIZE, "8255")) {
- dev_warn(dev->class_dev,
- "0x%04lx (I/O port conflict)\n", iobase);
-
+ ret = __comedi_request_region(dev, iobase, _8255_SIZE);
+ if (ret) {
s->type = COMEDI_SUBD_UNUSED;
} else {
ret = subdev_8255_init(dev, s, NULL, iobase);
if (ret)
return ret;
- dev_info(dev->class_dev, "0x%04lx\n", iobase);
}
}
@@ -402,7 +391,7 @@ static void dev_8255_detach(struct comedi_device *dev)
spriv = s->private;
release_region(spriv->iobase, _8255_SIZE);
}
- subdev_8255_cleanup(dev, s);
+ comedi_spriv_free(dev, i);
}
}
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
index 1e589b4b8b7..0f6e7492b7d 100644
--- a/drivers/staging/comedi/drivers/8255.h
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -32,7 +32,6 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
int (*io) (int, int, int, unsigned long),
unsigned long iobase);
-void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s);
void subdev_8255_interrupt(struct comedi_device *dev,
struct comedi_subdevice *s);
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index 0ae356ae56e..76dec96aeb2 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -60,126 +60,98 @@ Configuration Options: not applicable, uses PCI auto config
#include "8255.h"
-/*
- * PCI Device ID's supported by this driver
- */
-#define PCI_DEVICE_ID_ADLINK_PCI7224 0x7224
-#define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248
-#define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296
-
-#define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b
-#define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014
-#define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017
-#define PCI_DEVICE_ID_CB_PCIDIO24 0x0028
-
-#define PCI_DEVICE_ID_NI_PCIDIO96 0x0160
-#define PCI_DEVICE_ID_NI_PCI6503 0x0400
-#define PCI_DEVICE_ID_NI_PCI6503B 0x1250
-#define PCI_DEVICE_ID_NI_PXI6508 0x13c0
-#define PCI_DEVICE_ID_NI_PCIDIO96B 0x1630
-#define PCI_DEVICE_ID_NI_PCI6503X 0x17d0
-#define PCI_DEVICE_ID_NI_PXI_6503 0x1800
+enum pci_8255_boardid {
+ BOARD_ADLINK_PCI7224,
+ BOARD_ADLINK_PCI7248,
+ BOARD_ADLINK_PCI7296,
+ BOARD_CB_PCIDIO24,
+ BOARD_CB_PCIDIO24H,
+ BOARD_CB_PCIDIO48H,
+ BOARD_CB_PCIDIO96H,
+ BOARD_NI_PCIDIO96,
+ BOARD_NI_PCIDIO96B,
+ BOARD_NI_PXI6508,
+ BOARD_NI_PCI6503,
+ BOARD_NI_PCI6503B,
+ BOARD_NI_PCI6503X,
+ BOARD_NI_PXI_6503,
+};
struct pci_8255_boardinfo {
const char *name;
- unsigned short vendor;
- unsigned short device;
int dio_badr;
- int is_mmio;
int n_8255;
};
static const struct pci_8255_boardinfo pci_8255_boards[] = {
- {
+ [BOARD_ADLINK_PCI7224] = {
.name = "adl_pci-7224",
- .vendor = PCI_VENDOR_ID_ADLINK,
- .device = PCI_DEVICE_ID_ADLINK_PCI7224,
.dio_badr = 2,
.n_8255 = 1,
- }, {
+ },
+ [BOARD_ADLINK_PCI7248] = {
.name = "adl_pci-7248",
- .vendor = PCI_VENDOR_ID_ADLINK,
- .device = PCI_DEVICE_ID_ADLINK_PCI7248,
.dio_badr = 2,
.n_8255 = 2,
- }, {
+ },
+ [BOARD_ADLINK_PCI7296] = {
.name = "adl_pci-7296",
- .vendor = PCI_VENDOR_ID_ADLINK,
- .device = PCI_DEVICE_ID_ADLINK_PCI7296,
.dio_badr = 2,
.n_8255 = 4,
- }, {
+ },
+ [BOARD_CB_PCIDIO24] = {
.name = "cb_pci-dio24",
- .vendor = PCI_VENDOR_ID_CB,
- .device = PCI_DEVICE_ID_CB_PCIDIO24,
.dio_badr = 2,
.n_8255 = 1,
- }, {
+ },
+ [BOARD_CB_PCIDIO24H] = {
.name = "cb_pci-dio24h",
- .vendor = PCI_VENDOR_ID_CB,
- .device = PCI_DEVICE_ID_CB_PCIDIO24H,
.dio_badr = 2,
.n_8255 = 1,
- }, {
+ },
+ [BOARD_CB_PCIDIO48H] = {
.name = "cb_pci-dio48h",
- .vendor = PCI_VENDOR_ID_CB,
- .device = PCI_DEVICE_ID_CB_PCIDIO48H,
.dio_badr = 1,
.n_8255 = 2,
- }, {
+ },
+ [BOARD_CB_PCIDIO96H] = {
.name = "cb_pci-dio96h",
- .vendor = PCI_VENDOR_ID_CB,
- .device = PCI_DEVICE_ID_CB_PCIDIO96H,
.dio_badr = 2,
.n_8255 = 4,
- }, {
+ },
+ [BOARD_NI_PCIDIO96] = {
.name = "ni_pci-dio-96",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PCIDIO96,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 4,
- }, {
+ },
+ [BOARD_NI_PCIDIO96B] = {
.name = "ni_pci-dio-96b",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PCIDIO96B,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 4,
- }, {
+ },
+ [BOARD_NI_PXI6508] = {
.name = "ni_pxi-6508",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PXI6508,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 4,
- }, {
+ },
+ [BOARD_NI_PCI6503] = {
.name = "ni_pci-6503",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PCI6503,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 1,
- }, {
+ },
+ [BOARD_NI_PCI6503B] = {
.name = "ni_pci-6503b",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PCI6503B,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 1,
- }, {
+ },
+ [BOARD_NI_PCI6503X] = {
.name = "ni_pci-6503x",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PCI6503X,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 1,
- }, {
+ },
+ [BOARD_NI_PXI_6503] = {
.name = "ni_pxi-6503",
- .vendor = PCI_VENDOR_ID_NI,
- .device = PCI_DEVICE_ID_NI_PXI_6503,
.dio_badr = 1,
- .is_mmio = 1,
.n_8255 = 1,
},
};
@@ -200,34 +172,19 @@ static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
}
}
-static const void *pci_8255_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct pci_8255_boardinfo *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pci_8255_boards); i++) {
- board = &pci_8255_boards[i];
- if (pcidev->vendor == board->vendor &&
- pcidev->device == board->device)
- return board;
- }
- return NULL;
-}
-
static int pci_8255_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct pci_8255_boardinfo *board;
+ const struct pci_8255_boardinfo *board = NULL;
struct pci_8255_private *devpriv;
struct comedi_subdevice *s;
- resource_size_t iobase;
- unsigned long len;
+ bool is_mmio;
int ret;
int i;
- board = pci_8255_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(pci_8255_boards))
+ board = &pci_8255_boards[context];
if (!board)
return -ENODEV;
dev->board_ptr = board;
@@ -238,18 +195,19 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
- iobase = pci_resource_start(pcidev, board->dio_badr);
- len = pci_resource_len(pcidev, board->dio_badr);
- if (board->is_mmio) {
- devpriv->mmio_base = ioremap(iobase, len);
+ is_mmio = (pci_resource_flags(pcidev, board->dio_badr) &
+ IORESOURCE_MEM) != 0;
+ if (is_mmio) {
+ devpriv->mmio_base = pci_ioremap_bar(pcidev, board->dio_badr);
if (!devpriv->mmio_base)
return -ENOMEM;
+ } else {
+ dev->iobase = pci_resource_start(pcidev, board->dio_badr);
}
- dev->iobase = iobase;
/*
* One, two, or four subdevices are setup by this driver depending
@@ -261,8 +219,10 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
return ret;
for (i = 0; i < board->n_8255; i++) {
+ unsigned long iobase;
+
s = &dev->subdevices[i];
- if (board->is_mmio) {
+ if (is_mmio) {
iobase = (unsigned long)(devpriv->mmio_base + (i * 4));
ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase);
} else {
@@ -281,26 +241,14 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
static void pci_8255_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct pci_8255_boardinfo *board = comedi_board(dev);
struct pci_8255_private *devpriv = dev->private;
- struct comedi_subdevice *s;
int i;
- if (!board || !devpriv)
- return;
- if (dev->subdevices) {
- for (i = 0; i < board->n_8255; i++) {
- s = &dev->subdevices[i];
- subdev_8255_cleanup(dev, s);
- }
- }
- if (pcidev) {
- if (devpriv->mmio_base)
- iounmap(devpriv->mmio_base);
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ for (i = 0; i < dev->n_subdevices; i++)
+ comedi_spriv_free(dev, i);
+ if (devpriv && devpriv->mmio_base)
+ iounmap(devpriv->mmio_base);
+ comedi_pci_disable(dev);
}
static struct comedi_driver pci_8255_driver = {
@@ -311,26 +259,26 @@ static struct comedi_driver pci_8255_driver = {
};
static int pci_8255_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &pci_8255_driver);
+ return comedi_pci_auto_config(dev, &pci_8255_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7224) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7248) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_ADLINK_PCI7296) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO24H) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO48H) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_CB_PCIDIO96H) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCIDIO96B) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI6508) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503B) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI6503X) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI_6503) },
+ { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 },
+ { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 },
+ { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 },
+ { PCI_VDEVICE(CB, 0x0028), BOARD_CB_PCIDIO24 },
+ { PCI_VDEVICE(CB, 0x0014), BOARD_CB_PCIDIO24H },
+ { PCI_VDEVICE(CB, 0x000b), BOARD_CB_PCIDIO48H },
+ { PCI_VDEVICE(CB, 0x0017), BOARD_CB_PCIDIO96H },
+ { PCI_VDEVICE(NI, 0x0160), BOARD_NI_PCIDIO96 },
+ { PCI_VDEVICE(NI, 0x1630), BOARD_NI_PCIDIO96B },
+ { PCI_VDEVICE(NI, 0x13c0), BOARD_NI_PXI6508 },
+ { PCI_VDEVICE(NI, 0x0400), BOARD_NI_PCI6503 },
+ { PCI_VDEVICE(NI, 0x1250), BOARD_NI_PCI6503B },
+ { PCI_VDEVICE(NI, 0x17d0), BOARD_NI_PCI6503X },
+ { PCI_VDEVICE(NI, 0x1800), BOARD_NI_PXI_6503 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, pci_8255_pci_table);
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 315e836ff99..57e984f0f46 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -12,6 +12,8 @@ obj-$(CONFIG_COMEDI_SKEL) += skel.o
# Comedi ISA drivers
obj-$(CONFIG_COMEDI_ACL7225B) += acl7225b.o
+obj-$(CONFIG_COMEDI_AMPLC_DIO200_ISA) += amplc_dio200.o
+obj-$(CONFIG_COMEDI_AMPLC_PC263_ISA) += amplc_pc263.o
obj-$(CONFIG_COMEDI_PCL711) += pcl711.o
obj-$(CONFIG_COMEDI_PCL724) += pcl724.o
obj-$(CONFIG_COMEDI_PCL725) += pcl725.o
@@ -75,10 +77,11 @@ obj-$(CONFIG_COMEDI_ADL_PCI9111) += adl_pci9111.o
obj-$(CONFIG_COMEDI_ADL_PCI9118) += adl_pci9118.o
obj-$(CONFIG_COMEDI_ADV_PCI1710) += adv_pci1710.o
obj-$(CONFIG_COMEDI_ADV_PCI1723) += adv_pci1723.o
+obj-$(CONFIG_COMEDI_ADV_PCI1724) += adv_pci1724.o
obj-$(CONFIG_COMEDI_ADV_PCI_DIO) += adv_pci_dio.o
-obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200.o
+obj-$(CONFIG_COMEDI_AMPLC_DIO200_PCI) += amplc_dio200_pci.o
obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236.o
-obj-$(CONFIG_COMEDI_AMPLC_PC263) += amplc_pc263.o
+obj-$(CONFIG_COMEDI_AMPLC_PC263_PCI) += amplc_pci263.o
obj-$(CONFIG_COMEDI_AMPLC_PCI224) += amplc_pci224.o
obj-$(CONFIG_COMEDI_AMPLC_PCI230) += amplc_pci230.o
obj-$(CONFIG_COMEDI_CONTEC_PCI_DIO) += contec_pci_dio.o
@@ -103,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
@@ -133,5 +137,6 @@ obj-$(CONFIG_COMEDI_NI_TIOCMD) += ni_tiocmd.o
obj-$(CONFIG_COMEDI_NI_LABPC) += ni_labpc.o
obj-$(CONFIG_COMEDI_8255) += 8255.o
+obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200_common.o
obj-$(CONFIG_COMEDI_DAS08) += das08.o
obj-$(CONFIG_COMEDI_FC) += comedi_fc.o
diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c
index 28c7fd3a96b..9e2c7aeea53 100644
--- a/drivers/staging/comedi/drivers/acl7225b.c
+++ b/drivers/staging/comedi/drivers/acl7225b.c
@@ -15,43 +15,59 @@ Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
#include <linux/ioport.h>
-#define ACL7225_SIZE 8 /* Requires 8 ioports, but only 4 are used */
-#define P16R16DIO_SIZE 4
#define ACL7225_RIO_LO 0 /* Relays input/output low byte (R0-R7) */
#define ACL7225_RIO_HI 1 /* Relays input/output high byte (R8-R15) */
#define ACL7225_DI_LO 2 /* Digital input low byte (DI0-DI7) */
#define ACL7225_DI_HI 3 /* Digital input high byte (DI8-DI15) */
-struct boardtype {
- const char *name; /* driver name */
- int io_range; /* len of I/O space */
+struct acl7225b_boardinfo {
+ const char *name;
+ int io_range;
};
-static int acl7225b_do_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static const struct acl7225b_boardinfo acl7225b_boards[] = {
+ {
+ .name = "acl7225b",
+ .io_range = 8, /* only 4 are used */
+ }, {
+ .name = "p16r16dio",
+ .io_range = 4,
+ },
+};
+
+static int acl7225b_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- if (data[0]) {
- s->state &= ~data[0];
- s->state |= (data[0] & data[1]);
+ unsigned long reg = (unsigned long)s->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
+
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
+
+ if (mask & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + reg);
+ if (mask & 0xff00)
+ outb((s->state >> 8), dev->iobase + reg + 1);
}
- if (data[0] & 0x00ff)
- outb(s->state & 0xff, dev->iobase + (unsigned long)s->private);
- if (data[0] & 0xff00)
- outb((s->state >> 8),
- dev->iobase + (unsigned long)s->private + 1);
data[1] = s->state;
return insn->n;
}
-static int acl7225b_di_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int acl7225b_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- data[1] = inb(dev->iobase + (unsigned long)s->private) |
- (inb(dev->iobase + (unsigned long)s->private + 1) << 8);
+ unsigned long reg = (unsigned long)s->private;
+
+ data[1] = inb(dev->iobase + reg) |
+ (inb(dev->iobase + reg + 1) << 8);
return insn->n;
}
@@ -59,23 +75,13 @@ static int acl7225b_di_insn(struct comedi_device *dev,
static int acl7225b_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- const struct boardtype *board = comedi_board(dev);
+ const struct acl7225b_boardinfo *board = comedi_board(dev);
struct comedi_subdevice *s;
- int iobase, iorange;
int ret;
- iobase = it->options[0];
- iorange = board->io_range;
- printk(KERN_INFO "comedi%d: acl7225b: board=%s 0x%04x\n", dev->minor,
- board->name, iobase);
- if (!request_region(iobase, iorange, "acl7225b")) {
- printk(KERN_ERR "comedi%d: request_region failed - I/O port conflict\n",
- dev->minor);
- return -EIO;
- }
- dev->board_name = board->name;
- dev->iobase = iobase;
- dev->irq = 0;
+ ret = comedi_request_region(dev, it->options[0], board->io_range);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
@@ -83,61 +89,48 @@ static int acl7225b_attach(struct comedi_device *dev,
s = &dev->subdevices[0];
/* Relays outputs */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->maxdata = 1;
- s->n_chan = 16;
- s->insn_bits = acl7225b_do_insn;
- s->range_table = &range_digital;
- s->private = (void *)ACL7225_RIO_LO;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_RIO_LO;
s = &dev->subdevices[1];
/* Relays status */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->maxdata = 1;
- s->n_chan = 16;
- s->insn_bits = acl7225b_di_insn;
- s->range_table = &range_digital;
- s->private = (void *)ACL7225_RIO_LO;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_RIO_LO;
s = &dev->subdevices[2];
/* Isolated digital inputs */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->maxdata = 1;
- s->n_chan = 16;
- s->insn_bits = acl7225b_di_insn;
- s->range_table = &range_digital;
- s->private = (void *)ACL7225_DI_LO;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_DI_LO;
return 0;
}
-static void acl7225b_detach(struct comedi_device *dev)
-{
- const struct boardtype *board = comedi_board(dev);
-
- if (dev->iobase)
- release_region(dev->iobase, board->io_range);
-}
-
-static const struct boardtype boardtypes[] = {
- { "acl7225b", ACL7225_SIZE, },
- { "p16r16dio", P16R16DIO_SIZE, },
-};
-
static struct comedi_driver acl7225b_driver = {
.driver_name = "acl7225b",
.module = THIS_MODULE,
.attach = acl7225b_attach,
- .detach = acl7225b_detach,
- .board_name = &boardtypes[0].name,
- .num_names = ARRAY_SIZE(boardtypes),
- .offset = sizeof(struct boardtype),
+ .detach = comedi_legacy_detach,
+ .board_name = &acl7225b_boards[0].name,
+ .num_names = ARRAY_SIZE(acl7225b_boards),
+ .offset = sizeof(struct acl7225b_boardinfo),
};
module_comedi_driver(acl7225b_driver);
+MODULE_DESCRIPTION("Comedi: NuDAQ ACL-7225B, 16 Relay & 16 Isolated DI Card");
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
index 1e05732e9f3..97e7eec343d 100644
--- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -704,9 +704,9 @@ static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev,
| unsigned char *_ pb_ChannelStatus) |
+----------------------------------------------------------------------------+
| Task :
- (0) Set the digital output from selected SSI moule |
+ (0) Set the digital output from selected SSI module |
| (b_ModuleNbr) ON
- (1) Set the digital output from selected SSI moule |
+ (1) Set the digital output from selected SSI module |
| (b_ModuleNbr) OFF
(2)Read the status from selected SSI digital input |
| (b_InputChannel)
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index 1051fa5ce8f..0c3db57a50f 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -84,37 +84,16 @@ static int i_ADDI_Reset(struct comedi_device *dev)
return 0;
}
-static const void *addi_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const void *p = dev->driver->board_name;
- const struct addi_board *this_board;
- int i;
-
- for (i = 0; i < dev->driver->num_names; i++) {
- this_board = p;
- if (this_board->i_VendorId == pcidev->vendor &&
- this_board->i_DeviceId == pcidev->device)
- return this_board;
- p += dev->driver->offset;
- }
- return NULL;
-}
-
static int addi_auto_attach(struct comedi_device *dev,
unsigned long context_unused)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct addi_board *this_board;
+ const struct addi_board *this_board = comedi_board(dev);
struct addi_private *devpriv;
struct comedi_subdevice *s;
int ret, n_subdevices;
unsigned int dw_Dummy;
- this_board = addi_find_boardinfo(dev, pcidev);
- if (!this_board)
- return -ENODEV;
- dev->board_ptr = this_board;
dev->board_name = this_board->pc_DriverName;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
@@ -122,7 +101,7 @@ static int addi_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -141,8 +120,7 @@ static int addi_auto_attach(struct comedi_device *dev,
/* board has an ADDIDATA_9054 eeprom */
dev->iobase = pci_resource_start(pcidev, 2);
devpriv->iobase = pci_resource_start(pcidev, 2);
- devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3),
- this_board->i_IorangeBase3);
+ devpriv->dw_AiBase = pci_ioremap_bar(pcidev, 3);
}
devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
@@ -338,7 +316,6 @@ static int addi_auto_attach(struct comedi_device *dev,
static void i_ADDI_Detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct addi_private *devpriv = dev->private;
if (devpriv) {
@@ -349,8 +326,5 @@ static void i_ADDI_Detach(struct comedi_device *dev)
if (devpriv->dw_AiBase)
iounmap(devpriv->dw_AiBase);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index 6d8b29f945d..c034bf1426e 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -45,12 +45,7 @@
/* structure for the boardtype */
struct addi_board {
const char *pc_DriverName; /* driver name */
- int i_VendorId; /* PCI vendor a device ID of card */
- int i_DeviceId;
- int i_IorangeBase0;
int i_IorangeBase1;
- int i_IorangeBase2; /* base 2 range */
- int i_IorangeBase3; /* base 3 range */
int i_PCIEeprom; /* eeprom present or not */
char *pc_EepromChip; /* type of chip */
int i_NbrAiChannel; /* num of A/D chans */
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
index 5a53e58258a..43c2c10a7c3 100644
--- a/drivers/staging/comedi/drivers/addi_apci_035.c
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -15,9 +15,6 @@
static const struct addi_board apci035_boardtypes[] = {
{
.pc_DriverName = "apci035",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x0300,
- .i_IorangeBase0 = 127,
.i_IorangeBase1 = APCI035_ADDRESS_RANGE,
.i_PCIEeprom = 1,
.pc_EepromChip = ADDIDATA_S5920,
@@ -39,20 +36,25 @@ static const struct addi_board apci035_boardtypes[] = {
},
};
+static int apci035_auto_attach(struct comedi_device *dev,
+ unsigned long context)
+{
+ dev->board_ptr = &apci035_boardtypes[0];
+
+ return addi_auto_attach(dev, context);
+}
+
static struct comedi_driver apci035_driver = {
.driver_name = "addi_apci_035",
.module = THIS_MODULE,
- .auto_attach = addi_auto_attach,
+ .auto_attach = apci035_auto_attach,
.detach = i_ADDI_Detach,
- .num_names = ARRAY_SIZE(apci035_boardtypes),
- .board_name = &apci035_boardtypes[0].pc_DriverName,
- .offset = sizeof(struct addi_board),
};
static int apci035_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci035_driver);
+ return comedi_pci_auto_config(dev, &apci035_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
index c0d0429c35c..3d4878facc2 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -296,14 +296,12 @@ static int apci1032_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -353,16 +351,11 @@ static int apci1032_auto_attach(struct comedi_device *dev,
static void apci1032_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
apci1032_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci1032_driver = {
@@ -373,9 +366,9 @@ static struct comedi_driver apci1032_driver = {
};
static int apci1032_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci1032_driver);
+ return comedi_pci_auto_config(dev, &apci1032_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index 9c2f8eeb797..b52cfe01e6c 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -13,11 +13,7 @@
static const struct addi_board apci1500_boardtypes[] = {
{
.pc_DriverName = "apci1500",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
- .i_DeviceId = 0x80fc,
- .i_IorangeBase0 = 128,
.i_IorangeBase1 = APCI1500_ADDRESS_RANGE,
- .i_IorangeBase2 = 4,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.i_NbrDiChannel = 16,
.i_NbrDoChannel = 16,
@@ -39,24 +35,29 @@ static const struct addi_board apci1500_boardtypes[] = {
},
};
+static int apci1500_auto_attach(struct comedi_device *dev,
+ unsigned long context)
+{
+ dev->board_ptr = &apci1500_boardtypes[0];
+
+ return addi_auto_attach(dev, context);
+}
+
static struct comedi_driver apci1500_driver = {
.driver_name = "addi_apci_1500",
.module = THIS_MODULE,
- .auto_attach = addi_auto_attach,
+ .auto_attach = apci1500_auto_attach,
.detach = i_ADDI_Detach,
- .num_names = ARRAY_SIZE(apci1500_boardtypes),
- .board_name = &apci1500_boardtypes[0].pc_DriverName,
- .offset = sizeof(struct addi_board),
};
static int apci1500_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci1500_driver);
+ return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci1500_pci_table);
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
index 69e39963841..ed01c56630b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1516.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -36,13 +36,6 @@
#include "comedi_fc.h"
/*
- * PCI device ids supported by this driver
- */
-#define PCI_DEVICE_ID_APCI1016 0x1000
-#define PCI_DEVICE_ID_APCI1516 0x1001
-#define PCI_DEVICE_ID_APCI2016 0x1002
-
-/*
* PCI bar 1 I/O Register map - Digital input/output
*/
#define APCI1516_DI_REG 0x00
@@ -53,28 +46,32 @@
*/
#define APCI1516_WDOG_REG 0x00
+enum apci1516_boardid {
+ BOARD_APCI1016,
+ BOARD_APCI1516,
+ BOARD_APCI2016,
+};
+
struct apci1516_boardinfo {
const char *name;
- unsigned short device;
int di_nchan;
int do_nchan;
int has_wdog;
};
static const struct apci1516_boardinfo apci1516_boardtypes[] = {
- {
+ [BOARD_APCI1016] = {
.name = "apci1016",
- .device = PCI_DEVICE_ID_APCI1016,
.di_nchan = 16,
- }, {
+ },
+ [BOARD_APCI1516] = {
.name = "apci1516",
- .device = PCI_DEVICE_ID_APCI1516,
.di_nchan = 8,
.do_nchan = 8,
.has_wdog = 1,
- }, {
+ },
+ [BOARD_APCI2016] = {
.name = "apci2016",
- .device = PCI_DEVICE_ID_APCI2016,
.do_nchan = 16,
.has_wdog = 1,
},
@@ -130,30 +127,17 @@ static int apci1516_reset(struct comedi_device *dev)
return 0;
}
-static const void *apci1516_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct apci1516_boardinfo *this_board;
- int i;
-
- for (i = 0; i < dev->driver->num_names; i++) {
- this_board = &apci1516_boardtypes[i];
- if (this_board->device == pcidev->device)
- return this_board;
- }
- return NULL;
-}
-
static int apci1516_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct apci1516_boardinfo *this_board;
+ const struct apci1516_boardinfo *this_board = NULL;
struct apci1516_private *devpriv;
struct comedi_subdevice *s;
int ret;
- this_board = apci1516_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(apci1516_boardtypes))
+ this_board = &apci1516_boardtypes[context];
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
@@ -164,7 +148,7 @@ static int apci1516_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -217,14 +201,10 @@ static int apci1516_auto_attach(struct comedi_device *dev,
static void apci1516_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
apci1516_reset(dev);
- if (dev->subdevices)
- addi_watchdog_cleanup(&dev->subdevices[2]);
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ comedi_spriv_free(dev, 2);
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci1516_driver = {
@@ -235,15 +215,15 @@ static struct comedi_driver apci1516_driver = {
};
static int apci1516_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci1516_driver);
+ return comedi_pci_auto_config(dev, &apci1516_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1016) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1516) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI2016) },
+ { PCI_VDEVICE(ADDIDATA, 0x1000), BOARD_APCI1016 },
+ { PCI_VDEVICE(ADDIDATA, 0x1001), BOARD_APCI1516 },
+ { PCI_VDEVICE(ADDIDATA, 0x1002), BOARD_APCI2016 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci1516_pci_table);
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index ddea64df918..22bace62210 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -13,9 +13,6 @@
static const struct addi_board apci1564_boardtypes[] = {
{
.pc_DriverName = "apci1564",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x1006,
- .i_IorangeBase0 = 128,
.i_IorangeBase1 = APCI1564_ADDRESS_RANGE,
.i_PCIEeprom = ADDIDATA_EEPROM,
.pc_EepromChip = ADDIDATA_93C76,
@@ -36,20 +33,25 @@ static const struct addi_board apci1564_boardtypes[] = {
},
};
+static int apci1564_auto_attach(struct comedi_device *dev,
+ unsigned long context)
+{
+ dev->board_ptr = &apci1564_boardtypes[0];
+
+ return addi_auto_attach(dev, context);
+}
+
static struct comedi_driver apci1564_driver = {
.driver_name = "addi_apci_1564",
.module = THIS_MODULE,
- .auto_attach = addi_auto_attach,
+ .auto_attach = apci1564_auto_attach,
.detach = i_ADDI_Detach,
- .num_names = ARRAY_SIZE(apci1564_boardtypes),
- .board_name = &apci1564_boardtypes[0].pc_DriverName,
- .offset = sizeof(struct addi_board),
};
static int apci1564_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci1564_driver);
+ return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci1564_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
index e51f8000136..4c6a9b5a06a 100644
--- a/drivers/staging/comedi/drivers/addi_apci_16xx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c
@@ -34,35 +34,29 @@
#include "../comedidev.h"
/*
- * PCI device ids supported by this driver
- */
-#define PCI_DEVICE_ID_APCI1648 0x1009
-#define PCI_DEVICE_ID_APCI1696 0x100a
-
-/*
* Register I/O map
*/
#define APCI16XX_IN_REG(x) (((x) * 4) + 0x08)
#define APCI16XX_OUT_REG(x) (((x) * 4) + 0x14)
#define APCI16XX_DIR_REG(x) (((x) * 4) + 0x20)
+enum apci16xx_boardid {
+ BOARD_APCI1648,
+ BOARD_APCI1696,
+};
+
struct apci16xx_boardinfo {
const char *name;
- unsigned short vendor;
- unsigned short device;
int n_chan;
};
static const struct apci16xx_boardinfo apci16xx_boardtypes[] = {
- {
+ [BOARD_APCI1648] = {
.name = "apci1648",
- .vendor = PCI_VENDOR_ID_ADDIDATA,
- .device = PCI_DEVICE_ID_APCI1648,
.n_chan = 48, /* 2 subdevices */
- }, {
+ },
+ [BOARD_APCI1696] = {
.name = "apci1696",
- .vendor = PCI_VENDOR_ID_ADDIDATA,
- .device = PCI_DEVICE_ID_APCI1696,
.n_chan = 96, /* 3 subdevices */
},
};
@@ -130,39 +124,25 @@ static int apci16xx_dio_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static const void *apci16xx_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct apci16xx_boardinfo *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(apci16xx_boardtypes); i++) {
- board = &apci16xx_boardtypes[i];
- if (board->vendor == pcidev->vendor &&
- board->device == pcidev->device)
- return board;
- }
- return NULL;
-}
-
static int apci16xx_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct apci16xx_boardinfo *board;
+ const struct apci16xx_boardinfo *board = NULL;
struct comedi_subdevice *s;
unsigned int n_subdevs;
unsigned int last;
int i;
int ret;
- board = apci16xx_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(apci16xx_boardtypes))
+ board = &apci16xx_boardtypes[context];
if (!board)
return -ENODEV;
dev->board_ptr = board;
dev->board_name = board->name;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -204,35 +184,22 @@ static int apci16xx_auto_attach(struct comedi_device *dev,
return 0;
}
-static void apci16xx_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
-}
-
static struct comedi_driver apci16xx_driver = {
.driver_name = "addi_apci_16xx",
.module = THIS_MODULE,
.auto_attach = apci16xx_auto_attach,
- .detach = apci16xx_detach,
- .num_names = ARRAY_SIZE(apci16xx_boardtypes),
- .board_name = &apci16xx_boardtypes[0].name,
- .offset = sizeof(struct apci16xx_boardinfo),
+ .detach = comedi_pci_disable,
};
static int apci16xx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci16xx_driver);
+ return comedi_pci_auto_config(dev, &apci16xx_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1648) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1696) },
+ { PCI_VDEVICE(ADDIDATA, 0x1009), BOARD_APCI1648 },
+ { PCI_VDEVICE(ADDIDATA, 0x100a), BOARD_APCI1696 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci16xx_pci_table);
diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c
index e83e829831b..c9e6471eb06 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1710.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1710.c
@@ -21,72 +21,29 @@ static void fpu_end(void)
#include "addi-data/addi_eeprom.c"
#include "addi-data/hwdrv_APCI1710.c"
-static const struct addi_board apci1710_boardtypes[] = {
- {
- .pc_DriverName = "apci1710",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
- .i_DeviceId = APCI1710_BOARD_DEVICE_ID,
- .interrupt = v_APCI1710_Interrupt,
- },
-};
-
static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
{
- struct comedi_device *dev = d;
- const struct addi_board *this_board = comedi_board(dev);
-
- this_board->interrupt(irq, d);
+ v_APCI1710_Interrupt(irq, d);
return IRQ_RETVAL(1);
}
-static const void *apci1710_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct addi_board *this_board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(apci1710_boardtypes); i++) {
- this_board = &apci1710_boardtypes[i];
- if (this_board->i_VendorId == pcidev->vendor &&
- this_board->i_DeviceId == pcidev->device)
- return this_board;
- }
- return NULL;
-}
-
static int apci1710_auto_attach(struct comedi_device *dev,
unsigned long context_unused)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct addi_board *this_board;
struct addi_private *devpriv;
struct comedi_subdevice *s;
int ret;
- this_board = apci1710_find_boardinfo(dev, pcidev);
- if (!this_board)
- return -ENODEV;
- dev->board_ptr = this_board;
- dev->board_name = this_board->pc_DriverName;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
-
- if (this_board->i_IorangeBase1)
- dev->iobase = pci_resource_start(pcidev, 1);
- else
- dev->iobase = pci_resource_start(pcidev, 0);
-
- devpriv->iobase = dev->iobase;
- devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
- devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
- devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
+ devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2);
if (pcidev->irq > 0) {
ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
@@ -97,24 +54,17 @@ static int apci1710_auto_attach(struct comedi_device *dev,
i_ADDI_AttachPCI1710(dev);
- devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2);
-
i_APCI1710_Reset(dev);
return 0;
}
static void apci1710_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
i_APCI1710_Reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci1710_driver = {
@@ -125,13 +75,13 @@ static struct comedi_driver apci1710_driver = {
};
static int apci1710_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci1710_driver);
+ return comedi_pci_auto_config(dev, &apci1710_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci1710_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMCC, APCI1710_BOARD_DEVICE_ID) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci1710_pci_table);
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
index 9ce1d26aff2..b666637f61b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -287,9 +287,7 @@ static int apci2032_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 1);
@@ -350,20 +348,14 @@ static int apci2032_auto_attach(struct comedi_device *dev,
static void apci2032_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
apci2032_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
if (dev->read_subdev)
kfree(dev->read_subdev->private);
- if (dev->subdevices)
- addi_watchdog_cleanup(&dev->subdevices[1]);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_spriv_free(dev, 1);
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci2032_driver = {
@@ -374,9 +366,9 @@ static struct comedi_driver apci2032_driver = {
};
static int apci2032_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci2032_driver);
+ return comedi_pci_auto_config(dev, &apci2032_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
index b1c4226902e..1cdc08d7979 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -88,9 +88,7 @@ static int apci2200_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -130,16 +128,10 @@ static int apci2200_auto_attach(struct comedi_device *dev,
static void apci2200_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
apci2200_reset(dev);
- if (dev->subdevices)
- addi_watchdog_cleanup(&dev->subdevices[2]);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_spriv_free(dev, 2);
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci2200_driver = {
@@ -150,9 +142,9 @@ static struct comedi_driver apci2200_driver = {
};
static int apci2200_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci2200_driver);
+ return comedi_pci_auto_config(dev, &apci2200_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci2200_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index 917234d24e9..317a26d97c2 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -8,11 +8,14 @@
#include "addi-data/hwdrv_apci3120.c"
+enum apci3120_boardid {
+ BOARD_APCI3120,
+ BOARD_APCI3001,
+};
+
static const struct addi_board apci3120_boardtypes[] = {
- {
+ [BOARD_APCI3120] = {
.pc_DriverName = "apci3120",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
- .i_DeviceId = 0x818D,
.i_NbrAiChannel = 16,
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 16,
@@ -23,10 +26,9 @@ static const struct addi_board apci3120_boardtypes[] = {
.i_NbrDoChannel = 4,
.i_DoMaxdata = 0x0f,
.interrupt = v_APCI3120_Interrupt,
- }, {
+ },
+ [BOARD_APCI3001] = {
.pc_DriverName = "apci3001",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD,
- .i_DeviceId = 0x828D,
.i_NbrAiChannel = 16,
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 16,
@@ -47,31 +49,17 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
return IRQ_RETVAL(1);
}
-static const void *apci3120_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct addi_board *this_board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(apci3120_boardtypes); i++) {
- this_board = &apci3120_boardtypes[i];
- if (this_board->i_VendorId == pcidev->vendor &&
- this_board->i_DeviceId == pcidev->device)
- return this_board;
- }
- return NULL;
-}
-
static int apci3120_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct addi_board *this_board;
+ const struct addi_board *this_board = NULL;
struct addi_private *devpriv;
struct comedi_subdevice *s;
int ret, pages, i;
- this_board = apci3120_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(apci3120_boardtypes))
+ this_board = &apci3120_boardtypes[context];
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
@@ -82,7 +70,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
pci_set_master(pcidev);
@@ -215,7 +203,6 @@ static int apci3120_auto_attach(struct comedi_device *dev,
static void apci3120_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct addi_private *devpriv = dev->private;
if (devpriv) {
@@ -234,10 +221,7 @@ static void apci3120_detach(struct comedi_device *dev)
devpriv->ui_DmaBufferPages[1]);
}
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci3120_driver = {
@@ -248,14 +232,14 @@ static struct comedi_driver apci3120_driver = {
};
static int apci3120_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci3120_driver);
+ return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) },
+ { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
+ { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
index 90ee4f844f9..17b540d3c6a 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -22,15 +22,15 @@ static void fpu_end(void)
#include "addi-data/hwdrv_apci3200.c"
#include "addi-data/addi_common.c"
+enum apci3200_boardid {
+ BOARD_APCI3200,
+ BOARD_APCI3300,
+};
+
static const struct addi_board apci3200_boardtypes[] = {
- {
+ [BOARD_APCI3200] = {
.pc_DriverName = "apci3200",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3000,
- .i_IorangeBase0 = 128,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 4,
- .i_IorangeBase3 = 4,
.i_PCIEeprom = ADDIDATA_EEPROM,
.pc_EepromChip = ADDIDATA_S5920,
.i_NbrAiChannel = 16,
@@ -53,14 +53,10 @@ static const struct addi_board apci3200_boardtypes[] = {
.ai_cancel = i_APCI3200_StopCyclicAcquisition,
.di_bits = apci3200_di_insn_bits,
.do_bits = apci3200_do_insn_bits,
- }, {
+ },
+ [BOARD_APCI3300] = {
.pc_DriverName = "apci3300",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3007,
- .i_IorangeBase0 = 128,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 4,
- .i_IorangeBase3 = 4,
.i_PCIEeprom = ADDIDATA_EEPROM,
.pc_EepromChip = ADDIDATA_S5920,
.i_NbrAiChannelDiff = 8,
@@ -85,29 +81,40 @@ static const struct addi_board apci3200_boardtypes[] = {
},
};
-static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, apci3200_pci_table);
+static int apci3200_auto_attach(struct comedi_device *dev,
+ unsigned long context)
+{
+ const struct addi_board *board = NULL;
+
+ if (context < ARRAY_SIZE(apci3200_boardtypes))
+ board = &apci3200_boardtypes[context];
+ if (!board)
+ return -ENODEV;
+ dev->board_ptr = board;
+
+ return addi_auto_attach(dev, context);
+}
static struct comedi_driver apci3200_driver = {
.driver_name = "addi_apci_3200",
.module = THIS_MODULE,
- .auto_attach = addi_auto_attach,
+ .auto_attach = apci3200_auto_attach,
.detach = i_ADDI_Detach,
- .num_names = ARRAY_SIZE(apci3200_boardtypes),
- .board_name = &apci3200_boardtypes[0].pc_DriverName,
- .offset = sizeof(struct addi_board),
};
static int apci3200_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci3200_driver);
+ return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data);
}
+static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = {
+ { PCI_VDEVICE(ADDIDATA, 0x3000), BOARD_APCI3200 },
+ { PCI_VDEVICE(ADDIDATA, 0x3007), BOARD_APCI3300 },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, apci3200_pci_table);
+
static struct pci_driver apci3200_pci_driver = {
.name = "addi_apci_3200",
.id_table = apci3200_pci_table,
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index 786fcaf82c3..a0cf6ecdef0 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -339,14 +339,12 @@ static int apci3501_auto_attach(struct comedi_device *dev,
int ao_n_chan;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -423,16 +421,11 @@ static int apci3501_auto_attach(struct comedi_device *dev,
static void apci3501_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
apci3501_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver apci3501_driver = {
@@ -443,9 +436,9 @@ static struct comedi_driver apci3501_driver = {
};
static int apci3501_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci3501_driver);
+ return comedi_pci_auto_config(dev, &apci3501_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index 09d4b21fce2..ec4d6ca6863 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -10,15 +10,38 @@
#include "addi-data/hwdrv_apci3xxx.c"
#include "addi-data/addi_common.c"
+enum apci3xxx_boardid {
+ BOARD_APCI3000_16,
+ BOARD_APCI3000_8,
+ BOARD_APCI3000_4,
+ BOARD_APCI3006_16,
+ BOARD_APCI3006_8,
+ BOARD_APCI3006_4,
+ BOARD_APCI3010_16,
+ BOARD_APCI3010_8,
+ BOARD_APCI3010_4,
+ BOARD_APCI3016_16,
+ BOARD_APCI3016_8,
+ BOARD_APCI3016_4,
+ BOARD_APCI3100_16_4,
+ BOARD_APCI3100_8_4,
+ BOARD_APCI3106_16_4,
+ BOARD_APCI3106_8_4,
+ BOARD_APCI3110_16_4,
+ BOARD_APCI3110_8_4,
+ BOARD_APCI3116_16_4,
+ BOARD_APCI3116_8_4,
+ BOARD_APCI3003,
+ BOARD_APCI3002_16,
+ BOARD_APCI3002_8,
+ BOARD_APCI3002_4,
+ BOARD_APCI3500,
+};
+
static const struct addi_board apci3xxx_boardtypes[] = {
- {
+ [BOARD_APCI3000_16] = {
.pc_DriverName = "apci3000-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3010,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -37,14 +60,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3000_8] = {
.pc_DriverName = "apci3000-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x300F,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -63,14 +82,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3000_4] = {
.pc_DriverName = "apci3000-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x300E,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 4,
@@ -89,14 +104,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3006_16] = {
.pc_DriverName = "apci3006-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3013,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -115,14 +126,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3006_8] = {
.pc_DriverName = "apci3006-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3014,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -141,14 +148,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3006_4] = {
.pc_DriverName = "apci3006-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3015,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 4,
@@ -167,14 +170,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3010_16] = {
.pc_DriverName = "apci3010-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3016,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -198,14 +197,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3010_8] = {
.pc_DriverName = "apci3010-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3017,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -229,14 +224,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3010_4] = {
.pc_DriverName = "apci3010-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3018,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 4,
@@ -260,14 +251,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3016_16] = {
.pc_DriverName = "apci3016-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3019,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -291,14 +278,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3016_8] = {
.pc_DriverName = "apci3016-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301A,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -322,14 +305,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3016_4] = {
.pc_DriverName = "apci3016-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301B,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 4,
@@ -353,14 +332,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3100_16_4] = {
.pc_DriverName = "apci3100-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301C,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -383,14 +358,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3100_8_4] = {
.pc_DriverName = "apci3100-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301D,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -413,14 +384,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3106_16_4] = {
.pc_DriverName = "apci3106-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301E,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -443,14 +410,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3106_8_4] = {
.pc_DriverName = "apci3106-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x301F,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -473,14 +436,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3110_16_4] = {
.pc_DriverName = "apci3110-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3020,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -508,14 +467,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3110_8_4] = {
.pc_DriverName = "apci3110-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3021,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -543,14 +498,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3116_16_4] = {
.pc_DriverName = "apci3116-16-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3022,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 16,
@@ -578,14 +529,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3116_8_4] = {
.pc_DriverName = "apci3116-8-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3023,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannel = 8,
@@ -613,14 +560,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ttl_bits = i_APCI3XXX_InsnBitsTTLIO,
.ttl_read = i_APCI3XXX_InsnReadTTLIO,
.ttl_write = i_APCI3XXX_InsnWriteTTLIO,
- }, {
+ },
+ [BOARD_APCI3003] = {
.pc_DriverName = "apci3003",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x300B,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannelDiff = 4,
@@ -638,14 +581,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_bits = apci3xxx_do_insn_bits,
- }, {
+ },
+ [BOARD_APCI3002_16] = {
.pc_DriverName = "apci3002-16",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3002,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannelDiff = 16,
@@ -663,14 +602,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_bits = apci3xxx_do_insn_bits,
- }, {
+ },
+ [BOARD_APCI3002_8] = {
.pc_DriverName = "apci3002-8",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3003,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannelDiff = 8,
@@ -688,14 +623,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_bits = apci3xxx_do_insn_bits,
- }, {
+ },
+ [BOARD_APCI3002_4] = {
.pc_DriverName = "apci3002-4",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3004,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAiChannelDiff = 4,
@@ -713,14 +644,10 @@ static const struct addi_board apci3xxx_boardtypes[] = {
.ai_read = i_APCI3XXX_InsnReadAnalogInput,
.di_bits = apci3xxx_di_insn_bits,
.do_bits = apci3xxx_do_insn_bits,
- }, {
+ },
+ [BOARD_APCI3500] = {
.pc_DriverName = "apci3500",
- .i_VendorId = PCI_VENDOR_ID_ADDIDATA,
- .i_DeviceId = 0x3024,
- .i_IorangeBase0 = 256,
.i_IorangeBase1 = 256,
- .i_IorangeBase2 = 256,
- .i_IorangeBase3 = 256,
.i_PCIEeprom = ADDIDATA_NO_EEPROM,
.pc_EepromChip = ADDIDATA_9054,
.i_NbrAoChannel = 4,
@@ -737,48 +664,59 @@ static const struct addi_board apci3xxx_boardtypes[] = {
},
};
+static int apci3xxx_auto_attach(struct comedi_device *dev,
+ unsigned long context)
+{
+ const struct addi_board *board = NULL;
+
+ if (context < ARRAY_SIZE(apci3xxx_boardtypes))
+ board = &apci3xxx_boardtypes[context];
+ if (!board)
+ return -ENODEV;
+ dev->board_ptr = board;
+
+ return addi_auto_attach(dev, context);
+}
+
static struct comedi_driver apci3xxx_driver = {
.driver_name = "addi_apci_3xxx",
.module = THIS_MODULE,
- .auto_attach = addi_auto_attach,
+ .auto_attach = apci3xxx_auto_attach,
.detach = i_ADDI_Detach,
- .num_names = ARRAY_SIZE(apci3xxx_boardtypes),
- .board_name = &apci3xxx_boardtypes[0].pc_DriverName,
- .offset = sizeof(struct addi_board),
};
static int apci3xxx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &apci3xxx_driver);
+ return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300e) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301a) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301b) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301c) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301d) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301e) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301f) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024) },
+ { PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 },
+ { PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 },
+ { PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3013), BOARD_APCI3006_16 },
+ { PCI_VDEVICE(ADDIDATA, 0x3014), BOARD_APCI3006_8 },
+ { PCI_VDEVICE(ADDIDATA, 0x3015), BOARD_APCI3006_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3016), BOARD_APCI3010_16 },
+ { PCI_VDEVICE(ADDIDATA, 0x3017), BOARD_APCI3010_8 },
+ { PCI_VDEVICE(ADDIDATA, 0x3018), BOARD_APCI3010_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3019), BOARD_APCI3016_16 },
+ { PCI_VDEVICE(ADDIDATA, 0x301a), BOARD_APCI3016_8 },
+ { PCI_VDEVICE(ADDIDATA, 0x301b), BOARD_APCI3016_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x301c), BOARD_APCI3100_16_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x301d), BOARD_APCI3100_8_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x301e), BOARD_APCI3106_16_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x301f), BOARD_APCI3106_8_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3020), BOARD_APCI3110_16_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3021), BOARD_APCI3110_8_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3022), BOARD_APCI3116_16_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3023), BOARD_APCI3116_8_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x300B), BOARD_APCI3003 },
+ { PCI_VDEVICE(ADDIDATA, 0x3002), BOARD_APCI3002_16 },
+ { PCI_VDEVICE(ADDIDATA, 0x3003), BOARD_APCI3002_8 },
+ { PCI_VDEVICE(ADDIDATA, 0x3004), BOARD_APCI3002_4 },
+ { PCI_VDEVICE(ADDIDATA, 0x3024), BOARD_APCI3500 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci3xxx_pci_table);
diff --git a/drivers/staging/comedi/drivers/addi_watchdog.c b/drivers/staging/comedi/drivers/addi_watchdog.c
index 375ab665e09..1666b5f510d 100644
--- a/drivers/staging/comedi/drivers/addi_watchdog.c
+++ b/drivers/staging/comedi/drivers/addi_watchdog.c
@@ -150,12 +150,6 @@ int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase)
}
EXPORT_SYMBOL_GPL(addi_watchdog_init);
-void addi_watchdog_cleanup(struct comedi_subdevice *s)
-{
- kfree(s->private);
-}
-EXPORT_SYMBOL_GPL(addi_watchdog_cleanup);
-
static int __init addi_watchdog_module_init(void)
{
return 0;
diff --git a/drivers/staging/comedi/drivers/addi_watchdog.h b/drivers/staging/comedi/drivers/addi_watchdog.h
index f374a7bff44..83b47befa4d 100644
--- a/drivers/staging/comedi/drivers/addi_watchdog.h
+++ b/drivers/staging/comedi/drivers/addi_watchdog.h
@@ -5,6 +5,5 @@
void addi_watchdog_reset(unsigned long iobase);
int addi_watchdog_init(struct comedi_subdevice *, unsigned long iobase);
-void addi_watchdog_cleanup(struct comedi_subdevice *s);
#endif
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index 7b3e331616e..8a438ff1bd4 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -47,12 +47,6 @@ References:
#include "../comedidev.h"
/*
- * ADLINK PCI Device ID's supported by this driver
- */
-#define PCI_DEVICE_ID_PCI6208 0x6208
-#define PCI_DEVICE_ID_PCI6216 0x6216
-
-/*
* PCI-6208/6216-GL register map
*/
#define PCI6208_AO_CONTROL(x) (0x00 + (2 * (x)))
@@ -66,20 +60,23 @@ References:
#define PCI6208_MAX_AO_CHANNELS 16
+enum pci6208_boardid {
+ BOARD_PCI6208,
+ BOARD_PCI6216,
+};
+
struct pci6208_board {
const char *name;
- unsigned short dev_id;
int ao_chans;
};
static const struct pci6208_board pci6208_boards[] = {
- {
+ [BOARD_PCI6208] = {
.name = "adl_pci6208",
- .dev_id = PCI_DEVICE_ID_PCI6208,
.ao_chans = 8,
- }, {
+ },
+ [BOARD_PCI6216] = {
.name = "adl_pci6216",
- .dev_id = PCI_DEVICE_ID_PCI6216,
.ao_chans = 16,
},
};
@@ -162,31 +159,18 @@ static int pci6208_do_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static const void *pci6208_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct pci6208_board *boardinfo;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) {
- boardinfo = &pci6208_boards[i];
- if (boardinfo->dev_id == pcidev->device)
- return boardinfo;
- }
- return NULL;
-}
-
static int pci6208_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct pci6208_board *boardinfo;
+ const struct pci6208_board *boardinfo = NULL;
struct pci6208_private *devpriv;
struct comedi_subdevice *s;
unsigned int val;
int ret;
- boardinfo = pci6208_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(pci6208_boards))
+ boardinfo = &pci6208_boards[context];
if (!boardinfo)
return -ENODEV;
dev->board_ptr = boardinfo;
@@ -197,7 +181,7 @@ static int pci6208_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
@@ -249,32 +233,23 @@ static int pci6208_auto_attach(struct comedi_device *dev,
return 0;
}
-static void pci6208_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
-}
-
static struct comedi_driver adl_pci6208_driver = {
.driver_name = "adl_pci6208",
.module = THIS_MODULE,
.auto_attach = pci6208_auto_attach,
- .detach = pci6208_detach,
+ .detach = comedi_pci_disable,
};
static int adl_pci6208_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adl_pci6208_driver);
+ return comedi_pci_auto_config(dev, &adl_pci6208_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI6208) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI6216) },
+ { PCI_VDEVICE(ADLINK, 0x6208), BOARD_PCI6208 },
+ { PCI_VDEVICE(ADLINK, 0x6216), BOARD_PCI6216 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c
index f27f48e6e70..e3960745f50 100644
--- a/drivers/staging/comedi/drivers/adl_pci7x3x.c
+++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c
@@ -53,60 +53,57 @@ Configuration Options: not applicable, uses comedi PCI auto config
#include "../comedidev.h"
/*
- * PCI Device ID's supported by this driver
- */
-#define PCI_DEVICE_ID_PCI7230 0x7230
-#define PCI_DEVICE_ID_PCI7233 0x7233
-#define PCI_DEVICE_ID_PCI7234 0x7234
-#define PCI_DEVICE_ID_PCI7432 0x7432
-#define PCI_DEVICE_ID_PCI7433 0x7433
-#define PCI_DEVICE_ID_PCI7434 0x7434
-
-/*
* Register I/O map (32-bit access only)
*/
#define PCI7X3X_DIO_REG 0x00
#define PCI743X_DIO_REG 0x04
+enum apci1516_boardid {
+ BOARD_PCI7230,
+ BOARD_PCI7233,
+ BOARD_PCI7234,
+ BOARD_PCI7432,
+ BOARD_PCI7433,
+ BOARD_PCI7434,
+};
+
struct adl_pci7x3x_boardinfo {
const char *name;
- unsigned short device;
int nsubdevs;
int di_nchan;
int do_nchan;
};
static const struct adl_pci7x3x_boardinfo adl_pci7x3x_boards[] = {
- {
+ [BOARD_PCI7230] = {
.name = "adl_pci7230",
- .device = PCI_DEVICE_ID_PCI7230,
.nsubdevs = 2,
.di_nchan = 16,
.do_nchan = 16,
- }, {
+ },
+ [BOARD_PCI7233] = {
.name = "adl_pci7233",
- .device = PCI_DEVICE_ID_PCI7233,
.nsubdevs = 1,
.di_nchan = 32,
- }, {
+ },
+ [BOARD_PCI7234] = {
.name = "adl_pci7234",
- .device = PCI_DEVICE_ID_PCI7234,
.nsubdevs = 1,
.do_nchan = 32,
- }, {
+ },
+ [BOARD_PCI7432] = {
.name = "adl_pci7432",
- .device = PCI_DEVICE_ID_PCI7432,
.nsubdevs = 2,
.di_nchan = 32,
.do_nchan = 32,
- }, {
+ },
+ [BOARD_PCI7433] = {
.name = "adl_pci7433",
- .device = PCI_DEVICE_ID_PCI7433,
.nsubdevs = 2,
.di_nchan = 64,
- }, {
+ },
+ [BOARD_PCI7434] = {
.name = "adl_pci7434",
- .device = PCI_DEVICE_ID_PCI7434,
.nsubdevs = 2,
.do_nchan = 64,
}
@@ -150,37 +147,24 @@ static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct adl_pci7x3x_boardinfo *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(adl_pci7x3x_boards); i++) {
- board = &adl_pci7x3x_boards[i];
- if (pcidev->device == board->device)
- return board;
- }
- return NULL;
-}
-
static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct adl_pci7x3x_boardinfo *board;
+ const struct adl_pci7x3x_boardinfo *board = NULL;
struct comedi_subdevice *s;
int subdev;
int nchan;
int ret;
- board = adl_pci7x3x_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(adl_pci7x3x_boards))
+ board = &adl_pci7x3x_boards[context];
if (!board)
return -ENODEV;
dev->board_ptr = board;
dev->board_name = board->name;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
@@ -275,36 +259,27 @@ static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
return 0;
}
-static void adl_pci7x3x_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
-}
-
static struct comedi_driver adl_pci7x3x_driver = {
.driver_name = "adl_pci7x3x",
.module = THIS_MODULE,
.auto_attach = adl_pci7x3x_auto_attach,
- .detach = adl_pci7x3x_detach,
+ .detach = comedi_pci_disable,
};
static int adl_pci7x3x_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adl_pci7x3x_driver);
+ return comedi_pci_auto_config(dev, &adl_pci7x3x_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(adl_pci7x3x_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7233) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7234) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7433) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7434) },
+ { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 },
+ { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 },
+ { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 },
+ { PCI_VDEVICE(ADLINK, 0x7432), BOARD_PCI7432 },
+ { PCI_VDEVICE(ADLINK, 0x7433), BOARD_PCI7433 },
+ { PCI_VDEVICE(ADLINK, 0x7434), BOARD_PCI7434 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, adl_pci7x3x_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index d06b83f3865..b3ec60afe3a 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -1,217 +1,74 @@
/*
- comedi/drivers/adl_pci8164.c
-
- Hardware comedi driver fot PCI-8164 Adlink card
- Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
-
- 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.
+ * comedi/drivers/adl_pci8164.c
+ *
+ * Hardware comedi driver for PCI-8164 Adlink card
+ * Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+ *
+ * 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: adl_pci8164
-Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
-Devices: [ADLink] PCI-8164 (adl_pci8164)
-Author: Michel Lachaine <mike@mikelachaine.ca>
-Status: experimental
-Updated: Mon, 14 Apr 2008 15:10:32 +0100
-
-Configuration Options: not applicable, uses PCI auto config
-*/
+ * Driver: adl_pci8164
+ * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
+ * Devices: (ADLink) PCI-8164 [adl_pci8164]
+ * Author: Michel Lachaine <mike@mikelachaine.ca>
+ * Status: experimental
+ * Updated: Mon, 14 Apr 2008 15:10:32 +0100
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ */
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/delay.h>
#include "../comedidev.h"
-#include "comedi_fc.h"
-#include "8253.h"
-
-#define PCI8164_AXIS_X 0x00
-#define PCI8164_AXIS_Y 0x08
-#define PCI8164_AXIS_Z 0x10
-#define PCI8164_AXIS_U 0x18
-#define PCI8164_MSTS 0x00
-#define PCI8164_SSTS 0x02
-#define PCI8164_BUF0 0x04
-#define PCI8164_BUF1 0x06
-
-#define PCI8164_CMD 0x00
-#define PCI8164_OTP 0x02
-
-#define PCI_DEVICE_ID_PCI8164 0x8164
-
-/*
- all the read commands are the same except for the addition a constant
- * const to the data for inw()
- */
-static void adl_pci8164_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data,
- char *action, unsigned short offset)
-{
- int axis, axis_reg;
- char axisname;
-
- axis = CR_CHAN(insn->chanspec);
-
- switch (axis) {
- case 0:
- axis_reg = PCI8164_AXIS_X;
- axisname = 'X';
- break;
- case 1:
- axis_reg = PCI8164_AXIS_Y;
- axisname = 'Y';
- break;
- case 2:
- axis_reg = PCI8164_AXIS_Z;
- axisname = 'Z';
- break;
- case 3:
- axis_reg = PCI8164_AXIS_U;
- axisname = 'U';
- break;
- default:
- axis_reg = PCI8164_AXIS_X;
- axisname = 'X';
- }
-
- data[0] = inw(dev->iobase + axis_reg + offset);
- dev_dbg(dev->class_dev,
- "pci8164 %s read -> %04X:%04X on axis %c\n",
- action, data[0], data[1], axisname);
-}
-
-static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_read(dev, s, insn, data, "MSTS", PCI8164_MSTS);
- return 2;
-}
-
-static int adl_pci8164_insn_read_ssts(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_read(dev, s, insn, data, "SSTS", PCI8164_SSTS);
- return 2;
-}
-
-static int adl_pci8164_insn_read_buf0(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_read(dev, s, insn, data, "BUF0", PCI8164_BUF0);
- return 2;
-}
+#define PCI8164_AXIS(x) ((x) * 0x08)
+#define PCI8164_CMD_MSTS_REG 0x00
+#define PCI8164_OTP_SSTS_REG 0x02
+#define PCI8164_BUF0_REG 0x04
+#define PCI8164_BUF1_REG 0x06
-static int adl_pci8164_insn_read_buf1(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_read(dev, s, insn, data, "BUF1", PCI8164_BUF1);
- return 2;
-}
-
-/*
- all the write commands are the same except for the addition a constant
- * const to the data for outw()
- */
-static void adl_pci8164_insn_out(struct comedi_device *dev,
+static int adl_pci8164_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
- unsigned int *data,
- char *action, unsigned short offset)
+ unsigned int *data)
{
- unsigned int axis, axis_reg;
-
- char axisname;
-
- axis = CR_CHAN(insn->chanspec);
+ unsigned long offset = (unsigned long)s->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
- switch (axis) {
- case 0:
- axis_reg = PCI8164_AXIS_X;
- axisname = 'X';
- break;
- case 1:
- axis_reg = PCI8164_AXIS_Y;
- axisname = 'Y';
- break;
- case 2:
- axis_reg = PCI8164_AXIS_Z;
- axisname = 'Z';
- break;
- case 3:
- axis_reg = PCI8164_AXIS_U;
- axisname = 'U';
- break;
- default:
- axis_reg = PCI8164_AXIS_X;
- axisname = 'X';
- }
-
- outw(data[0], dev->iobase + axis_reg + offset);
-
- dev_dbg(dev->class_dev,
- "pci8164 %s write -> %04X:%04X on axis %c\n",
- action, data[0], data[1], axisname);
+ for (i = 0; i < insn->n; i++)
+ data[i] = inw(dev->iobase + PCI8164_AXIS(chan) + offset);
+ return insn->n;
}
-static int adl_pci8164_insn_write_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_out(dev, s, insn, data, "CMD", PCI8164_CMD);
- return 2;
-}
-
-static int adl_pci8164_insn_write_otp(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int adl_pci8164_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- adl_pci8164_insn_out(dev, s, insn, data, "OTP", PCI8164_OTP);
- return 2;
-}
+ unsigned long offset = (unsigned long)s->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
-static int adl_pci8164_insn_write_buf0(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_out(dev, s, insn, data, "BUF0", PCI8164_BUF0);
- return 2;
-}
+ for (i = 0; i < insn->n; i++)
+ outw(data[i], dev->iobase + PCI8164_AXIS(chan) + offset);
-static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- adl_pci8164_insn_out(dev, s, insn, data, "BUF1", PCI8164_BUF1);
- return 2;
+ return insn->n;
}
static int adl_pci8164_auto_attach(struct comedi_device *dev,
@@ -221,9 +78,7 @@ static int adl_pci8164_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
@@ -232,77 +87,70 @@ static int adl_pci8164_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
+ /* read MSTS register / write CMD register for each axis (channel) */
s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- /* s->range_table = &range_axis; */
- s->insn_read = adl_pci8164_insn_read_msts;
- s->insn_write = adl_pci8164_insn_write_cmd;
-
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ s->insn_read = adl_pci8164_insn_read;
+ s->insn_write = adl_pci8164_insn_write;
+ s->private = (void *)PCI8164_CMD_MSTS_REG;
+
+ /* read SSTS register / write OTP register for each axis (channel) */
s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- /* s->range_table = &range_axis; */
- s->insn_read = adl_pci8164_insn_read_ssts;
- s->insn_write = adl_pci8164_insn_write_otp;
-
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ s->insn_read = adl_pci8164_insn_read;
+ s->insn_write = adl_pci8164_insn_write;
+ s->private = (void *)PCI8164_OTP_SSTS_REG;
+
+ /* read/write BUF0 register for each axis (channel) */
s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- /* s->range_table = &range_axis; */
- s->insn_read = adl_pci8164_insn_read_buf0;
- s->insn_write = adl_pci8164_insn_write_buf0;
-
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ s->insn_read = adl_pci8164_insn_read;
+ s->insn_write = adl_pci8164_insn_write;
+ s->private = (void *)PCI8164_BUF0_REG;
+
+ /* read/write BUF1 register for each axis (channel) */
s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_PROC;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 4;
- s->maxdata = 0xffff;
- s->len_chanlist = 4;
- /* s->range_table = &range_axis; */
- s->insn_read = adl_pci8164_insn_read_buf1;
- s->insn_write = adl_pci8164_insn_write_buf1;
-
- dev_info(dev->class_dev, "%s attached\n", dev->board_name);
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ s->insn_read = adl_pci8164_insn_read;
+ s->insn_write = adl_pci8164_insn_write;
+ s->private = (void *)PCI8164_BUF1_REG;
return 0;
}
-static void adl_pci8164_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
-}
-
static struct comedi_driver adl_pci8164_driver = {
.driver_name = "adl_pci8164",
.module = THIS_MODULE,
.auto_attach = adl_pci8164_auto_attach,
- .detach = adl_pci8164_detach,
+ .detach = comedi_pci_disable,
};
static int adl_pci8164_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adl_pci8164_driver);
+ return comedi_pci_auto_config(dev, &adl_pci8164_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) },
- {0}
+ { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index eeb10ec7f17..6247fdcedcb 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -75,6 +75,7 @@ TODO:
#include "../comedidev.h"
#include "8253.h"
+#include "plx9052.h"
#include "comedi_fc.h"
#define PCI9111_DRIVER_NAME "adl_pci9111"
@@ -120,6 +121,14 @@ TODO:
#define PCI9111_8254_BASE_REG 0x40
#define PCI9111_INT_CLR_REG 0x48
+/* PLX 9052 Local Interrupt 1 enabled and active */
+#define PCI9111_LI1_ACTIVE (PLX9052_INTCSR_LI1ENAB | \
+ PLX9052_INTCSR_LI1STAT)
+
+/* PLX 9052 Local Interrupt 2 enabled and active */
+#define PCI9111_LI2_ACTIVE (PLX9052_INTCSR_LI2ENAB | \
+ PLX9052_INTCSR_LI2STAT)
+
static const struct comedi_lrange pci9111_ai_range = {
5,
{
@@ -150,17 +159,6 @@ struct pci9111_private_data {
short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
};
-#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
-
-#define PLX9050_LINTI1_ENABLE (1 << 0)
-#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1)
-#define PLX9050_LINTI1_STATUS (1 << 2)
-#define PLX9050_LINTI2_ENABLE (1 << 3)
-#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4)
-#define PLX9050_LINTI2_STATUS (1 << 5)
-#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6)
-#define PLX9050_SOFTWARE_INTERRUPT (1 << 7)
-
static void plx9050_interrupt_control(unsigned long io_base,
bool LINTi1_enable,
bool LINTi1_active_high,
@@ -171,18 +169,18 @@ static void plx9050_interrupt_control(unsigned long io_base,
int flags = 0;
if (LINTi1_enable)
- flags |= PLX9050_LINTI1_ENABLE;
+ flags |= PLX9052_INTCSR_LI1ENAB;
if (LINTi1_active_high)
- flags |= PLX9050_LINTI1_ACTIVE_HIGH;
+ flags |= PLX9052_INTCSR_LI1POL;
if (LINTi2_enable)
- flags |= PLX9050_LINTI2_ENABLE;
+ flags |= PLX9052_INTCSR_LI2ENAB;
if (LINTi2_active_high)
- flags |= PLX9050_LINTI2_ACTIVE_HIGH;
+ flags |= PLX9052_INTCSR_LI2POL;
if (interrupt_enable)
- flags |= PLX9050_PCI_INTERRUPT_ENABLE;
+ flags |= PLX9052_INTCSR_PCIENAB;
- outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
+ outb(flags, io_base + PLX9052_INTCSR);
}
static void pci9111_timer_set(struct comedi_device *dev)
@@ -607,21 +605,17 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
spin_lock_irqsave(&dev->spinlock, irq_flags);
/* Check if we are source of interrupt */
- intcsr = inb(dev_private->lcr_io_base +
- PLX9050_REGISTER_INTERRUPT_CONTROL);
- if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
- && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
- == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
- || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))
- == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) {
+ intcsr = inb(dev_private->lcr_io_base + PLX9052_INTCSR);
+ if (!(((intcsr & PLX9052_INTCSR_PCIENAB) != 0) &&
+ (((intcsr & PCI9111_LI1_ACTIVE) == PCI9111_LI1_ACTIVE) ||
+ ((intcsr & PCI9111_LI2_ACTIVE) == PCI9111_LI2_ACTIVE)))) {
/* Not the source of the interrupt. */
- /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */
+ /* (N.B. not using PLX9052_INTCSR_SOFTINT) */
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
return IRQ_NONE;
}
- if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
- (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
+ if ((intcsr & PCI9111_LI1_ACTIVE) == PCI9111_LI1_ACTIVE) {
/* Interrupt comes from fifo_half-full signal */
status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
@@ -865,14 +859,12 @@ static int pci9111_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL);
if (!dev_private)
return -ENOMEM;
dev->private = dev_private;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev_private->lcr_io_base = pci_resource_start(pcidev, 1);
@@ -939,16 +931,11 @@ static int pci9111_auto_attach(struct comedi_device *dev,
static void pci9111_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
pci9111_reset(dev);
if (dev->irq != 0)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver adl_pci9111_driver = {
@@ -959,9 +946,10 @@ static struct comedi_driver adl_pci9111_driver = {
};
static int pci9111_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adl_pci9111_driver);
+ return comedi_pci_auto_config(dev, &adl_pci9111_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 4dbac7459a4..cb4ef2dcbf0 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -1970,12 +1970,9 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
u16 u16w;
dev->board_name = this_board->name;
- ret = comedi_pci_enable(pcidev, dev->board_name);
- if (ret) {
- dev_err(dev->class_dev,
- "cannot enable PCI device %s\n", pci_name(pcidev));
+ ret = comedi_pci_enable(dev);
+ if (ret)
return ret;
- }
if (master)
pci_set_master(pcidev);
@@ -2202,12 +2199,9 @@ static void pci9118_detach(struct comedi_device *dev)
free_pages((unsigned long)devpriv->dmabuf_virt[1],
devpriv->dmabuf_pages[1]);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
-
+ comedi_pci_disable(dev);
+ if (pcidev)
pci_dev_put(pcidev);
- }
}
static struct comedi_driver adl_pci9118_driver = {
@@ -2222,9 +2216,10 @@ static struct comedi_driver adl_pci9118_driver = {
};
static int adl_pci9118_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adl_pci9118_driver);
+ return comedi_pci_auto_config(dev, &adl_pci9118_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index f7950dfe2dd..71142e36e7f 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -213,43 +213,19 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct adq12b_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
- int unipolar, differential;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
- unipolar = it->options[1];
- differential = it->options[2];
-
- printk(KERN_INFO "comedi%d: adq12b called with options base=0x%03lx, "
- "%s and %s\n", dev->minor, iobase,
- (unipolar == 1) ? "unipolar" : "bipolar",
- (differential == 1) ? "differential" : "single-ended");
-
- /* if no address was specified, try the default 0x300 */
- if (iobase == 0) {
- printk(KERN_WARNING "comedi%d: adq12b warning: I/O base "
- "address not specified. Trying the default 0x300.\n",
- dev->minor);
- iobase = 0x300;
- }
-
- printk("comedi%d: adq12b: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, ADQ12B_SIZE, "adq12b")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], ADQ12B_SIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- devpriv->unipolar = unipolar;
- devpriv->differential = differential;
+ devpriv->unipolar = it->options[1];
+ devpriv->differential = it->options[2];
devpriv->digital_state = 0;
/*
* initialize channel and range to -1 so we make sure we
@@ -265,7 +241,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s = &dev->subdevices[0];
/* analog input subdevice */
s->type = COMEDI_SUBD_AI;
- if (differential) {
+ if (devpriv->differential) {
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
s->n_chan = 8;
} else {
@@ -273,7 +249,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->n_chan = 16;
}
- if (unipolar)
+ if (devpriv->unipolar)
s->range_table = &range_adq12b_ai_unipolar;
else
s->range_table = &range_adq12b_ai_bipolar;
@@ -302,22 +278,14 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->range_table = &range_digital;
s->insn_bits = adq12b_do_insn_bits;
- printk(KERN_INFO "attached\n");
-
return 0;
}
-static void adq12b_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, ADQ12B_SIZE);
-}
-
static struct comedi_driver adq12b_driver = {
.driver_name = "adq12b",
.module = THIS_MODULE,
.attach = adq12b_attach,
- .detach = adq12b_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(adq12b_driver);
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 3d788c76d64..f847bbc175e 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -59,9 +59,6 @@ Configuration options:
#define TYPE_PCI1713 2
#define TYPE_PCI1720 3
-#define IORANGE_171x 32
-#define IORANGE_1720 16
-
#define PCI171x_AD_DATA 0 /* R: A/D data */
#define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */
#define PCI171x_RANGE 2 /* W: A/D gain/range register */
@@ -178,10 +175,17 @@ static const struct comedi_lrange range_pci171x_da = { 2, {
}
};
+enum pci1710_boardid {
+ BOARD_PCI1710,
+ BOARD_PCI1710HG,
+ BOARD_PCI1711,
+ BOARD_PCI1713,
+ BOARD_PCI1720,
+ BOARD_PCI1731,
+};
+
struct boardtype {
const char *name; /* board name */
- int device_id;
- int iorange; /* I/O range len */
char have_irq; /* 1=card support IRQ */
char cardtype; /* 0=1710& co. 2=1713, ... */
int n_aichan; /* num of A/D chans */
@@ -200,10 +204,8 @@ struct boardtype {
};
static const struct boardtype boardtypes[] = {
- {
+ [BOARD_PCI1710] = {
.name = "pci1710",
- .device_id = 0x1710,
- .iorange = IORANGE_171x,
.have_irq = 1,
.cardtype = TYPE_PCI171X,
.n_aichan = 16,
@@ -219,10 +221,9 @@ static const struct boardtype boardtypes[] = {
.rangelist_ao = &range_pci171x_da,
.ai_ns_min = 10000,
.fifo_half_size = 2048,
- }, {
+ },
+ [BOARD_PCI1710HG] = {
.name = "pci1710hg",
- .device_id = 0x1710,
- .iorange = IORANGE_171x,
.have_irq = 1,
.cardtype = TYPE_PCI171X,
.n_aichan = 16,
@@ -238,10 +239,9 @@ static const struct boardtype boardtypes[] = {
.rangelist_ao = &range_pci171x_da,
.ai_ns_min = 10000,
.fifo_half_size = 2048,
- }, {
+ },
+ [BOARD_PCI1711] = {
.name = "pci1711",
- .device_id = 0x1711,
- .iorange = IORANGE_171x,
.have_irq = 1,
.cardtype = TYPE_PCI171X,
.n_aichan = 16,
@@ -256,10 +256,9 @@ static const struct boardtype boardtypes[] = {
.rangelist_ao = &range_pci171x_da,
.ai_ns_min = 10000,
.fifo_half_size = 512,
- }, {
+ },
+ [BOARD_PCI1713] = {
.name = "pci1713",
- .device_id = 0x1713,
- .iorange = IORANGE_171x,
.have_irq = 1,
.cardtype = TYPE_PCI1713,
.n_aichan = 32,
@@ -269,18 +268,16 @@ static const struct boardtype boardtypes[] = {
.rangecode_ai = range_codes_pci1710_3,
.ai_ns_min = 10000,
.fifo_half_size = 2048,
- }, {
+ },
+ [BOARD_PCI1720] = {
.name = "pci1720",
- .device_id = 0x1720,
- .iorange = IORANGE_1720,
.cardtype = TYPE_PCI1720,
.n_aochan = 4,
.ao_maxdata = 0x0fff,
.rangelist_ao = &range_pci1720,
- }, {
+ },
+ [BOARD_PCI1731] = {
.name = "pci1731",
- .device_id = 0x1731,
- .iorange = IORANGE_171x,
.have_irq = 1,
.cardtype = TYPE_PCI171X,
.n_aichan = 16,
@@ -307,7 +304,7 @@ struct pci1710_private {
unsigned int ai_et_CntrlReg;
unsigned int ai_et_MuxVal;
unsigned int ai_et_div1, ai_et_div2;
- unsigned int act_chanlist[32]; /* list of scaned channel */
+ unsigned int act_chanlist[32]; /* list of scanned channel */
unsigned char act_chanlist_len; /* len of scanlist */
unsigned char act_chanlist_pos; /* actual position in MUX list */
unsigned char da_ranges; /* copy of D/A outpit range register */
@@ -334,7 +331,7 @@ static const unsigned int muxonechan[] = {
/*
==============================================================================
- Check if channel list from user is builded correctly
+ Check if channel list from user is built correctly
If it's ok, then program scan/gain logic.
This works for all cards.
*/
@@ -1220,30 +1217,17 @@ static int pci1710_reset(struct comedi_device *dev)
}
}
-static const void *pci1710_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct boardtype *this_board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
- this_board = &boardtypes[i];
- if (pcidev->device == this_board->device_id)
- return this_board;
- }
- return NULL;
-}
-
static int pci1710_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct boardtype *this_board;
+ const struct boardtype *this_board = NULL;
struct pci1710_private *devpriv;
struct comedi_subdevice *s;
int ret, subdev, n_subdevices;
- this_board = pci1710_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(boardtypes))
+ this_board = &boardtypes[context];
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
@@ -1254,7 +1238,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
@@ -1378,16 +1362,11 @@ static int pci1710_auto_attach(struct comedi_device *dev,
static void pci1710_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->iobase)
pci1710_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver adv_pci1710_driver = {
@@ -1398,17 +1377,68 @@ static struct comedi_driver adv_pci1710_driver = {
};
static int adv_pci1710_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adv_pci1710_driver);
+ return comedi_pci_auto_config(dev, &adv_pci1710_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1710) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1711) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1713) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1731) },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0x0000),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xb100),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xb200),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xc100),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xc200),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, 0x1000, 0xd100),
+ .driver_data = BOARD_PCI1710,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0x0002),
+ .driver_data = BOARD_PCI1710HG,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xb102),
+ .driver_data = BOARD_PCI1710HG,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xb202),
+ .driver_data = BOARD_PCI1710HG,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xc102),
+ .driver_data = BOARD_PCI1710HG,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710,
+ PCI_VENDOR_ID_ADVANTECH, 0xc202),
+ .driver_data = BOARD_PCI1710HG,
+ }, {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, 0x1000, 0xd102),
+ .driver_data = BOARD_PCI1710HG,
+ },
+ { PCI_VDEVICE(ADVANTECH, 0x1711), BOARD_PCI1711 },
+ { PCI_VDEVICE(ADVANTECH, 0x1713), BOARD_PCI1713 },
+ { PCI_VDEVICE(ADVANTECH, 0x1720), BOARD_PCI1720 },
+ { PCI_VDEVICE(ADVANTECH, 0x1731), BOARD_PCI1731 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, adv_pci1710_pci_table);
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index 02ce55a01d2..ccc114d6c08 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -242,14 +242,12 @@ static int pci1723_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
@@ -306,14 +304,9 @@ static int pci1723_auto_attach(struct comedi_device *dev,
static void pci1723_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase) {
- pci1723_reset(dev);
- comedi_pci_disable(pcidev);
- }
- }
+ if (dev->iobase)
+ pci1723_reset(dev);
+ comedi_pci_disable(dev);
}
static struct comedi_driver adv_pci1723_driver = {
@@ -324,9 +317,10 @@ static struct comedi_driver adv_pci1723_driver = {
};
static int adv_pci1723_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adv_pci1723_driver);
+ return comedi_pci_auto_config(dev, &adv_pci1723_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(adv_pci1723_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c
new file mode 100644
index 00000000000..e60f12578d4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1724.c
@@ -0,0 +1,409 @@
+/*
+ comedi/drivers/adv_pci1724.c
+ This is a driver for the Advantech PCI-1724U card.
+
+ Author: Frank Mori Hess <fmh6jj@gmail.com>
+ Copyright (C) 2013 GnuBIO Inc
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ 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: adv_1724
+Description: Advantech PCI-1724U
+Author: Frank Mori Hess <fmh6jj@gmail.com>
+Status: works
+Updated: 2013-02-09
+Devices: [Advantech] PCI-1724U (adv_pci1724)
+
+Subdevice 0 is the analog output.
+Subdevice 1 is the offset calibration for the analog output.
+Subdevice 2 is the gain calibration for the analog output.
+
+The calibration offset and gains have quite a large effect
+on the analog output, so it is possible to adjust the analog output to
+have an output range significantly different from the board's
+nominal output ranges. For a calibrated +/- 10V range, the analog
+output's offset will be set somewhere near mid-range (0x2000) and its
+gain will be near maximum (0x3fff).
+
+There is really no difference between the board's documented 0-20mA
+versus 4-20mA output ranges. To pick one or the other is simply a matter
+of adjusting the offset and gain calibration until the board outputs in
+the desired range.
+
+Configuration options:
+ None
+
+Manual configuration of comedi devices is not supported by this driver;
+supported PCI devices are configured as comedi devices automatically.
+
+*/
+
+#include <linux/pci.h>
+
+#include "../comedidev.h"
+
+#define PCI_VENDOR_ID_ADVANTECH 0x13fe
+
+#define NUM_AO_CHANNELS 32
+
+/* register offsets */
+enum board_registers {
+ DAC_CONTROL_REG = 0x0,
+ SYNC_OUTPUT_REG = 0x4,
+ EEPROM_CONTROL_REG = 0x8,
+ SYNC_OUTPUT_TRIGGER_REG = 0xc,
+ BOARD_ID_REG = 0x10
+};
+
+/* bit definitions for registers */
+enum dac_control_contents {
+ DAC_DATA_MASK = 0x3fff,
+ DAC_DESTINATION_MASK = 0xc000,
+ DAC_NORMAL_MODE = 0xc000,
+ DAC_OFFSET_MODE = 0x8000,
+ DAC_GAIN_MODE = 0x4000,
+ DAC_CHANNEL_SELECT_MASK = 0xf0000,
+ DAC_GROUP_SELECT_MASK = 0xf00000
+};
+
+static uint32_t dac_data_bits(uint16_t dac_data)
+{
+ return dac_data & DAC_DATA_MASK;
+}
+
+static uint32_t dac_channel_select_bits(unsigned channel)
+{
+ return (channel << 16) & DAC_CHANNEL_SELECT_MASK;
+}
+
+static uint32_t dac_group_select_bits(unsigned group)
+{
+ return (1 << (20 + group)) & DAC_GROUP_SELECT_MASK;
+}
+
+static uint32_t dac_channel_and_group_select_bits(unsigned comedi_channel)
+{
+ return dac_channel_select_bits(comedi_channel % 8) |
+ dac_group_select_bits(comedi_channel / 8);
+}
+
+enum sync_output_contents {
+ SYNC_MODE = 0x1,
+ DAC_BUSY = 0x2, /* dac state machine is not ready */
+};
+
+enum sync_output_trigger_contents {
+ SYNC_TRIGGER_BITS = 0x0 /* any value works */
+};
+
+enum board_id_contents {
+ BOARD_ID_MASK = 0xf
+};
+
+static const struct comedi_lrange ao_ranges_1724 = { 4,
+ {
+ BIP_RANGE(10),
+ RANGE_mA(0, 20),
+ RANGE_mA(4, 20),
+ RANGE_unitless(0, 1)
+ }
+};
+
+static const struct comedi_lrange *const ao_range_list_1724[NUM_AO_CHANNELS] = {
+ [0 ... NUM_AO_CHANNELS - 1] = &ao_ranges_1724,
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct adv_pci1724_private {
+ int ao_value[NUM_AO_CHANNELS];
+ int offset_value[NUM_AO_CHANNELS];
+ int gain_value[NUM_AO_CHANNELS];
+};
+
+static int wait_for_dac_idle(struct comedi_device *dev)
+{
+ static const int timeout = 10000;
+ int i;
+
+ for (i = 0; i < timeout; ++i) {
+ if ((inl(dev->iobase + SYNC_OUTPUT_REG) & DAC_BUSY) == 0)
+ break;
+ udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "Timed out waiting for dac to become idle.");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int set_dac(struct comedi_device *dev, unsigned mode, unsigned channel,
+ unsigned data)
+{
+ int retval;
+ unsigned control_bits;
+
+ retval = wait_for_dac_idle(dev);
+ if (retval < 0)
+ return retval;
+
+ control_bits = mode;
+ control_bits |= dac_channel_and_group_select_bits(channel);
+ control_bits |= dac_data_bits(data);
+ outl(control_bits, dev->iobase + DAC_CONTROL_REG);
+ return 0;
+}
+
+static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct adv_pci1724_private *devpriv = dev->private;
+ int channel = CR_CHAN(insn->chanspec);
+ int retval;
+ int i;
+
+ /* turn off synchronous mode */
+ outl(0, dev->iobase + SYNC_OUTPUT_REG);
+
+ for (i = 0; i < insn->n; ++i) {
+ retval = set_dac(dev, DAC_NORMAL_MODE, channel, data[i]);
+ if (retval < 0)
+ return retval;
+ devpriv->ao_value[channel] = data[i];
+ }
+ return insn->n;
+}
+
+static int ao_readback_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct adv_pci1724_private *devpriv = dev->private;
+ int channel = CR_CHAN(insn->chanspec);
+ int i;
+
+ if (devpriv->ao_value[channel] < 0) {
+ comedi_error(dev,
+ "Cannot read back channels which have not yet been written to.");
+ return -EIO;
+ }
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_value[channel];
+
+ return insn->n;
+}
+
+static int offset_write_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct adv_pci1724_private *devpriv = dev->private;
+ int channel = CR_CHAN(insn->chanspec);
+ int retval;
+ int i;
+
+ /* turn off synchronous mode */
+ outl(0, dev->iobase + SYNC_OUTPUT_REG);
+
+ for (i = 0; i < insn->n; ++i) {
+ retval = set_dac(dev, DAC_OFFSET_MODE, channel, data[i]);
+ if (retval < 0)
+ return retval;
+ devpriv->offset_value[channel] = data[i];
+ }
+
+ return insn->n;
+}
+
+static int offset_read_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct adv_pci1724_private *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
+ int i;
+
+ if (devpriv->offset_value[channel] < 0) {
+ comedi_error(dev,
+ "Cannot read back channels which have not yet been written to.");
+ return -EIO;
+ }
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->offset_value[channel];
+
+ return insn->n;
+}
+
+static int gain_write_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct adv_pci1724_private *devpriv = dev->private;
+ int channel = CR_CHAN(insn->chanspec);
+ int retval;
+ int i;
+
+ /* turn off synchronous mode */
+ outl(0, dev->iobase + SYNC_OUTPUT_REG);
+
+ for (i = 0; i < insn->n; ++i) {
+ retval = set_dac(dev, DAC_GAIN_MODE, channel, data[i]);
+ if (retval < 0)
+ return retval;
+ devpriv->gain_value[channel] = data[i];
+ }
+
+ return insn->n;
+}
+
+static int gain_read_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct adv_pci1724_private *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
+ int i;
+
+ if (devpriv->gain_value[channel] < 0) {
+ comedi_error(dev,
+ "Cannot read back channels which have not yet been written to.");
+ return -EIO;
+ }
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->gain_value[channel];
+
+ return insn->n;
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device *dev)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ ret = comedi_alloc_subdevices(dev, 3);
+ if (ret)
+ return ret;
+
+ /* analog output subdevice */
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = NUM_AO_CHANNELS;
+ s->maxdata = 0x3fff;
+ s->range_table_list = ao_range_list_1724;
+ s->insn_read = ao_readback_insn;
+ s->insn_write = ao_winsn;
+
+ /* offset calibration */
+ s = &dev->subdevices[1];
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = NUM_AO_CHANNELS;
+ s->insn_read = offset_read_insn;
+ s->insn_write = offset_write_insn;
+ s->maxdata = 0x3fff;
+
+ /* gain calibration */
+ s = &dev->subdevices[2];
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = NUM_AO_CHANNELS;
+ s->insn_read = gain_read_insn;
+ s->insn_write = gain_write_insn;
+ s->maxdata = 0x3fff;
+
+ return 0;
+}
+
+static int adv_pci1724_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct adv_pci1724_private *devpriv;
+ int i;
+ int retval;
+ unsigned int board_id;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ /* init software copies of output values to indicate we don't know
+ * what the output value is since it has never been written. */
+ for (i = 0; i < NUM_AO_CHANNELS; ++i) {
+ devpriv->ao_value[i] = -1;
+ devpriv->offset_value[i] = -1;
+ devpriv->gain_value[i] = -1;
+ }
+
+ retval = comedi_pci_enable(dev);
+ if (retval)
+ return retval;
+
+ dev->iobase = pci_resource_start(pcidev, 2);
+ board_id = inl(dev->iobase + BOARD_ID_REG) & BOARD_ID_MASK;
+ dev_info(dev->class_dev, "board id: %d\n", board_id);
+
+ retval = setup_subdevices(dev);
+ if (retval < 0)
+ return retval;
+
+ dev_info(dev->class_dev, "%s (pci %s) attached, board id: %u\n",
+ dev->board_name, pci_name(pcidev), board_id);
+ return 0;
+}
+
+static struct comedi_driver adv_pci1724_driver = {
+ .driver_name = "adv_pci1724",
+ .module = THIS_MODULE,
+ .auto_attach = adv_pci1724_auto_attach,
+ .detach = comedi_pci_disable,
+};
+
+static int adv_pci1724_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &adv_pci1724_driver,
+ id->driver_data);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(adv_pci1724_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1724) },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, adv_pci1724_pci_table);
+
+static struct pci_driver adv_pci1724_pci_driver = {
+ .name = "adv_pci1724",
+ .id_table = adv_pci1724_pci_table,
+ .probe = adv_pci1724_pci_probe,
+ .remove = comedi_pci_auto_unconfig,
+};
+
+module_comedi_pci_driver(adv_pci1724_driver, adv_pci1724_pci_driver);
+
+MODULE_AUTHOR("Frank Mori Hess <fmh6jj@gmail.com>");
+MODULE_DESCRIPTION("Advantech PCI-1724U Comedi driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 338c43e716b..f70c67471c1 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -236,8 +236,6 @@ struct diosubd_data {
struct dio_boardtype {
const char *name; /* board name */
- int vendor_id; /* vendor/device PCI ID */
- int device_id;
int main_pci_region; /* main I/O PCI region */
enum hw_cards_id cardtype;
int nsubdevs;
@@ -250,10 +248,8 @@ struct dio_boardtype {
};
static const struct dio_boardtype boardtypes[] = {
- {
+ [TYPE_PCI1730] = {
.name = "pci1730",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1730,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1730,
.nsubdevs = 5,
@@ -263,30 +259,27 @@ static const struct dio_boardtype boardtypes[] = {
.sdo[1] = { 16, PCI1730_IDO, 2, 0, },
.boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1733] = {
.name = "pci1733",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1733,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1733,
.nsubdevs = 2,
.sdi[1] = { 32, PCI1733_IDI, 4, 0, },
.boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1734] = {
.name = "pci1734",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1734,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1734,
.nsubdevs = 2,
.sdo[1] = { 32, PCI1734_IDO, 4, 0, },
.boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1735] = {
.name = "pci1735",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1735,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1735,
.nsubdevs = 4,
@@ -295,10 +288,9 @@ static const struct dio_boardtype boardtypes[] = {
.boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, },
.s8254[0] = { 3, PCI1735_C8254, 1, 0, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1736] = {
.name = "pci1736",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1736,
.main_pci_region = PCI1736_MAINREG,
.cardtype = TYPE_PCI1736,
.nsubdevs = 3,
@@ -306,39 +298,35 @@ static const struct dio_boardtype boardtypes[] = {
.sdo[1] = { 16, PCI1736_IDO, 2, 0, },
.boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1739] = {
.name = "pci1739",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1739,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1739,
.nsubdevs = 2,
.sdio[0] = { 48, PCI1739_DIO, 2, 0, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1750] = {
.name = "pci1750",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1750,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1750,
.nsubdevs = 2,
.sdi[1] = { 16, PCI1750_IDI, 2, 0, },
.sdo[1] = { 16, PCI1750_IDO, 2, 0, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1751] = {
.name = "pci1751",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1751,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1751,
.nsubdevs = 3,
.sdio[0] = { 48, PCI1751_DIO, 2, 0, },
.s8254[0] = { 3, PCI1751_CNT, 1, 0, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1752] = {
.name = "pci1752",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1752,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1752,
.nsubdevs = 3,
@@ -346,29 +334,26 @@ static const struct dio_boardtype boardtypes[] = {
.sdo[1] = { 32, PCI1752_IDO2, 2, 0, },
.boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_16b,
- }, {
+ },
+ [TYPE_PCI1753] = {
.name = "pci1753",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1753,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1753,
.nsubdevs = 4,
.sdio[0] = { 96, PCI1753_DIO, 4, 0, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1753E] = {
.name = "pci1753e",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1753,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1753E,
.nsubdevs = 8,
.sdio[0] = { 96, PCI1753_DIO, 4, 0, },
.sdio[1] = { 96, PCI1753E_DIO, 4, 0, },
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1754] = {
.name = "pci1754",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1754,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1754,
.nsubdevs = 3,
@@ -376,10 +361,9 @@ static const struct dio_boardtype boardtypes[] = {
.sdi[1] = { 32, PCI1754_IDI2, 2, 0, },
.boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_16b,
- }, {
+ },
+ [TYPE_PCI1756] = {
.name = "pci1756",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1756,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1756,
.nsubdevs = 3,
@@ -387,19 +371,17 @@ static const struct dio_boardtype boardtypes[] = {
.sdo[1] = { 32, PCI1756_IDO, 2, 0, },
.boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
.io_access = IO_16b,
- }, {
+ },
+ [TYPE_PCI1760] = {
/* This card has its own 'attach' */
.name = "pci1760",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1760,
.main_pci_region = 0,
.cardtype = TYPE_PCI1760,
.nsubdevs = 4,
.io_access = IO_8b,
- }, {
+ },
+ [TYPE_PCI1762] = {
.name = "pci1762",
- .vendor_id = PCI_VENDOR_ID_ADVANTECH,
- .device_id = 0x1762,
.main_pci_region = PCIDIO_MAINREG,
.cardtype = TYPE_PCI1762,
.nsubdevs = 3,
@@ -1076,31 +1058,50 @@ static int pci_dio_add_8254(struct comedi_device *dev,
return 0;
}
-static const void *pci_dio_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
+static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev,
+ unsigned long cardtype)
{
- const struct dio_boardtype *this_board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) {
- this_board = &boardtypes[i];
- if (this_board->vendor_id == pcidev->vendor &&
- this_board->device_id == pcidev->device)
- return this_board;
+ /*
+ * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion
+ * board available. Need to enable PCI device and request the main
+ * registers PCI BAR temporarily to perform the test.
+ */
+ if (cardtype != TYPE_PCI1753)
+ return cardtype;
+ if (pci_enable_device(pcidev) < 0)
+ return cardtype;
+ if (pci_request_region(pcidev, PCIDIO_MAINREG, "adv_pci_dio") == 0) {
+ /*
+ * This test is based on Advantech's "advdaq" driver source
+ * (which declares its module licence as "GPL" although the
+ * driver source does not include a "COPYING" file).
+ */
+ unsigned long reg =
+ pci_resource_start(pcidev, PCIDIO_MAINREG) + 53;
+
+ outb(0x05, reg);
+ if ((inb(reg) & 0x07) == 0x02) {
+ outb(0x02, reg);
+ if ((inb(reg) & 0x07) == 0x05)
+ cardtype = TYPE_PCI1753E;
+ }
+ pci_release_region(pcidev, PCIDIO_MAINREG);
}
- return NULL;
+ pci_disable_device(pcidev);
+ return cardtype;
}
static int pci_dio_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct dio_boardtype *this_board;
+ const struct dio_boardtype *this_board = NULL;
struct pci_dio_private *devpriv;
struct comedi_subdevice *s;
int ret, subdev, i, j;
- this_board = pci_dio_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(boardtypes))
+ this_board = &boardtypes[context];
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
@@ -1111,7 +1112,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, this_board->main_pci_region);
@@ -1172,7 +1173,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev,
static void pci_dio_detach(struct comedi_device *dev)
{
struct pci_dio_private *devpriv = dev->private;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct comedi_subdevice *s;
int i;
@@ -1180,18 +1180,13 @@ static void pci_dio_detach(struct comedi_device *dev)
if (devpriv->valid)
pci_dio_reset(dev);
}
- if (dev->subdevices) {
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- if (s->type == COMEDI_SUBD_DIO)
- subdev_8255_cleanup(dev, s);
- s->private = NULL;
- }
- }
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = &dev->subdevices[i];
+ if (s->type == COMEDI_SUBD_DIO)
+ comedi_spriv_free(dev, i);
+ s->private = NULL; /* some private data is static */
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver adv_pci_dio_driver = {
@@ -1202,26 +1197,29 @@ static struct comedi_driver adv_pci_dio_driver = {
};
static int adv_pci_dio_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &adv_pci_dio_driver);
+ unsigned long cardtype;
+
+ cardtype = pci_dio_override_cardtype(dev, id->driver_data);
+ return comedi_pci_auto_config(dev, &adv_pci_dio_driver, cardtype);
}
static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1730) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1733) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1739) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1753) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1754) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1756) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) },
- { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1762) },
+ { PCI_VDEVICE(ADVANTECH, 0x1730), TYPE_PCI1730 },
+ { PCI_VDEVICE(ADVANTECH, 0x1733), TYPE_PCI1733 },
+ { PCI_VDEVICE(ADVANTECH, 0x1734), TYPE_PCI1734 },
+ { PCI_VDEVICE(ADVANTECH, 0x1735), TYPE_PCI1735 },
+ { PCI_VDEVICE(ADVANTECH, 0x1736), TYPE_PCI1736 },
+ { PCI_VDEVICE(ADVANTECH, 0x1739), TYPE_PCI1739 },
+ { PCI_VDEVICE(ADVANTECH, 0x1750), TYPE_PCI1750 },
+ { PCI_VDEVICE(ADVANTECH, 0x1751), TYPE_PCI1751 },
+ { PCI_VDEVICE(ADVANTECH, 0x1752), TYPE_PCI1752 },
+ { PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 },
+ { PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 },
+ { PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 },
+ { PCI_VDEVICE(ADVANTECH, 0x1760), TYPE_PCI1760 },
+ { PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, adv_pci_dio_pci_table);
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
index 601f03d5897..e2dc08a058b 100644
--- a/drivers/staging/comedi/drivers/aio_aio12_8.c
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -200,17 +200,11 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
const struct aio12_8_boardtype *board = comedi_board(dev);
struct aio12_8_private *devpriv;
struct comedi_subdevice *s;
- int iobase;
int ret;
- dev->board_name = board->name;
-
- iobase = it->options[0];
- if (!request_region(iobase, 32, dev->board_name)) {
- printk(KERN_ERR "I/O port conflict");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], 32);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -250,8 +244,8 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
s = &dev->subdevices[2];
/* 8255 Digital i/o subdevice */
- iobase = dev->iobase + AIO12_8_8255_BASE_REG;
- ret = subdev_8255_init(dev, s, NULL, iobase);
+ ret = subdev_8255_init(dev, s, NULL,
+ dev->iobase + AIO12_8_8255_BASE_REG);
if (ret)
return ret;
@@ -267,10 +261,8 @@ static int aio_aio12_8_attach(struct comedi_device *dev,
static void aio_aio12_8_detach(struct comedi_device *dev)
{
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[2]);
- if (dev->iobase)
- release_region(dev->iobase, 24);
+ comedi_spriv_free(dev, 2);
+ comedi_legacy_detach(dev);
}
static struct comedi_driver aio_aio12_8_driver = {
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 64c1ae58ce7..126854c0509 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -77,22 +77,12 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
static int aio_iiro_16_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- int iobase;
struct comedi_subdevice *s;
int ret;
- printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor);
-
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
-
- if (!request_region(iobase, AIO_IIRO_16_SIZE, dev->board_name)) {
- printk("I/O port conflict");
- return -EIO;
- }
-
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], AIO_IIRO_16_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
@@ -114,22 +104,14 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
s->range_table = &range_digital;
s->insn_bits = aio_iiro_16_dio_insn_bits_read;
- printk("attached\n");
-
return 1;
}
-static void aio_iiro_16_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, AIO_IIRO_16_SIZE);
-}
-
static struct comedi_driver aio_iiro_16_driver = {
.driver_name = "aio_iiro_16",
.module = THIS_MODULE,
.attach = aio_iiro_16_attach,
- .detach = aio_iiro_16_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(aio_iiro_16_driver);
diff --git a/drivers/staging/comedi/drivers/am9513.h b/drivers/staging/comedi/drivers/am9513.h
deleted file mode 100644
index 0bb839e5149..00000000000
--- a/drivers/staging/comedi/drivers/am9513.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- module/am9513.h
- value added preprocessor definitions for Am9513 timer chip
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-
- 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.
-
-*/
-
-#ifndef _AM9513_H_
-#define _AM9513_H_
-
-#if 0
-
-/*
- * Before including this file, the following need to be defined:
- */
-#define Am9513_8BITBUS xxx
-/* or */
-#define Am9513_16BITBUS xxx
-
-#define Am9513_output_control(a) xxx
-#define Am9513_input_status() xxx
-#define Am9513_output_data(a) xxx
-#define Am9513_input_data() xxx
-
-#endif
-
-/*
- *
- */
-
-#ifdef Am9513_8BITBUS
-
-#define Am9513_write_register(reg, val) \
- do { \
- Am9513_output_control(reg); \
- Am9513_output_data(val>>8); \
- Am9513_output_data(val&0xff); \
- } while (0)
-
-#define Am9513_read_register(reg, val) \
- do { \
- Am9513_output_control(reg); \
- val = Am9513_input_data()<<8; \
- val |= Am9513_input_data(); \
- } while (0)
-
-#else /* Am9513_16BITBUS */
-
-#define Am9513_write_register(reg, val) \
- do { \
- Am9513_output_control(reg); \
- Am9513_output_data(val); \
- } while (0)
-
-#define Am9513_read_register(reg, val) \
- do { \
- Am9513_output_control(reg); \
- val = Am9513_input_data(); \
- } while (0)
-
-#endif
-
-#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 7c53dea12c7..297750bef0f 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -1,10 +1,9 @@
/*
comedi/drivers/amplc_dio200.c
- Driver for Amplicon PC272E and PCI272 DIO boards.
- (Support for other boards in Amplicon 200 series may be added at
- a later date, e.g. PCI215.)
- Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+ Driver for Amplicon PC212E, PC214E, PC215E, PC218E, PC272E.
+
+ Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/>
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
@@ -26,26 +25,23 @@
*/
/*
* Driver: amplc_dio200
- * Description: Amplicon 200 Series Digital I/O
+ * Description: Amplicon 200 Series ISA Digital I/O
* Author: Ian Abbott <abbotti@mev.co.uk>
* Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
- * PCI215 (pci215), PCIe215 (pcie215), PC218E (pc218e), PCIe236 (pcie236),
- * PC272E (pc272e), PCI272 (pci272), PCIe296 (pcie296)
- * Updated: Wed, 24 Oct 2012 16:22:34 +0100
+ * PC218E (pc218e), PC272E (pc272e)
+ * Updated: Mon, 18 Mar 2013 14:40:41 +0000
+ *
* Status: works
*
- * Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
+ * Configuration options:
* [0] - I/O port base address
* [1] - IRQ (optional, but commands won't work without it)
*
- * Manual configuration of PCI(e) cards is not supported; they are configured
- * automatically.
- *
* Passing a zero for an option is the same as leaving it unspecified.
*
* SUBDEVICES
*
- * PC212E PC214E PC215E/PCI215
+ * PC212E PC214E PC215E
* ------------- ------------- -------------
* Subdevices 6 4 5
* 0 PPI-X PPI-X PPI-X
@@ -55,29 +51,16 @@
* 4 CTR-Z2 INTERRUPT
* 5 INTERRUPT
*
- * PCIe215 PC218E PCIe236
- * ------------- ------------- -------------
- * Subdevices 8 7 8
- * 0 PPI-X CTR-X1 PPI-X
- * 1 UNUSED CTR-X2 UNUSED
- * 2 PPI-Y CTR-Y1 UNUSED
- * 3 UNUSED CTR-Y2 UNUSED
- * 4 CTR-Z1 CTR-Z1 CTR-Z1
- * 5 CTR-Z2 CTR-Z2 CTR-Z2
- * 6 TIMER INTERRUPT TIMER
- * 7 INTERRUPT INTERRUPT
- *
- * PC272E/PCI272 PCIe296
+ * PC218E PC272E
* ------------- -------------
- * Subdevices 4 8
- * 0 PPI-X PPI-X1
- * 1 PPI-Y PPI-X2
- * 2 PPI-Z PPI-Y1
- * 3 INTERRUPT PPI-Y2
- * 4 CTR-Z1
- * 5 CTR-Z2
- * 6 TIMER
- * 7 INTERRUPT
+ * Subdevices 7 4
+ * 0 CTR-X1 PPI-X
+ * 1 CTR-X2 PPI-Y
+ * 2 CTR-Y1 PPI-Z
+ * 3 CTR-Y2 INTERRUPT
+ * 4 CTR-Z1
+ * 5 CTR-Z2
+ * 6 INTERRUPT
*
* Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
* are configurable as inputs or outputs in four groups:
@@ -120,14 +103,6 @@
* the SK1 connector. This pin is shared by all three counter
* channels on the chip.
*
- * For the PCIe boards, clock sources in the range 0 to 31 are allowed
- * and the following additional clock sources are defined:
- *
- * 8. HIGH logic level.
- * 9. LOW logic level.
- * 10. "Pattern present" signal.
- * 11. Internal 20 MHz clock.
- *
* INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
* clock source in data[1]. For internal clock sources, data[2] is set
* to the period in ns.
@@ -149,27 +124,6 @@
* 6. Reserved.
* 7. Reserved.
*
- * For the PCIe boards, gate sources in the range 0 to 31 are allowed;
- * the following additional clock sources and clock sources 6 and 7 are
- * (re)defined:
- *
- * 6. /GAT n, negated version of the counter channel's dedicated
- * GAT input (negated version of gate source 2).
- * 7. OUT n-2, the non-inverted output of counter channel n-2
- * (negated version of gate source 3).
- * 8. "Pattern present" signal, HIGH while pattern present.
- * 9. "Pattern occurred" latched signal, latches HIGH when pattern
- * occurs.
- * 10. "Pattern gone away" latched signal, latches LOW when pattern
- * goes away after it occurred.
- * 11. Negated "pattern present" signal, LOW while pattern present
- * (negated version of gate source 8).
- * 12. Negated "pattern occurred" latched signal, latches LOW when
- * pattern occurs (negated version of gate source 9).
- * 13. Negated "pattern gone away" latched signal, latches LOW when
- * pattern goes away after it occurred (negated version of gate
- * source 10).
- *
* INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
* source in data[2].
*
@@ -186,8 +140,6 @@
* 3. The counter subdevices are connected in a ring, so the highest
* counter subdevice precedes the lowest.
*
- * The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
- *
* The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
* digital inputs come from the interrupt status register. The number of
* channels matches the number of interrupt sources. The PC214E does not
@@ -196,7 +148,7 @@
*
* INTERRUPT SOURCES
*
- * PC212E PC214E PC215E/PCI215
+ * PC212E PC214E PC215E
* ------------- ------------- -------------
* Sources 6 1 6
* 0 PPI-X-C0 JUMPER-J5 PPI-X-C0
@@ -206,25 +158,15 @@
* 4 CTR-Z1-OUT1 CTR-Z1-OUT1
* 5 CTR-Z2-OUT1 CTR-Z2-OUT1
*
- * PCIe215 PC218E PCIe236
- * ------------- ------------- -------------
- * Sources 6 6 6
- * 0 PPI-X-C0 CTR-X1-OUT1 PPI-X-C0
- * 1 PPI-X-C3 CTR-X2-OUT1 PPI-X-C3
- * 2 PPI-Y-C0 CTR-Y1-OUT1 unused
- * 3 PPI-Y-C3 CTR-Y2-OUT1 unused
- * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1
- * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1
- *
- * PC272E/PCI272 PCIe296
+ * PC218E PC272E
* ------------- -------------
* Sources 6 6
- * 0 PPI-X-C0 PPI-X1-C0
- * 1 PPI-X-C3 PPI-X1-C3
- * 2 PPI-Y-C0 PPI-Y1-C0
- * 3 PPI-Y-C3 PPI-Y1-C3
- * 4 PPI-Z-C0 CTR-Z1-OUT1
- * 5 PPI-Z-C3 CTR-Z2-OUT1
+ * 0 CTR-X1-OUT1 PPI-X-C0
+ * 1 CTR-X2-OUT1 PPI-X-C3
+ * 2 CTR-Y1-OUT1 PPI-Y-C0
+ * 3 CTR-Y2-OUT1 PPI-Y-C3
+ * 4 CTR-Z1-OUT1 PPI-Z-C0
+ * 5 CTR-Z2-OUT1 PPI-Z-C3
*
* When an interrupt source is enabled in the interrupt source enable
* register, a rising edge on the source signal latches the corresponding
@@ -232,14 +174,11 @@
*
* When the interrupt status register value as a whole (actually, just the
* 6 least significant bits) goes from zero to non-zero, the board will
- * generate an interrupt. For level-triggered hardware interrupts (PCI
- * card), the interrupt will remain asserted until the interrupt status
- * register is cleared to zero. For edge-triggered hardware interrupts
- * (ISA card), no further interrupts will occur until the interrupt status
- * register is cleared to zero. To clear a bit to zero in the interrupt
- * status register, the corresponding interrupt source must be disabled
- * in the interrupt source enable register (there is no separate interrupt
- * clear register).
+ * generate an interrupt. No further interrupts will occur until the
+ * interrupt status register is cleared to zero. To clear a bit to zero in
+ * the interrupt status register, the corresponding interrupt source must
+ * be disabled in the interrupt source enable register (there is no
+ * separate interrupt clear register).
*
* The PC214E does not have an interrupt source enable register or an
* interrupt status register; its 'INTERRUPT' subdevice has a single
@@ -258,1835 +197,116 @@
* order they appear in the channel list.
*/
-#include <linux/pci.h>
-#include <linux/interrupt.h>
#include <linux/slab.h>
#include "../comedidev.h"
-#include "comedi_fc.h"
-#include "8253.h"
-
-#define DIO200_DRIVER_NAME "amplc_dio200"
-
-#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_ISA)
-#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI)
-
-/* PCI IDs */
-#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
-#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
-#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
-#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
-#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
-
-/* 8255 control register bits */
-#define CR_C_LO_IO 0x01
-#define CR_B_IO 0x02
-#define CR_B_MODE 0x04
-#define CR_C_HI_IO 0x08
-#define CR_A_IO 0x10
-#define CR_A_MODE(a) ((a)<<5)
-#define CR_CW 0x80
-
-/* 200 series registers */
-#define DIO200_IO_SIZE 0x20
-#define DIO200_PCIE_IO_SIZE 0x4000
-#define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
-#define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
-#define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
-#define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
-#define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
-#define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
-#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
-/* Extra registers for new PCIe boards */
-#define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */
-#define DIO200_VERSION 0x24 /* Hardware version register */
-#define DIO200_TS_CONFIG 0x600 /* Timestamp timer config register */
-#define DIO200_TS_COUNT 0x602 /* Timestamp timer count register */
-
-/*
- * Functions for constructing value for DIO_200_?CLK_SCE and
- * DIO_200_?GAT_SCE registers:
- *
- * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
- * 'chan' is the channel: 0, 1 or 2.
- * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
- */
-static unsigned char clk_gat_sce(unsigned int which, unsigned int chan,
- unsigned int source)
-{
- return (which << 5) | (chan << 3) |
- ((source & 030) << 3) | (source & 007);
-}
-
-static unsigned char clk_sce(unsigned int which, unsigned int chan,
- unsigned int source)
-{
- return clk_gat_sce(which, chan, source);
-}
-
-static unsigned char gat_sce(unsigned int which, unsigned int chan,
- unsigned int source)
-{
- return clk_gat_sce(which, chan, source);
-}
-
-/*
- * Periods of the internal clock sources in nanoseconds.
- */
-static const unsigned int clock_period[32] = {
- [1] = 100, /* 10 MHz */
- [2] = 1000, /* 1 MHz */
- [3] = 10000, /* 100 kHz */
- [4] = 100000, /* 10 kHz */
- [5] = 1000000, /* 1 kHz */
- [11] = 50, /* 20 MHz (enhanced boards) */
- /* clock sources 12 and later reserved for enhanced boards */
-};
-
-/*
- * Timestamp timer configuration register (for new PCIe boards).
- */
-#define TS_CONFIG_RESET 0x100 /* Reset counter to zero. */
-#define TS_CONFIG_CLK_SRC_MASK 0x0FF /* Clock source. */
-#define TS_CONFIG_MAX_CLK_SRC 2 /* Maximum clock source value. */
-
-/*
- * Periods of the timestamp timer clock sources in nanoseconds.
- */
-static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
- 1, /* 1 nanosecond (but with 20 ns granularity). */
- 1000, /* 1 microsecond. */
- 1000000, /* 1 millisecond. */
-};
-
-/*
- * Register region.
- */
-enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype };
-struct dio200_region {
- union {
- unsigned long iobase; /* I/O base address */
- unsigned char __iomem *membase; /* mapped MMIO base address */
- } u;
- enum dio200_regtype regtype;
-};
+#include "amplc_dio200.h"
/*
* Board descriptions.
*/
-
-enum dio200_bustype { isa_bustype, pci_bustype };
-
-enum dio200_model {
- pc212e_model,
- pc214e_model,
- pc215e_model, pci215_model, pcie215_model,
- pc218e_model,
- pcie236_model,
- pc272e_model, pci272_model,
- pcie296_model,
-};
-
-enum dio200_layout_idx {
-#if DO_ISA
- pc212_layout,
- pc214_layout,
-#endif
- pc215_layout,
-#if DO_ISA
- pc218_layout,
-#endif
- pc272_layout,
-#if DO_PCI
- pcie215_layout,
- pcie236_layout,
- pcie296_layout,
-#endif
-};
-
-struct dio200_board {
- const char *name;
- unsigned short devid;
- enum dio200_bustype bustype;
- enum dio200_model model;
- enum dio200_layout_idx layout;
- unsigned char mainbar;
- unsigned char mainshift;
- unsigned int mainsize;
-};
-
-static const struct dio200_board dio200_boards[] = {
-#if DO_ISA
- {
- .name = "pc212e",
- .bustype = isa_bustype,
- .model = pc212e_model,
- .layout = pc212_layout,
- .mainsize = DIO200_IO_SIZE,
- },
- {
- .name = "pc214e",
- .bustype = isa_bustype,
- .model = pc214e_model,
- .layout = pc214_layout,
- .mainsize = DIO200_IO_SIZE,
- },
- {
- .name = "pc215e",
- .bustype = isa_bustype,
- .model = pc215e_model,
- .layout = pc215_layout,
- .mainsize = DIO200_IO_SIZE,
- },
- {
- .name = "pc218e",
- .bustype = isa_bustype,
- .model = pc218e_model,
- .layout = pc218_layout,
- .mainsize = DIO200_IO_SIZE,
- },
+static const struct dio200_board dio200_isa_boards[] = {
{
- .name = "pc272e",
- .bustype = isa_bustype,
- .model = pc272e_model,
- .layout = pc272_layout,
- .mainsize = DIO200_IO_SIZE,
- },
-#endif
-#if DO_PCI
+ .name = "pc212e",
+ .bustype = isa_bustype,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 6,
+ .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, sd_8254,
+ sd_intr},
+ .sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ },
+ },
{
- .name = "pci215",
- .devid = PCI_DEVICE_ID_AMPLICON_PCI215,
- .bustype = pci_bustype,
- .model = pci215_model,
- .layout = pc215_layout,
- .mainbar = 2,
- .mainsize = DIO200_IO_SIZE,
- },
+ .name = "pc214e",
+ .bustype = isa_bustype,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 4,
+ .sdtype = {sd_8255, sd_8255, sd_8254, sd_intr},
+ .sdinfo = {0x00, 0x08, 0x10, 0x01},
+ },
+ },
{
- .name = "pci272",
- .devid = PCI_DEVICE_ID_AMPLICON_PCI272,
- .bustype = pci_bustype,
- .model = pci272_model,
- .layout = pc272_layout,
- .mainbar = 2,
- .mainsize = DIO200_IO_SIZE,
- },
+ .name = "pc215e",
+ .bustype = isa_bustype,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 5,
+ .sdtype = {sd_8255, sd_8255, sd_8254, sd_8254, sd_intr},
+ .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ },
+ },
{
- .name = "pcie215",
- .devid = PCI_DEVICE_ID_AMPLICON_PCIE215,
- .bustype = pci_bustype,
- .model = pcie215_model,
- .layout = pcie215_layout,
- .mainbar = 1,
- .mainshift = 3,
- .mainsize = DIO200_PCIE_IO_SIZE,
- },
+ .name = "pc218e",
+ .bustype = isa_bustype,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 7,
+ .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, sd_8254,
+ sd_intr},
+ .sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ },
+ },
{
- .name = "pcie236",
- .devid = PCI_DEVICE_ID_AMPLICON_PCIE236,
- .bustype = pci_bustype,
- .model = pcie236_model,
- .layout = pcie236_layout,
- .mainbar = 1,
- .mainshift = 3,
- .mainsize = DIO200_PCIE_IO_SIZE,
- },
- {
- .name = "pcie296",
- .devid = PCI_DEVICE_ID_AMPLICON_PCIE296,
- .bustype = pci_bustype,
- .model = pcie296_model,
- .layout = pcie296_layout,
- .mainbar = 1,
- .mainshift = 3,
- .mainsize = DIO200_PCIE_IO_SIZE,
- },
-#endif
-};
-
-/*
- * Layout descriptions - some ISA and PCI board descriptions share the same
- * layout.
- */
-
-enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
-
-#define DIO200_MAX_SUBDEVS 8
-#define DIO200_MAX_ISNS 6
-
-struct dio200_layout {
- unsigned short n_subdevs; /* number of subdevices */
- unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
- unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
- char has_int_sce; /* has interrupt enable/status register */
- char has_clk_gat_sce; /* has clock/gate selection registers */
- char has_enhancements; /* has enhanced features */
-};
-
-static const struct dio200_layout dio200_layouts[] = {
-#if DO_ISA
- [pc212_layout] = {
- .n_subdevs = 6,
- .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254,
- sd_8254,
- sd_intr},
- .sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14,
- 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 1,
- },
- [pc214_layout] = {
- .n_subdevs = 4,
- .sdtype = {sd_8255, sd_8255, sd_8254,
- sd_intr},
- .sdinfo = {0x00, 0x08, 0x10, 0x01},
- .has_int_sce = 0,
- .has_clk_gat_sce = 0,
- },
-#endif
- [pc215_layout] = {
- .n_subdevs = 5,
- .sdtype = {sd_8255, sd_8255, sd_8254,
- sd_8254,
- sd_intr},
- .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 1,
- },
-#if DO_ISA
- [pc218_layout] = {
- .n_subdevs = 7,
- .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254,
- sd_8254,
- sd_intr},
- .sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10,
- 0x14,
- 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 1,
- },
-#endif
- [pc272_layout] = {
- .n_subdevs = 4,
- .sdtype = {sd_8255, sd_8255, sd_8255,
- sd_intr},
- .sdinfo = {0x00, 0x08, 0x10, 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 0,
- },
-#if DO_PCI
- [pcie215_layout] = {
- .n_subdevs = 8,
- .sdtype = {sd_8255, sd_none, sd_8255, sd_none,
- sd_8254, sd_8254, sd_timer, sd_intr},
- .sdinfo = {0x00, 0x00, 0x08, 0x00,
- 0x10, 0x14, 0x00, 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 1,
- .has_enhancements = 1,
- },
- [pcie236_layout] = {
- .n_subdevs = 8,
- .sdtype = {sd_8255, sd_none, sd_none, sd_none,
- sd_8254, sd_8254, sd_timer, sd_intr},
- .sdinfo = {0x00, 0x00, 0x00, 0x00,
- 0x10, 0x14, 0x00, 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 1,
- .has_enhancements = 1,
- },
- [pcie296_layout] = {
- .n_subdevs = 8,
- .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255,
- sd_8254, sd_8254, sd_timer, sd_intr},
- .sdinfo = {0x00, 0x04, 0x08, 0x0C,
- 0x10, 0x14, 0x00, 0x3F},
- .has_int_sce = 1,
- .has_clk_gat_sce = 1,
- .has_enhancements = 1,
- },
-#endif
-};
-
-/* this structure is for data unique to this hardware driver. If
- several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the struct comedi_device struct.
- */
-struct dio200_private {
- struct dio200_region io; /* Register region */
- int intr_sd;
-};
-
-struct dio200_subdev_8254 {
- unsigned int ofs; /* Counter base offset */
- unsigned int clk_sce_ofs; /* CLK_SCE base address */
- unsigned int gat_sce_ofs; /* GAT_SCE base address */
- int which; /* Bit 5 of CLK_SCE or GAT_SCE */
- unsigned int clock_src[3]; /* Current clock sources */
- unsigned int gate_src[3]; /* Current gate sources */
- spinlock_t spinlock;
-};
-
-struct dio200_subdev_8255 {
- unsigned int ofs; /* DIO base offset */
+ .name = "pc272e",
+ .bustype = isa_bustype,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 4,
+ .sdtype = {sd_8255, sd_8255, sd_8255, sd_intr},
+ .sdinfo = {0x00, 0x08, 0x10, 0x3F},
+ .has_int_sce = true,
+ },
+ },
};
-struct dio200_subdev_intr {
- unsigned int ofs;
- spinlock_t spinlock;
- int active;
- unsigned int valid_isns;
- unsigned int enabled_isns;
- unsigned int stopcount;
- int continuous;
-};
-
-static inline const struct dio200_layout *
-dio200_board_layout(const struct dio200_board *board)
-{
- return &dio200_layouts[board->layout];
-}
-
-static inline const struct dio200_layout *
-dio200_dev_layout(struct comedi_device *dev)
-{
- return dio200_board_layout(comedi_board(dev));
-}
-
-static inline bool is_pci_board(const struct dio200_board *board)
-{
- return DO_PCI && board->bustype == pci_bustype;
-}
-
-static inline bool is_isa_board(const struct dio200_board *board)
-{
- return DO_ISA && board->bustype == isa_bustype;
-}
-
-/*
- * Read 8-bit register.
- */
-static unsigned char dio200_read8(struct comedi_device *dev,
- unsigned int offset)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
-
- offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- return inb(devpriv->io.u.iobase + offset);
- else
- return readb(devpriv->io.u.membase + offset);
-}
-
-/*
- * Write 8-bit register.
- */
-static void dio200_write8(struct comedi_device *dev, unsigned int offset,
- unsigned char val)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
-
- offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- outb(val, devpriv->io.u.iobase + offset);
- else
- writeb(val, devpriv->io.u.membase + offset);
-}
-
-/*
- * Read 32-bit register.
- */
-static unsigned int dio200_read32(struct comedi_device *dev,
- unsigned int offset)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
-
- offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- return inl(devpriv->io.u.iobase + offset);
- else
- return readl(devpriv->io.u.membase + offset);
-}
-
-/*
- * Write 32-bit register.
- */
-static void dio200_write32(struct comedi_device *dev, unsigned int offset,
- unsigned int val)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
-
- offset <<= thisboard->mainshift;
- if (devpriv->io.regtype == io_regtype)
- outl(val, devpriv->io.u.iobase + offset);
- else
- writel(val, devpriv->io.u.membase + offset);
-}
-
-/*
- * This function looks for a board matching the supplied PCI device.
- */
-static const struct dio200_board *
-dio200_find_pci_board(struct pci_dev *pci_dev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(dio200_boards); i++)
- if (is_pci_board(&dio200_boards[i]) &&
- pci_dev->device == dio200_boards[i].devid)
- return &dio200_boards[i];
- return NULL;
-}
-
-/*
- * This function checks and requests an I/O region, reporting an error
- * if there is a conflict.
- */
-static int
-dio200_request_region(struct comedi_device *dev,
- unsigned long from, unsigned long extent)
-{
- if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
- dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n",
- from, extent);
- return -EIO;
- }
- return 0;
-}
-
-/*
- * 'insn_bits' function for an 'INTERRUPT' subdevice.
- */
-static int
-dio200_subdev_intr_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_intr *subpriv = s->private;
-
- if (layout->has_int_sce) {
- /* Just read the interrupt status register. */
- data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
- } else {
- /* No interrupt status register. */
- data[0] = 0;
- }
-
- return insn->n;
-}
-
-/*
- * Called to stop acquisition for an 'INTERRUPT' subdevice.
- */
-static void dio200_stop_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_intr *subpriv = s->private;
-
- subpriv->active = 0;
- subpriv->enabled_isns = 0;
- if (layout->has_int_sce)
- dio200_write8(dev, subpriv->ofs, 0);
-}
-
-/*
- * Called to start acquisition for an 'INTERRUPT' subdevice.
- */
-static int dio200_start_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int n;
- unsigned isn_bits;
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_intr *subpriv = s->private;
- struct comedi_cmd *cmd = &s->async->cmd;
- int retval = 0;
-
- if (!subpriv->continuous && subpriv->stopcount == 0) {
- /* An empty acquisition! */
- s->async->events |= COMEDI_CB_EOA;
- subpriv->active = 0;
- retval = 1;
- } else {
- /* Determine interrupt sources to enable. */
- isn_bits = 0;
- if (cmd->chanlist) {
- for (n = 0; n < cmd->chanlist_len; n++)
- isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
- }
- isn_bits &= subpriv->valid_isns;
- /* Enable interrupt sources. */
- subpriv->enabled_isns = isn_bits;
- if (layout->has_int_sce)
- dio200_write8(dev, subpriv->ofs, isn_bits);
- }
-
- return retval;
-}
-
-/*
- * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
- */
-static int
-dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum)
-{
- struct dio200_subdev_intr *subpriv;
- unsigned long flags;
- int event = 0;
-
- if (trignum != 0)
- return -EINVAL;
-
- subpriv = s->private;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- s->async->inttrig = NULL;
- if (subpriv->active)
- event = dio200_start_intr(dev, s);
-
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- if (event)
- comedi_event(dev, s);
-
- return 1;
-}
-
-/*
- * This is called from the interrupt service routine to handle a read
- * scan on an 'INTERRUPT' subdevice.
- */
-static int dio200_handle_read_intr(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_intr *subpriv = s->private;
- unsigned triggered;
- unsigned intstat;
- unsigned cur_enabled;
- unsigned int oldevents;
- unsigned long flags;
-
- triggered = 0;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- oldevents = s->async->events;
- if (layout->has_int_sce) {
- /*
- * Collect interrupt sources that have triggered and disable
- * them temporarily. Loop around until no extra interrupt
- * sources have triggered, at which point, the valid part of
- * the interrupt status register will read zero, clearing the
- * cause of the interrupt.
- *
- * Mask off interrupt sources already seen to avoid infinite
- * loop in case of misconfiguration.
- */
- cur_enabled = subpriv->enabled_isns;
- while ((intstat = (dio200_read8(dev, subpriv->ofs) &
- subpriv->valid_isns & ~triggered)) != 0) {
- triggered |= intstat;
- cur_enabled &= ~triggered;
- dio200_write8(dev, subpriv->ofs, cur_enabled);
- }
- } else {
- /*
- * No interrupt status register. Assume the single interrupt
- * source has triggered.
- */
- triggered = subpriv->enabled_isns;
- }
-
- if (triggered) {
- /*
- * Some interrupt sources have triggered and have been
- * temporarily disabled to clear the cause of the interrupt.
- *
- * Reenable them NOW to minimize the time they are disabled.
- */
- cur_enabled = subpriv->enabled_isns;
- if (layout->has_int_sce)
- dio200_write8(dev, subpriv->ofs, cur_enabled);
-
- if (subpriv->active) {
- /*
- * The command is still active.
- *
- * Ignore interrupt sources that the command isn't
- * interested in (just in case there's a race
- * condition).
- */
- if (triggered & subpriv->enabled_isns) {
- /* Collect scan data. */
- short val;
- unsigned int n, ch, len;
-
- val = 0;
- len = s->async->cmd.chanlist_len;
- for (n = 0; n < len; n++) {
- ch = CR_CHAN(s->async->cmd.chanlist[n]);
- if (triggered & (1U << ch))
- val |= (1U << n);
- }
- /* Write the scan to the buffer. */
- if (comedi_buf_put(s->async, val)) {
- s->async->events |= (COMEDI_CB_BLOCK |
- COMEDI_CB_EOS);
- } else {
- /* Error! Stop acquisition. */
- dio200_stop_intr(dev, s);
- s->async->events |= COMEDI_CB_ERROR
- | COMEDI_CB_OVERFLOW;
- comedi_error(dev, "buffer overflow");
- }
-
- /* Check for end of acquisition. */
- if (!subpriv->continuous) {
- /* stop_src == TRIG_COUNT */
- if (subpriv->stopcount > 0) {
- subpriv->stopcount--;
- if (subpriv->stopcount == 0) {
- s->async->events |=
- COMEDI_CB_EOA;
- dio200_stop_intr(dev,
- s);
- }
- }
- }
- }
- }
- }
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- if (oldevents != s->async->events)
- comedi_event(dev, s);
-
- return (triggered != 0);
-}
-
-/*
- * 'cancel' function for an 'INTERRUPT' subdevice.
- */
-static int dio200_subdev_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_intr *subpriv = s->private;
- unsigned long flags;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- if (subpriv->active)
- dio200_stop_intr(dev, s);
-
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- return 0;
-}
-
-/*
- * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
- */
-static int
-dio200_subdev_intr_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
-{
- int err = 0;
-
- /* Step 1 : check if triggers are trivially valid */
-
- err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
- err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
- err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
-
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
-
- err |= cfc_check_trigger_is_unique(cmd->start_src);
- err |= cfc_check_trigger_is_unique(cmd->stop_src);
-
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check if arguments are trivially valid */
-
- err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
- err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
-
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- /* any count allowed */
- break;
- case TRIG_NONE:
- err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
- break;
- default:
- break;
- }
-
- if (err)
- return 3;
-
- /* step 4: fix up any arguments */
-
- /* if (err) return 4; */
-
- return 0;
-}
-
-/*
- * 'do_cmd' function for an 'INTERRUPT' subdevice.
- */
-static int dio200_subdev_intr_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct comedi_cmd *cmd = &s->async->cmd;
- struct dio200_subdev_intr *subpriv = s->private;
- unsigned long flags;
- int event = 0;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- subpriv->active = 1;
-
- /* Set up end of acquisition. */
- switch (cmd->stop_src) {
- case TRIG_COUNT:
- subpriv->continuous = 0;
- subpriv->stopcount = cmd->stop_arg;
- break;
- default:
- /* TRIG_NONE */
- subpriv->continuous = 1;
- subpriv->stopcount = 0;
- break;
- }
-
- /* Set up start of acquisition. */
- switch (cmd->start_src) {
- case TRIG_INT:
- s->async->inttrig = dio200_inttrig_start_intr;
- break;
- default:
- /* TRIG_NOW */
- event = dio200_start_intr(dev, s);
- break;
- }
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
-
- if (event)
- comedi_event(dev, s);
-
- return 0;
-}
-
-/*
- * This function initializes an 'INTERRUPT' subdevice.
- */
-static int
-dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int offset, unsigned valid_isns)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_intr *subpriv;
-
- subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
- if (!subpriv)
- return -ENOMEM;
-
- subpriv->ofs = offset;
- subpriv->valid_isns = valid_isns;
- spin_lock_init(&subpriv->spinlock);
-
- if (layout->has_int_sce)
- /* Disable interrupt sources. */
- dio200_write8(dev, subpriv->ofs, 0);
-
- s->private = subpriv;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- if (layout->has_int_sce) {
- s->n_chan = DIO200_MAX_ISNS;
- s->len_chanlist = DIO200_MAX_ISNS;
- } else {
- /* No interrupt source register. Support single channel. */
- s->n_chan = 1;
- s->len_chanlist = 1;
- }
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = dio200_subdev_intr_insn_bits;
- s->do_cmdtest = dio200_subdev_intr_cmdtest;
- s->do_cmd = dio200_subdev_intr_cmd;
- s->cancel = dio200_subdev_intr_cancel;
-
- return 0;
-}
-
-/*
- * This function cleans up an 'INTERRUPT' subdevice.
- */
-static void
-dio200_subdev_intr_cleanup(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_intr *subpriv = s->private;
- kfree(subpriv);
-}
-
-/*
- * Interrupt service routine.
- */
-static irqreturn_t dio200_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct dio200_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- int handled;
-
- if (!dev->attached)
- return IRQ_NONE;
-
- if (devpriv->intr_sd >= 0) {
- s = &dev->subdevices[devpriv->intr_sd];
- handled = dio200_handle_read_intr(dev, s);
- } else {
- handled = 0;
- }
-
- return IRQ_RETVAL(handled);
-}
-
-/*
- * Read an '8254' counter subdevice channel.
- */
-static unsigned int
-dio200_subdev_8254_read_chan(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int chan)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
- unsigned int val;
-
- /* latch counter */
- val = chan << 6;
- dio200_write8(dev, subpriv->ofs + i8254_control_reg, val);
- /* read lsb, msb */
- val = dio200_read8(dev, subpriv->ofs + chan);
- val += dio200_read8(dev, subpriv->ofs + chan) << 8;
- return val;
-}
-
-/*
- * Write an '8254' subdevice channel.
- */
-static void
-dio200_subdev_8254_write_chan(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int chan,
- unsigned int count)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
-
- /* write lsb, msb */
- dio200_write8(dev, subpriv->ofs + chan, count & 0xff);
- dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff);
-}
-
-/*
- * Set mode of an '8254' subdevice channel.
- */
-static void
-dio200_subdev_8254_set_mode(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int chan,
- unsigned int mode)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
- unsigned int byte;
-
- byte = chan << 6;
- byte |= 0x30; /* access order: lsb, msb */
- byte |= (mode & 0xf); /* counter mode and BCD|binary */
- dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte);
-}
-
-/*
- * Read status byte of an '8254' counter subdevice channel.
- */
-static unsigned int
-dio200_subdev_8254_status(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int chan)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
-
- /* latch status */
- dio200_write8(dev, subpriv->ofs + i8254_control_reg,
- 0xe0 | (2 << chan));
- /* read status */
- return dio200_read8(dev, subpriv->ofs + chan);
-}
-
-/*
- * Handle 'insn_read' for an '8254' counter subdevice.
- */
-static int
-dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
- int chan = CR_CHAN(insn->chanspec);
- unsigned int n;
- unsigned long flags;
-
- for (n = 0; n < insn->n; n++) {
- spin_lock_irqsave(&subpriv->spinlock, flags);
- data[n] = dio200_subdev_8254_read_chan(dev, s, chan);
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
- }
- return insn->n;
-}
-
-/*
- * Handle 'insn_write' for an '8254' counter subdevice.
- */
-static int
-dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
- int chan = CR_CHAN(insn->chanspec);
- unsigned int n;
- unsigned long flags;
-
- for (n = 0; n < insn->n; n++) {
- spin_lock_irqsave(&subpriv->spinlock, flags);
- dio200_subdev_8254_write_chan(dev, s, chan, data[n]);
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
- }
- return insn->n;
-}
-
-/*
- * Set gate source for an '8254' counter subdevice channel.
- */
-static int
-dio200_subdev_8254_set_gate_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int counter_number,
- unsigned int gate_src)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_8254 *subpriv = s->private;
- unsigned char byte;
-
- if (!layout->has_clk_gat_sce)
- return -1;
- if (counter_number > 2)
- return -1;
- if (gate_src > (layout->has_enhancements ? 31 : 7))
- return -1;
-
- subpriv->gate_src[counter_number] = gate_src;
- byte = gat_sce(subpriv->which, counter_number, gate_src);
- dio200_write8(dev, subpriv->gat_sce_ofs, byte);
-
- return 0;
-}
-
-/*
- * Get gate source for an '8254' counter subdevice channel.
- */
-static int
-dio200_subdev_8254_get_gate_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int counter_number)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_8254 *subpriv = s->private;
-
- if (!layout->has_clk_gat_sce)
- return -1;
- if (counter_number > 2)
- return -1;
-
- return subpriv->gate_src[counter_number];
-}
-
-/*
- * Set clock source for an '8254' counter subdevice channel.
- */
-static int
-dio200_subdev_8254_set_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int counter_number,
- unsigned int clock_src)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_8254 *subpriv = s->private;
- unsigned char byte;
-
- if (!layout->has_clk_gat_sce)
- return -1;
- if (counter_number > 2)
- return -1;
- if (clock_src > (layout->has_enhancements ? 31 : 7))
- return -1;
-
- subpriv->clock_src[counter_number] = clock_src;
- byte = clk_sce(subpriv->which, counter_number, clock_src);
- dio200_write8(dev, subpriv->clk_sce_ofs, byte);
-
- return 0;
-}
-
-/*
- * Get clock source for an '8254' counter subdevice channel.
- */
-static int
-dio200_subdev_8254_get_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int counter_number,
- unsigned int *period_ns)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_8254 *subpriv = s->private;
- unsigned clock_src;
-
- if (!layout->has_clk_gat_sce)
- return -1;
- if (counter_number > 2)
- return -1;
-
- clock_src = subpriv->clock_src[counter_number];
- *period_ns = clock_period[clock_src];
- return clock_src;
-}
-
-/*
- * Handle 'insn_config' for an '8254' counter subdevice.
- */
-static int
-dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct dio200_subdev_8254 *subpriv = s->private;
- int ret = 0;
- int chan = CR_CHAN(insn->chanspec);
- unsigned long flags;
-
- spin_lock_irqsave(&subpriv->spinlock, flags);
- switch (data[0]) {
- case INSN_CONFIG_SET_COUNTER_MODE:
- if (data[1] > (I8254_MODE5 | I8254_BINARY))
- ret = -EINVAL;
- else
- dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
- break;
- case INSN_CONFIG_8254_READ_STATUS:
- data[1] = dio200_subdev_8254_status(dev, s, chan);
- break;
- case INSN_CONFIG_SET_GATE_SRC:
- ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
- if (ret < 0)
- ret = -EINVAL;
- break;
- case INSN_CONFIG_GET_GATE_SRC:
- ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
- if (ret < 0) {
- ret = -EINVAL;
- break;
- }
- data[2] = ret;
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
- if (ret < 0)
- ret = -EINVAL;
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
- if (ret < 0) {
- ret = -EINVAL;
- break;
- }
- data[1] = ret;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- spin_unlock_irqrestore(&subpriv->spinlock, flags);
- return ret < 0 ? ret : insn->n;
-}
-
-/*
- * This function initializes an '8254' counter subdevice.
- */
-static int
-dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int offset)
-{
- const struct dio200_layout *layout = dio200_dev_layout(dev);
- struct dio200_subdev_8254 *subpriv;
- unsigned int chan;
-
- subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
- if (!subpriv)
- return -ENOMEM;
-
- s->private = subpriv;
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 3;
- s->maxdata = 0xFFFF;
- s->insn_read = dio200_subdev_8254_read;
- s->insn_write = dio200_subdev_8254_write;
- s->insn_config = dio200_subdev_8254_config;
-
- spin_lock_init(&subpriv->spinlock);
- subpriv->ofs = offset;
- if (layout->has_clk_gat_sce) {
- /* Derive CLK_SCE and GAT_SCE register offsets from
- * 8254 offset. */
- subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3);
- subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3);
- subpriv->which = (offset >> 2) & 1;
- }
-
- /* Initialize channels. */
- for (chan = 0; chan < 3; chan++) {
- dio200_subdev_8254_set_mode(dev, s, chan,
- I8254_MODE0 | I8254_BINARY);
- if (layout->has_clk_gat_sce) {
- /* Gate source 0 is VCC (logic 1). */
- dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
- /* Clock source 0 is the dedicated clock input. */
- dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
- }
- }
-
- return 0;
-}
-
-/*
- * This function cleans up an '8254' counter subdevice.
- */
-static void
-dio200_subdev_8254_cleanup(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_intr *subpriv = s->private;
- kfree(subpriv);
-}
-
-/*
- * This function sets I/O directions for an '8255' DIO subdevice.
- */
-static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_8255 *subpriv = s->private;
- int config;
-
- config = CR_CW;
- /* 1 in io_bits indicates output, 1 in config indicates input */
- if (!(s->io_bits & 0x0000ff))
- config |= CR_A_IO;
- if (!(s->io_bits & 0x00ff00))
- config |= CR_B_IO;
- if (!(s->io_bits & 0x0f0000))
- config |= CR_C_LO_IO;
- if (!(s->io_bits & 0xf00000))
- config |= CR_C_HI_IO;
- dio200_write8(dev, subpriv->ofs + 3, config);
-}
-
-/*
- * Handle 'insn_bits' for an '8255' DIO subdevice.
- */
-static int dio200_subdev_8255_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct dio200_subdev_8255 *subpriv = s->private;
-
- if (data[0]) {
- s->state &= ~data[0];
- s->state |= (data[0] & data[1]);
- if (data[0] & 0xff)
- dio200_write8(dev, subpriv->ofs, s->state & 0xff);
- if (data[0] & 0xff00)
- dio200_write8(dev, subpriv->ofs + 1,
- (s->state >> 8) & 0xff);
- if (data[0] & 0xff0000)
- dio200_write8(dev, subpriv->ofs + 2,
- (s->state >> 16) & 0xff);
- }
- data[1] = dio200_read8(dev, subpriv->ofs);
- data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
- data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
- return 2;
-}
-
-/*
- * Handle 'insn_config' for an '8255' DIO subdevice.
- */
-static int dio200_subdev_8255_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int mask;
- unsigned int bits;
-
- mask = 1 << CR_CHAN(insn->chanspec);
- if (mask & 0x0000ff)
- bits = 0x0000ff;
- else if (mask & 0x00ff00)
- bits = 0x00ff00;
- else if (mask & 0x0f0000)
- bits = 0x0f0000;
- else
- bits = 0xf00000;
- switch (data[0]) {
- case INSN_CONFIG_DIO_INPUT:
- s->io_bits &= ~bits;
- break;
- case INSN_CONFIG_DIO_OUTPUT:
- s->io_bits |= bits;
- break;
- case INSN_CONFIG_DIO_QUERY:
- data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
- return insn->n;
- break;
- default:
- return -EINVAL;
- }
- dio200_subdev_8255_set_dir(dev, s);
- return 1;
-}
-
-/*
- * This function initializes an '8255' DIO subdevice.
- *
- * offset is the offset to the 8255 chip.
- */
-static int dio200_subdev_8255_init(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int offset)
-{
- struct dio200_subdev_8255 *subpriv;
-
- subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
- if (!subpriv)
- return -ENOMEM;
- subpriv->ofs = offset;
- s->private = subpriv;
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 24;
- s->range_table = &range_digital;
- s->maxdata = 1;
- s->insn_bits = dio200_subdev_8255_bits;
- s->insn_config = dio200_subdev_8255_config;
- s->state = 0;
- s->io_bits = 0;
- dio200_subdev_8255_set_dir(dev, s);
- return 0;
-}
-
-/*
- * This function cleans up an '8255' DIO subdevice.
- */
-static void dio200_subdev_8255_cleanup(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct dio200_subdev_8255 *subpriv = s->private;
-
- kfree(subpriv);
-}
-
-/*
- * Handle 'insn_read' for a timer subdevice.
- */
-static int dio200_subdev_timer_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- unsigned int n;
-
- for (n = 0; n < insn->n; n++)
- data[n] = dio200_read32(dev, DIO200_TS_COUNT);
- return n;
-}
-
-/*
- * Reset timer subdevice.
- */
-static void dio200_subdev_timer_reset(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- unsigned int clock;
-
- clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
- dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
- dio200_write32(dev, DIO200_TS_CONFIG, clock);
-}
-
-/*
- * Get timer subdevice clock source and period.
- */
-static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *src,
- unsigned int *period)
-{
- unsigned int clk;
-
- clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
- *src = clk;
- *period = (clk < ARRAY_SIZE(ts_clock_period)) ?
- ts_clock_period[clk] : 0;
-}
-
-/*
- * Set timer subdevice clock source.
- */
-static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int src)
-{
- if (src > TS_CONFIG_MAX_CLK_SRC)
- return -EINVAL;
- dio200_write32(dev, DIO200_TS_CONFIG, src);
- return 0;
-}
-
-/*
- * Handle 'insn_config' for a timer subdevice.
- */
-static int dio200_subdev_timer_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- int ret = 0;
-
- switch (data[0]) {
- case INSN_CONFIG_RESET:
- dio200_subdev_timer_reset(dev, s);
- break;
- case INSN_CONFIG_SET_CLOCK_SRC:
- ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
- if (ret < 0)
- ret = -EINVAL;
- break;
- case INSN_CONFIG_GET_CLOCK_SRC:
- dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret < 0 ? ret : insn->n;
-}
-
-/*
- * This function initializes a timer subdevice.
- *
- * Uses the timestamp timer registers. There is only one timestamp timer.
- */
-static int dio200_subdev_timer_init(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- s->type = COMEDI_SUBD_TIMER;
- s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
- s->n_chan = 1;
- s->maxdata = 0xFFFFFFFF;
- s->insn_read = dio200_subdev_timer_read;
- s->insn_config = dio200_subdev_timer_config;
- return 0;
-}
-
-/*
- * This function cleans up a timer subdevice.
- */
-static void dio200_subdev_timer_cleanup(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- /* Nothing to do. */
-}
-
-/*
- * This function does some special set-up for the PCIe boards
- * PCIe215, PCIe236, PCIe296.
- */
-static int dio200_pcie_board_setup(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- void __iomem *brbase;
- resource_size_t brlen;
-
- /*
- * The board uses Altera Cyclone IV with PCI-Express hard IP.
- * The FPGA configuration has the PCI-Express Avalon-MM Bridge
- * Control registers in PCI BAR 0, offset 0, and the length of
- * these registers is 0x4000.
- *
- * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
- * Enable" register at offset 0x50 to allow generation of PCIe
- * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
- */
- brlen = pci_resource_len(pcidev, 0);
- if (brlen < 0x4000 ||
- !(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
- dev_err(dev->class_dev, "error! bad PCI region!\n");
- return -EINVAL;
- }
- brbase = ioremap_nocache(pci_resource_start(pcidev, 0), brlen);
- if (!brbase) {
- dev_err(dev->class_dev, "error! failed to map registers!\n");
- return -ENOMEM;
- }
- writel(0x80, brbase + 0x50);
- iounmap(brbase);
- /* Enable "enhanced" features of board. */
- dio200_write8(dev, DIO200_ENHANCE, 1);
- return 0;
-}
-
-static void dio200_report_attach(struct comedi_device *dev, unsigned int irq)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- char tmpbuf[60];
- int tmplen;
-
- if (is_isa_board(thisboard))
- tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
- "(base %#lx) ", devpriv->io.u.iobase);
- else if (is_pci_board(thisboard))
- tmplen = scnprintf(tmpbuf, sizeof(tmpbuf),
- "(pci %s) ", pci_name(pcidev));
- else
- tmplen = 0;
- if (irq)
- tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen,
- "(irq %u%s) ", irq,
- (dev->irq ? "" : " UNAVAILABLE"));
- else
- tmplen += scnprintf(&tmpbuf[tmplen], sizeof(tmpbuf) - tmplen,
- "(no irq) ");
- dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf);
-}
-
-static int dio200_common_attach(struct comedi_device *dev, unsigned int irq,
- unsigned long req_irq_flags)
-{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
- const struct dio200_layout *layout = dio200_board_layout(thisboard);
- struct comedi_subdevice *s;
- int sdx;
- unsigned int n;
- int ret;
-
- devpriv->intr_sd = -1;
- dev->board_name = thisboard->name;
-
- ret = comedi_alloc_subdevices(dev, layout->n_subdevs);
- if (ret)
- return ret;
-
- for (n = 0; n < dev->n_subdevices; n++) {
- s = &dev->subdevices[n];
- switch (layout->sdtype[n]) {
- case sd_8254:
- /* counter subdevice (8254) */
- ret = dio200_subdev_8254_init(dev, s,
- layout->sdinfo[n]);
- if (ret < 0)
- return ret;
- break;
- case sd_8255:
- /* digital i/o subdevice (8255) */
- ret = dio200_subdev_8255_init(dev, s,
- layout->sdinfo[n]);
- if (ret < 0)
- return ret;
- break;
- case sd_intr:
- /* 'INTERRUPT' subdevice */
- if (irq) {
- ret = dio200_subdev_intr_init(dev, s,
- DIO200_INT_SCE,
- layout->sdinfo[n]
- );
- if (ret < 0)
- return ret;
- devpriv->intr_sd = n;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- break;
- case sd_timer:
- /* Only on PCIe boards. */
- if (DO_PCI) {
- ret = dio200_subdev_timer_init(dev, s);
- if (ret < 0)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
- break;
- default:
- s->type = COMEDI_SUBD_UNUSED;
- break;
- }
- }
- sdx = devpriv->intr_sd;
- if (sdx >= 0 && sdx < dev->n_subdevices)
- dev->read_subdev = &dev->subdevices[sdx];
- if (irq) {
- if (request_irq(irq, dio200_interrupt, req_irq_flags,
- DIO200_DRIVER_NAME, dev) >= 0) {
- dev->irq = irq;
- } else {
- dev_warn(dev->class_dev,
- "warning! irq %u unavailable!\n", irq);
- }
- }
- dio200_report_attach(dev, irq);
- return 1;
-}
-
-/*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board. If you specified a board_name array
- * in the driver structure, dev->board_ptr contains that
- * address.
- */
static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct dio200_board *thisboard = comedi_board(dev);
struct dio200_private *devpriv;
+ unsigned int irq;
int ret;
- dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n");
+ irq = it->options[1];
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- /* Process options and reserve resources according to bus type. */
- if (is_isa_board(thisboard)) {
- unsigned long iobase;
- unsigned int irq;
-
- iobase = it->options[0];
- irq = it->options[1];
- ret = dio200_request_region(dev, iobase, thisboard->mainsize);
- if (ret < 0)
- return ret;
- devpriv->io.u.iobase = iobase;
- devpriv->io.regtype = io_regtype;
- return dio200_common_attach(dev, irq, 0);
- } else if (is_pci_board(thisboard)) {
- dev_err(dev->class_dev,
- "Manual configuration of PCI board '%s' is not supported\n",
- thisboard->name);
- return -EIO;
- } else {
- dev_err(dev->class_dev, DIO200_DRIVER_NAME
- ": BUG! cannot determine board type!\n");
- return -EINVAL;
- }
-}
-
-/*
- * The auto_attach hook is called at PCI probe time via
- * comedi_pci_auto_config(). dev->board_ptr is NULL on entry.
- * There should be a board entry matching the supplied PCI device.
- */
-static int dio200_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- const struct dio200_board *thisboard;
- struct dio200_private *devpriv;
- resource_size_t base, len;
- unsigned int bar;
- int ret;
-
- if (!DO_PCI)
- return -EINVAL;
-
- dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n",
- pci_name(pci_dev));
-
- devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
- if (!devpriv)
- return -ENOMEM;
- dev->private = devpriv;
-
- dev->board_ptr = dio200_find_pci_board(pci_dev);
- if (dev->board_ptr == NULL) {
- dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
- return -EINVAL;
- }
- thisboard = comedi_board(dev);
- ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "error! cannot enable PCI device and request regions!\n");
+ ret = comedi_request_region(dev, it->options[0], thisboard->mainsize);
+ if (ret)
return ret;
- }
- bar = thisboard->mainbar;
- base = pci_resource_start(pci_dev, bar);
- len = pci_resource_len(pci_dev, bar);
- if (len < thisboard->mainsize) {
- dev_err(dev->class_dev, "error! PCI region size too small!\n");
- return -EINVAL;
- }
- if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) {
- devpriv->io.u.membase = ioremap_nocache(base, len);
- if (!devpriv->io.u.membase) {
- dev_err(dev->class_dev,
- "error! cannot remap registers\n");
- return -ENOMEM;
- }
- devpriv->io.regtype = mmio_regtype;
- } else {
- devpriv->io.u.iobase = (unsigned long)base;
- devpriv->io.regtype = io_regtype;
- }
- switch (thisboard->model) {
- case pcie215_model:
- case pcie236_model:
- case pcie296_model:
- ret = dio200_pcie_board_setup(dev);
- if (ret < 0)
- return ret;
- break;
- default:
- break;
- }
- return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
+ devpriv->io.u.iobase = dev->iobase;
+ devpriv->io.regtype = io_regtype;
+ return amplc_dio200_common_attach(dev, irq, 0);
}
static void dio200_detach(struct comedi_device *dev)
{
- const struct dio200_board *thisboard = comedi_board(dev);
- struct dio200_private *devpriv = dev->private;
- const struct dio200_layout *layout;
- unsigned n;
-
- if (!thisboard || !devpriv)
- return;
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->subdevices) {
- layout = dio200_board_layout(thisboard);
- for (n = 0; n < dev->n_subdevices; n++) {
- struct comedi_subdevice *s = &dev->subdevices[n];
- switch (layout->sdtype[n]) {
- case sd_8254:
- dio200_subdev_8254_cleanup(dev, s);
- break;
- case sd_8255:
- dio200_subdev_8255_cleanup(dev, s);
- break;
- case sd_intr:
- dio200_subdev_intr_cleanup(dev, s);
- break;
- case sd_timer:
- /* Only on PCIe boards. */
- if (DO_PCI)
- dio200_subdev_timer_cleanup(dev, s);
- break;
- default:
- break;
- }
- }
- }
- if (is_isa_board(thisboard)) {
- if (devpriv->io.regtype == io_regtype)
- release_region(devpriv->io.u.iobase,
- thisboard->mainsize);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- if (pcidev) {
- if (devpriv->io.regtype != no_regtype) {
- if (devpriv->io.regtype == mmio_regtype)
- iounmap(devpriv->io.u.membase);
- comedi_pci_disable(pcidev);
- }
- }
- }
+ amplc_dio200_common_detach(dev);
+ comedi_legacy_detach(dev);
}
-/*
- * The struct comedi_driver structure tells the Comedi core module
- * which functions to call to configure/deconfigure (attach/detach)
- * the board, and also about the kernel module that contains
- * the device code.
- */
static struct comedi_driver amplc_dio200_driver = {
- .driver_name = DIO200_DRIVER_NAME,
+ .driver_name = "amplc_dio200",
.module = THIS_MODULE,
.attach = dio200_attach,
- .auto_attach = dio200_auto_attach,
.detach = dio200_detach,
- .board_name = &dio200_boards[0].name,
+ .board_name = &dio200_isa_boards[0].name,
.offset = sizeof(struct dio200_board),
- .num_names = ARRAY_SIZE(dio200_boards),
-};
-
-#if DO_PCI
-static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215) },
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296) },
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, dio200_pci_table);
-
-static int amplc_dio200_pci_probe(struct pci_dev *dev,
- const struct pci_device_id
- *ent)
-{
- return comedi_pci_auto_config(dev, &amplc_dio200_driver);
-}
-
-static struct pci_driver amplc_dio200_pci_driver = {
- .name = DIO200_DRIVER_NAME,
- .id_table = dio200_pci_table,
- .probe = &amplc_dio200_pci_probe,
- .remove = comedi_pci_auto_unconfig,
+ .num_names = ARRAY_SIZE(dio200_isa_boards),
};
-module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver);
-#else
module_comedi_driver(amplc_dio200_driver);
-#endif
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Amplicon 200 Series ISA DIO boards");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h
new file mode 100644
index 00000000000..cf2e7261740
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_dio200.h
@@ -0,0 +1,95 @@
+/*
+ comedi/drivers/amplc_dio.h
+
+ Header for amplc_dio200.c, amplc_dio200_common.c and
+ amplc_dio200_pci.c.
+
+ Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ 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.
+
+*/
+
+#ifndef AMPLC_DIO200_H_INCLUDED
+#define AMPLC_DIO200_H_INCLUDED
+
+/* 200 series register area sizes */
+#define DIO200_IO_SIZE 0x20
+#define DIO200_PCIE_IO_SIZE 0x4000
+
+/*
+ * Register region.
+ */
+enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype };
+struct dio200_region {
+ union {
+ unsigned long iobase; /* I/O base address */
+ unsigned char __iomem *membase; /* mapped MMIO base address */
+ } u;
+ enum dio200_regtype regtype;
+};
+
+/*
+ * Subdevice types.
+ */
+enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer };
+
+#define DIO200_MAX_SUBDEVS 8
+#define DIO200_MAX_ISNS 6
+
+/*
+ * Board descriptions.
+ */
+
+struct dio200_layout {
+ unsigned short n_subdevs; /* number of subdevices */
+ unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
+ unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
+ bool has_int_sce:1; /* has interrupt enable/status reg */
+ bool has_clk_gat_sce:1; /* has clock/gate selection registers */
+ bool has_enhancements:1; /* has enhanced features */
+};
+
+enum dio200_bustype { isa_bustype, pci_bustype };
+
+struct dio200_board {
+ const char *name;
+ struct dio200_layout layout;
+ enum dio200_bustype bustype;
+ unsigned char mainbar;
+ unsigned char mainshift;
+ unsigned int mainsize;
+};
+
+/*
+ * Comedi device private data.
+ */
+struct dio200_private {
+ struct dio200_region io; /* Register region */
+ int intr_sd;
+};
+
+int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
+ unsigned long req_irq_flags);
+
+void amplc_dio200_common_detach(struct comedi_device *dev);
+
+/* Used by initialization of PCIe boards. */
+void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val);
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c
new file mode 100644
index 00000000000..3403e5ccfa9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c
@@ -0,0 +1,1271 @@
+/*
+ comedi/drivers/amplc_dio200_common.c
+
+ Common support code for "amplc_dio200" and "amplc_dio200_pci".
+
+ Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ 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.
+
+*/
+
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#include "../comedidev.h"
+
+#include "amplc_dio200.h"
+#include "comedi_fc.h"
+#include "8253.h"
+
+/* 8255 control register bits */
+#define CR_C_LO_IO 0x01
+#define CR_B_IO 0x02
+#define CR_B_MODE 0x04
+#define CR_C_HI_IO 0x08
+#define CR_A_IO 0x10
+#define CR_A_MODE(a) ((a)<<5)
+#define CR_CW 0x80
+
+/* 200 series registers */
+#define DIO200_IO_SIZE 0x20
+#define DIO200_PCIE_IO_SIZE 0x4000
+#define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
+#define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
+#define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
+#define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
+#define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
+#define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
+#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
+/* Extra registers for new PCIe boards */
+#define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */
+#define DIO200_VERSION 0x24 /* Hardware version register */
+#define DIO200_TS_CONFIG 0x600 /* Timestamp timer config register */
+#define DIO200_TS_COUNT 0x602 /* Timestamp timer count register */
+
+/*
+ * Functions for constructing value for DIO_200_?CLK_SCE and
+ * DIO_200_?GAT_SCE registers:
+ *
+ * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
+ * 'chan' is the channel: 0, 1 or 2.
+ * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards.
+ */
+static unsigned char clk_gat_sce(unsigned int which, unsigned int chan,
+ unsigned int source)
+{
+ return (which << 5) | (chan << 3) |
+ ((source & 030) << 3) | (source & 007);
+}
+
+static unsigned char clk_sce(unsigned int which, unsigned int chan,
+ unsigned int source)
+{
+ return clk_gat_sce(which, chan, source);
+}
+
+static unsigned char gat_sce(unsigned int which, unsigned int chan,
+ unsigned int source)
+{
+ return clk_gat_sce(which, chan, source);
+}
+
+/*
+ * Periods of the internal clock sources in nanoseconds.
+ */
+static const unsigned int clock_period[32] = {
+ [1] = 100, /* 10 MHz */
+ [2] = 1000, /* 1 MHz */
+ [3] = 10000, /* 100 kHz */
+ [4] = 100000, /* 10 kHz */
+ [5] = 1000000, /* 1 kHz */
+ [11] = 50, /* 20 MHz (enhanced boards) */
+ /* clock sources 12 and later reserved for enhanced boards */
+};
+
+/*
+ * Timestamp timer configuration register (for new PCIe boards).
+ */
+#define TS_CONFIG_RESET 0x100 /* Reset counter to zero. */
+#define TS_CONFIG_CLK_SRC_MASK 0x0FF /* Clock source. */
+#define TS_CONFIG_MAX_CLK_SRC 2 /* Maximum clock source value. */
+
+/*
+ * Periods of the timestamp timer clock sources in nanoseconds.
+ */
+static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = {
+ 1, /* 1 nanosecond (but with 20 ns granularity). */
+ 1000, /* 1 microsecond. */
+ 1000000, /* 1 millisecond. */
+};
+
+struct dio200_subdev_8254 {
+ unsigned int ofs; /* Counter base offset */
+ unsigned int clk_sce_ofs; /* CLK_SCE base address */
+ unsigned int gat_sce_ofs; /* GAT_SCE base address */
+ int which; /* Bit 5 of CLK_SCE or GAT_SCE */
+ unsigned int clock_src[3]; /* Current clock sources */
+ unsigned int gate_src[3]; /* Current gate sources */
+ spinlock_t spinlock;
+};
+
+struct dio200_subdev_8255 {
+ unsigned int ofs; /* DIO base offset */
+};
+
+struct dio200_subdev_intr {
+ spinlock_t spinlock;
+ unsigned int ofs;
+ unsigned int valid_isns;
+ unsigned int enabled_isns;
+ unsigned int stopcount;
+ bool active:1;
+ bool continuous:1;
+};
+
+static inline const struct dio200_layout *
+dio200_board_layout(const struct dio200_board *board)
+{
+ return &board->layout;
+}
+
+static inline const struct dio200_layout *
+dio200_dev_layout(struct comedi_device *dev)
+{
+ return dio200_board_layout(comedi_board(dev));
+}
+
+/*
+ * Read 8-bit register.
+ */
+static unsigned char dio200_read8(struct comedi_device *dev,
+ unsigned int offset)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ return inb(devpriv->io.u.iobase + offset);
+ else
+ return readb(devpriv->io.u.membase + offset);
+}
+
+/*
+ * Write 8-bit register.
+ */
+static void dio200_write8(struct comedi_device *dev, unsigned int offset,
+ unsigned char val)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ outb(val, devpriv->io.u.iobase + offset);
+ else
+ writeb(val, devpriv->io.u.membase + offset);
+}
+
+/*
+ * Read 32-bit register.
+ */
+static unsigned int dio200_read32(struct comedi_device *dev,
+ unsigned int offset)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ return inl(devpriv->io.u.iobase + offset);
+ else
+ return readl(devpriv->io.u.membase + offset);
+}
+
+/*
+ * Write 32-bit register.
+ */
+static void dio200_write32(struct comedi_device *dev, unsigned int offset,
+ unsigned int val)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ offset <<= thisboard->mainshift;
+ if (devpriv->io.regtype == io_regtype)
+ outl(val, devpriv->io.u.iobase + offset);
+ else
+ writel(val, devpriv->io.u.membase + offset);
+}
+
+/*
+ * 'insn_bits' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (layout->has_int_sce) {
+ /* Just read the interrupt status register. */
+ data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns;
+ } else {
+ /* No interrupt status register. */
+ data[0] = 0;
+ }
+
+ return insn->n;
+}
+
+/*
+ * Called to stop acquisition for an 'INTERRUPT' subdevice.
+ */
+static void dio200_stop_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ subpriv->active = false;
+ subpriv->enabled_isns = 0;
+ if (layout->has_int_sce)
+ dio200_write8(dev, subpriv->ofs, 0);
+}
+
+/*
+ * Called to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int dio200_start_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ unsigned int n;
+ unsigned isn_bits;
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_intr *subpriv = s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval = 0;
+
+ if (!subpriv->continuous && subpriv->stopcount == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->active = false;
+ retval = 1;
+ } else {
+ /* Determine interrupt sources to enable. */
+ isn_bits = 0;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++)
+ isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ }
+ isn_bits &= subpriv->valid_isns;
+ /* Enable interrupt sources. */
+ subpriv->enabled_isns = isn_bits;
+ if (layout->has_int_sce)
+ dio200_write8(dev, subpriv->ofs, isn_bits);
+ }
+
+ return retval;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
+ unsigned int trignum)
+{
+ struct dio200_subdev_intr *subpriv;
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ subpriv = s->private;
+
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ s->async->inttrig = NULL;
+ if (subpriv->active)
+ event = dio200_start_intr(dev, s);
+
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (event)
+ comedi_event(dev, s);
+
+ return 1;
+}
+
+static void dio200_read_scan_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int triggered)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned short val;
+ unsigned int n, ch, len;
+
+ val = 0;
+ len = s->async->cmd.chanlist_len;
+ for (n = 0; n < len; n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (triggered & (1U << ch))
+ val |= (1U << n);
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, val)) {
+ s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+ } else {
+ /* Error! Stop acquisition. */
+ dio200_stop_intr(dev, s);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+ comedi_error(dev, "buffer overflow");
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->continuous) {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->stopcount > 0) {
+ subpriv->stopcount--;
+ if (subpriv->stopcount == 0) {
+ s->async->events |= COMEDI_CB_EOA;
+ dio200_stop_intr(dev, s);
+ }
+ }
+ }
+}
+
+/*
+ * This is called from the interrupt service routine to handle a read
+ * scan on an 'INTERRUPT' subdevice.
+ */
+static int dio200_handle_read_intr(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned triggered;
+ unsigned intstat;
+ unsigned cur_enabled;
+ unsigned int oldevents;
+ unsigned long flags;
+
+ triggered = 0;
+
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ oldevents = s->async->events;
+ if (layout->has_int_sce) {
+ /*
+ * Collect interrupt sources that have triggered and disable
+ * them temporarily. Loop around until no extra interrupt
+ * sources have triggered, at which point, the valid part of
+ * the interrupt status register will read zero, clearing the
+ * cause of the interrupt.
+ *
+ * Mask off interrupt sources already seen to avoid infinite
+ * loop in case of misconfiguration.
+ */
+ cur_enabled = subpriv->enabled_isns;
+ while ((intstat = (dio200_read8(dev, subpriv->ofs) &
+ subpriv->valid_isns & ~triggered)) != 0) {
+ triggered |= intstat;
+ cur_enabled &= ~triggered;
+ dio200_write8(dev, subpriv->ofs, cur_enabled);
+ }
+ } else {
+ /*
+ * No interrupt status register. Assume the single interrupt
+ * source has triggered.
+ */
+ triggered = subpriv->enabled_isns;
+ }
+
+ if (triggered) {
+ /*
+ * Some interrupt sources have triggered and have been
+ * temporarily disabled to clear the cause of the interrupt.
+ *
+ * Reenable them NOW to minimize the time they are disabled.
+ */
+ cur_enabled = subpriv->enabled_isns;
+ if (layout->has_int_sce)
+ dio200_write8(dev, subpriv->ofs, cur_enabled);
+
+ if (subpriv->active) {
+ /*
+ * The command is still active.
+ *
+ * Ignore interrupt sources that the command isn't
+ * interested in (just in case there's a race
+ * condition).
+ */
+ if (triggered & subpriv->enabled_isns)
+ /* Collect scan data. */
+ dio200_read_scan_intr(dev, s, triggered);
+ }
+ }
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (oldevents != s->async->events)
+ comedi_event(dev, s);
+
+ return (triggered != 0);
+}
+
+/*
+ * 'cancel' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned long flags;
+
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ if (subpriv->active)
+ dio200_stop_intr(dev, s);
+
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
+{
+ int err = 0;
+
+ /* Step 1 : check if triggers are trivially valid */
+
+ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+
+ if (err)
+ return 1;
+
+ /* Step 2a : make sure trigger sources are unique */
+
+ err |= cfc_check_trigger_is_unique(cmd->start_src);
+ err |= cfc_check_trigger_is_unique(cmd->stop_src);
+
+ /* Step 2b : and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* Step 3: check if arguments are trivially valid */
+
+ err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+ err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cmd(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned long flags;
+ int event = 0;
+
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ subpriv->active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->continuous = false;
+ subpriv->stopcount = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->continuous = true;
+ subpriv->stopcount = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = dio200_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = dio200_start_intr(dev, s);
+ break;
+ }
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (event)
+ comedi_event(dev, s);
+
+ return 0;
+}
+
+/*
+ * This function initializes an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
+ unsigned int offset, unsigned valid_isns)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_intr *subpriv;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv)
+ return -ENOMEM;
+
+ subpriv->ofs = offset;
+ subpriv->valid_isns = valid_isns;
+ spin_lock_init(&subpriv->spinlock);
+
+ if (layout->has_int_sce)
+ /* Disable interrupt sources. */
+ dio200_write8(dev, subpriv->ofs, 0);
+
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ if (layout->has_int_sce) {
+ s->n_chan = DIO200_MAX_ISNS;
+ s->len_chanlist = DIO200_MAX_ISNS;
+ } else {
+ /* No interrupt source register. Support single channel. */
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ }
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = dio200_subdev_intr_insn_bits;
+ s->do_cmdtest = dio200_subdev_intr_cmdtest;
+ s->do_cmd = dio200_subdev_intr_cmd;
+ s->cancel = dio200_subdev_intr_cancel;
+
+ return 0;
+}
+
+/*
+ * Interrupt service routine.
+ */
+static irqreturn_t dio200_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct dio200_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+ int handled;
+
+ if (!dev->attached)
+ return IRQ_NONE;
+
+ if (devpriv->intr_sd >= 0) {
+ s = &dev->subdevices[devpriv->intr_sd];
+ handled = dio200_handle_read_intr(dev, s);
+ } else {
+ handled = 0;
+ }
+
+ return IRQ_RETVAL(handled);
+}
+
+/*
+ * Read an '8254' counter subdevice channel.
+ */
+static unsigned int
+dio200_subdev_8254_read_chan(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned int val;
+
+ /* latch counter */
+ val = chan << 6;
+ dio200_write8(dev, subpriv->ofs + i8254_control_reg, val);
+ /* read lsb, msb */
+ val = dio200_read8(dev, subpriv->ofs + chan);
+ val += dio200_read8(dev, subpriv->ofs + chan) << 8;
+ return val;
+}
+
+/*
+ * Write an '8254' subdevice channel.
+ */
+static void
+dio200_subdev_8254_write_chan(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan,
+ unsigned int count)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+
+ /* write lsb, msb */
+ dio200_write8(dev, subpriv->ofs + chan, count & 0xff);
+ dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff);
+}
+
+/*
+ * Set mode of an '8254' subdevice channel.
+ */
+static void
+dio200_subdev_8254_set_mode(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan,
+ unsigned int mode)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned int byte;
+
+ byte = chan << 6;
+ byte |= 0x30; /* access order: lsb, msb */
+ byte |= (mode & 0xf); /* counter mode and BCD|binary */
+ dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte);
+}
+
+/*
+ * Read status byte of an '8254' counter subdevice channel.
+ */
+static unsigned int
+dio200_subdev_8254_status(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int chan)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+
+ /* latch status */
+ dio200_write8(dev, subpriv->ofs + i8254_control_reg,
+ 0xe0 | (2 << chan));
+ /* read status */
+ return dio200_read8(dev, subpriv->ofs + chan);
+}
+
+/*
+ * Handle 'insn_read' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int n;
+ unsigned long flags;
+
+ for (n = 0; n < insn->n; n++) {
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ data[n] = dio200_subdev_8254_read_chan(dev, s, chan);
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+ }
+ return insn->n;
+}
+
+/*
+ * Handle 'insn_write' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int n;
+ unsigned long flags;
+
+ for (n = 0; n < insn->n; n++) {
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ dio200_subdev_8254_write_chan(dev, s, chan, data[n]);
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+ }
+ return insn->n;
+}
+
+/*
+ * Set gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_subdev_8254_set_gate_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number,
+ unsigned int gate_src)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned char byte;
+
+ if (!layout->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+ if (gate_src > (layout->has_enhancements ? 31 : 7))
+ return -1;
+
+ subpriv->gate_src[counter_number] = gate_src;
+ byte = gat_sce(subpriv->which, counter_number, gate_src);
+ dio200_write8(dev, subpriv->gat_sce_ofs, byte);
+
+ return 0;
+}
+
+/*
+ * Get gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_subdev_8254_get_gate_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
+
+ if (!layout->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+
+ return subpriv->gate_src[counter_number];
+}
+
+/*
+ * Set clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_subdev_8254_set_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number,
+ unsigned int clock_src)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned char byte;
+
+ if (!layout->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+ if (clock_src > (layout->has_enhancements ? 31 : 7))
+ return -1;
+
+ subpriv->clock_src[counter_number] = clock_src;
+ byte = clk_sce(subpriv->which, counter_number, clock_src);
+ dio200_write8(dev, subpriv->clk_sce_ofs, byte);
+
+ return 0;
+}
+
+/*
+ * Get clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_subdev_8254_get_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int counter_number,
+ unsigned int *period_ns)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv = s->private;
+ unsigned clock_src;
+
+ if (!layout->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+
+ clock_src = subpriv->clock_src[counter_number];
+ *period_ns = clock_period[clock_src];
+ return clock_src;
+}
+
+/*
+ * Handle 'insn_config' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int ret = 0;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned long flags;
+
+ spin_lock_irqsave(&subpriv->spinlock, flags);
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ if (data[1] > (I8254_MODE5 | I8254_BINARY))
+ ret = -EINVAL;
+ else
+ dio200_subdev_8254_set_mode(dev, s, chan, data[1]);
+ break;
+ case INSN_CONFIG_8254_READ_STATUS:
+ data[1] = dio200_subdev_8254_status(dev, s, chan);
+ break;
+ case INSN_CONFIG_SET_GATE_SRC:
+ ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]);
+ if (ret < 0)
+ ret = -EINVAL;
+ break;
+ case INSN_CONFIG_GET_GATE_SRC:
+ ret = dio200_subdev_8254_get_gate_src(dev, s, chan);
+ if (ret < 0) {
+ ret = -EINVAL;
+ break;
+ }
+ data[2] = ret;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]);
+ if (ret < 0)
+ ret = -EINVAL;
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]);
+ if (ret < 0) {
+ ret = -EINVAL;
+ break;
+ }
+ data[1] = ret;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ spin_unlock_irqrestore(&subpriv->spinlock, flags);
+ return ret < 0 ? ret : insn->n;
+}
+
+/*
+ * This function initializes an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
+ unsigned int offset)
+{
+ const struct dio200_layout *layout = dio200_dev_layout(dev);
+ struct dio200_subdev_8254 *subpriv;
+ unsigned int chan;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv)
+ return -ENOMEM;
+
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xFFFF;
+ s->insn_read = dio200_subdev_8254_read;
+ s->insn_write = dio200_subdev_8254_write;
+ s->insn_config = dio200_subdev_8254_config;
+
+ spin_lock_init(&subpriv->spinlock);
+ subpriv->ofs = offset;
+ if (layout->has_clk_gat_sce) {
+ /* Derive CLK_SCE and GAT_SCE register offsets from
+ * 8254 offset. */
+ subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3);
+ subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3);
+ subpriv->which = (offset >> 2) & 1;
+ }
+
+ /* Initialize channels. */
+ for (chan = 0; chan < 3; chan++) {
+ dio200_subdev_8254_set_mode(dev, s, chan,
+ I8254_MODE0 | I8254_BINARY);
+ if (layout->has_clk_gat_sce) {
+ /* Gate source 0 is VCC (logic 1). */
+ dio200_subdev_8254_set_gate_src(dev, s, chan, 0);
+ /* Clock source 0 is the dedicated clock input. */
+ dio200_subdev_8254_set_clock_src(dev, s, chan, 0);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function sets I/O directions for an '8255' DIO subdevice.
+ */
+static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dio200_subdev_8255 *subpriv = s->private;
+ int config;
+
+ config = CR_CW;
+ /* 1 in io_bits indicates output, 1 in config indicates input */
+ if (!(s->io_bits & 0x0000ff))
+ config |= CR_A_IO;
+ if (!(s->io_bits & 0x00ff00))
+ config |= CR_B_IO;
+ if (!(s->io_bits & 0x0f0000))
+ config |= CR_C_LO_IO;
+ if (!(s->io_bits & 0xf00000))
+ config |= CR_C_HI_IO;
+ dio200_write8(dev, subpriv->ofs + 3, config);
+}
+
+/*
+ * Handle 'insn_bits' for an '8255' DIO subdevice.
+ */
+static int dio200_subdev_8255_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ struct dio200_subdev_8255 *subpriv = s->private;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ if (data[0] & 0xff)
+ dio200_write8(dev, subpriv->ofs, s->state & 0xff);
+ if (data[0] & 0xff00)
+ dio200_write8(dev, subpriv->ofs + 1,
+ (s->state >> 8) & 0xff);
+ if (data[0] & 0xff0000)
+ dio200_write8(dev, subpriv->ofs + 2,
+ (s->state >> 16) & 0xff);
+ }
+ data[1] = dio200_read8(dev, subpriv->ofs);
+ data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
+ data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
+ return 2;
+}
+
+/*
+ * Handle 'insn_config' for an '8255' DIO subdevice.
+ */
+static int dio200_subdev_8255_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int mask;
+ unsigned int bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x0000ff)
+ bits = 0x0000ff;
+ else if (mask & 0x00ff00)
+ bits = 0x00ff00;
+ else if (mask & 0x0f0000)
+ bits = 0x0f0000;
+ else
+ bits = 0xf00000;
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+ dio200_subdev_8255_set_dir(dev, s);
+ return 1;
+}
+
+/*
+ * This function initializes an '8255' DIO subdevice.
+ *
+ * offset is the offset to the 8255 chip.
+ */
+static int dio200_subdev_8255_init(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int offset)
+{
+ struct dio200_subdev_8255 *subpriv;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv)
+ return -ENOMEM;
+ subpriv->ofs = offset;
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 24;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = dio200_subdev_8255_bits;
+ s->insn_config = dio200_subdev_8255_config;
+ s->state = 0;
+ s->io_bits = 0;
+ dio200_subdev_8255_set_dir(dev, s);
+ return 0;
+}
+
+/*
+ * Handle 'insn_read' for a timer subdevice.
+ */
+static int dio200_subdev_timer_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int n;
+
+ for (n = 0; n < insn->n; n++)
+ data[n] = dio200_read32(dev, DIO200_TS_COUNT);
+ return n;
+}
+
+/*
+ * Reset timer subdevice.
+ */
+static void dio200_subdev_timer_reset(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ unsigned int clock;
+
+ clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
+ dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET);
+ dio200_write32(dev, DIO200_TS_CONFIG, clock);
+}
+
+/*
+ * Get timer subdevice clock source and period.
+ */
+static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *src,
+ unsigned int *period)
+{
+ unsigned int clk;
+
+ clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK;
+ *src = clk;
+ *period = (clk < ARRAY_SIZE(ts_clock_period)) ?
+ ts_clock_period[clk] : 0;
+}
+
+/*
+ * Set timer subdevice clock source.
+ */
+static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int src)
+{
+ if (src > TS_CONFIG_MAX_CLK_SRC)
+ return -EINVAL;
+ dio200_write32(dev, DIO200_TS_CONFIG, src);
+ return 0;
+}
+
+/*
+ * Handle 'insn_config' for a timer subdevice.
+ */
+static int dio200_subdev_timer_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ int ret = 0;
+
+ switch (data[0]) {
+ case INSN_CONFIG_RESET:
+ dio200_subdev_timer_reset(dev, s);
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]);
+ if (ret < 0)
+ ret = -EINVAL;
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret < 0 ? ret : insn->n;
+}
+
+/*
+ * This function initializes a timer subdevice.
+ *
+ * Uses the timestamp timer registers. There is only one timestamp timer.
+ */
+static int dio200_subdev_timer_init(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 1;
+ s->maxdata = 0xFFFFFFFF;
+ s->insn_read = dio200_subdev_timer_read;
+ s->insn_config = dio200_subdev_timer_config;
+ return 0;
+}
+
+void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val)
+{
+ dio200_write8(dev, DIO200_ENHANCE, val);
+}
+EXPORT_SYMBOL_GPL(amplc_dio200_set_enhance);
+
+int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq,
+ unsigned long req_irq_flags)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+ const struct dio200_layout *layout = dio200_board_layout(thisboard);
+ struct comedi_subdevice *s;
+ int sdx;
+ unsigned int n;
+ int ret;
+
+ devpriv->intr_sd = -1;
+
+ ret = comedi_alloc_subdevices(dev, layout->n_subdevs);
+ if (ret)
+ return ret;
+
+ for (n = 0; n < dev->n_subdevices; n++) {
+ s = &dev->subdevices[n];
+ switch (layout->sdtype[n]) {
+ case sd_8254:
+ /* counter subdevice (8254) */
+ ret = dio200_subdev_8254_init(dev, s,
+ layout->sdinfo[n]);
+ if (ret < 0)
+ return ret;
+ break;
+ case sd_8255:
+ /* digital i/o subdevice (8255) */
+ ret = dio200_subdev_8255_init(dev, s,
+ layout->sdinfo[n]);
+ if (ret < 0)
+ return ret;
+ break;
+ case sd_intr:
+ /* 'INTERRUPT' subdevice */
+ if (irq) {
+ ret = dio200_subdev_intr_init(dev, s,
+ DIO200_INT_SCE,
+ layout->sdinfo[n]
+ );
+ if (ret < 0)
+ return ret;
+ devpriv->intr_sd = n;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ break;
+ case sd_timer:
+ ret = dio200_subdev_timer_init(dev, s);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ s->type = COMEDI_SUBD_UNUSED;
+ break;
+ }
+ }
+ sdx = devpriv->intr_sd;
+ if (sdx >= 0 && sdx < dev->n_subdevices)
+ dev->read_subdev = &dev->subdevices[sdx];
+ if (irq) {
+ if (request_irq(irq, dio200_interrupt, req_irq_flags,
+ dev->board_name, dev) >= 0) {
+ dev->irq = irq;
+ } else {
+ dev_warn(dev->class_dev,
+ "warning! irq %u unavailable!\n", irq);
+ }
+ }
+ dev_info(dev->class_dev, "attached\n");
+ return 0;
+}
+EXPORT_SYMBOL_GPL(amplc_dio200_common_attach);
+
+void amplc_dio200_common_detach(struct comedi_device *dev)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+ const struct dio200_layout *layout;
+ unsigned n;
+
+ if (!thisboard || !devpriv)
+ return;
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (dev->subdevices) {
+ layout = dio200_board_layout(thisboard);
+ for (n = 0; n < dev->n_subdevices; n++) {
+ switch (layout->sdtype[n]) {
+ case sd_8254:
+ case sd_8255:
+ case sd_intr:
+ comedi_spriv_free(dev, n);
+ break;
+ case sd_timer:
+ default:
+ break;
+ }
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(amplc_dio200_common_detach);
+
+static int __init amplc_dio200_common_init(void)
+{
+ return 0;
+}
+module_init(amplc_dio200_common_init);
+
+static void __exit amplc_dio200_common_exit(void)
+{
+}
+module_exit(amplc_dio200_common_exit);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi helper for amplc_dio200 and amplc_dio200_pci");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
new file mode 100644
index 00000000000..4be44e87737
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
@@ -0,0 +1,486 @@
+/* comedi/drivers/amplc_dio200_pci.c
+
+ Driver for Amplicon PCI215, PCI272, PCIe215, PCIe236, PCIe296.
+
+ Copyright (C) 2005-2013 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ 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: amplc_dio200_pci
+ * Description: Amplicon 200 Series PCI Digital I/O
+ * Author: Ian Abbott <abbotti@mev.co.uk>
+ * Devices: [Amplicon] PCI215 (amplc_dio200_pci), PCIe215, PCIe236,
+ * PCI272, PCIe296
+ * Updated: Mon, 18 Mar 2013 15:03:50 +0000
+ * Status: works
+ *
+ * Configuration options:
+ * none
+ *
+ * Manual configuration of PCI(e) cards is not supported; they are configured
+ * automatically.
+ *
+ * SUBDEVICES
+ *
+ * PCI215 PCIe215 PCIe236
+ * ------------- ------------- -------------
+ * Subdevices 5 8 8
+ * 0 PPI-X PPI-X PPI-X
+ * 1 PPI-Y UNUSED UNUSED
+ * 2 CTR-Z1 PPI-Y UNUSED
+ * 3 CTR-Z2 UNUSED UNUSED
+ * 4 INTERRUPT CTR-Z1 CTR-Z1
+ * 5 CTR-Z2 CTR-Z2
+ * 6 TIMER TIMER
+ * 7 INTERRUPT INTERRUPT
+ *
+ *
+ * PCI272 PCIe296
+ * ------------- -------------
+ * Subdevices 4 8
+ * 0 PPI-X PPI-X1
+ * 1 PPI-Y PPI-X2
+ * 2 PPI-Z PPI-Y1
+ * 3 INTERRUPT PPI-Y2
+ * 4 CTR-Z1
+ * 5 CTR-Z2
+ * 6 TIMER
+ * 7 INTERRUPT
+ *
+ * Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
+ * are configurable as inputs or outputs in four groups:
+ *
+ * Port A - channels 0 to 7
+ * Port B - channels 8 to 15
+ * Port CL - channels 16 to 19
+ * Port CH - channels 20 to 23
+ *
+ * Only mode 0 of the 8255 chips is supported.
+ *
+ * Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
+ * channel is configured individually with INSN_CONFIG instructions. The
+ * specific type of configuration instruction is specified in data[0].
+ * Some configuration instructions expect an additional parameter in
+ * data[1]; others return a value in data[1]. The following configuration
+ * instructions are supported:
+ *
+ * INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
+ * BCD/binary setting specified in data[1].
+ *
+ * INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
+ * counter channel into data[1].
+ *
+ * INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
+ * specified in data[1] (this is a hardware-specific value). Not
+ * supported on PC214E. For the other boards, valid clock sources are
+ * 0 to 7 as follows:
+ *
+ * 0. CLK n, the counter channel's dedicated CLK input from the SK1
+ * connector. (N.B. for other values, the counter channel's CLKn
+ * pin on the SK1 connector is an output!)
+ * 1. Internal 10 MHz clock.
+ * 2. Internal 1 MHz clock.
+ * 3. Internal 100 kHz clock.
+ * 4. Internal 10 kHz clock.
+ * 5. Internal 1 kHz clock.
+ * 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
+ * 7. Ext Clock, the counter chip's dedicated Ext Clock input from
+ * the SK1 connector. This pin is shared by all three counter
+ * channels on the chip.
+ *
+ * For the PCIe boards, clock sources in the range 0 to 31 are allowed
+ * and the following additional clock sources are defined:
+ *
+ * 8. HIGH logic level.
+ * 9. LOW logic level.
+ * 10. "Pattern present" signal.
+ * 11. Internal 20 MHz clock.
+ *
+ * INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
+ * clock source in data[1]. For internal clock sources, data[2] is set
+ * to the period in ns.
+ *
+ * INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
+ * specified in data[2] (this is a hardware-specific value). Not
+ * supported on PC214E. For the other boards, valid gate sources are 0
+ * to 7 as follows:
+ *
+ * 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
+ * 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
+ * 2. GAT n, the counter channel's dedicated GAT input from the SK1
+ * connector. (N.B. for other values, the counter channel's GATn
+ * pin on the SK1 connector is an output!)
+ * 3. /OUT n-2, the inverted output of counter channel n-2 (see note
+ * 2 below).
+ * 4. Reserved.
+ * 5. Reserved.
+ * 6. Reserved.
+ * 7. Reserved.
+ *
+ * For the PCIe boards, gate sources in the range 0 to 31 are allowed;
+ * the following additional clock sources and clock sources 6 and 7 are
+ * (re)defined:
+ *
+ * 6. /GAT n, negated version of the counter channel's dedicated
+ * GAT input (negated version of gate source 2).
+ * 7. OUT n-2, the non-inverted output of counter channel n-2
+ * (negated version of gate source 3).
+ * 8. "Pattern present" signal, HIGH while pattern present.
+ * 9. "Pattern occurred" latched signal, latches HIGH when pattern
+ * occurs.
+ * 10. "Pattern gone away" latched signal, latches LOW when pattern
+ * goes away after it occurred.
+ * 11. Negated "pattern present" signal, LOW while pattern present
+ * (negated version of gate source 8).
+ * 12. Negated "pattern occurred" latched signal, latches LOW when
+ * pattern occurs (negated version of gate source 9).
+ * 13. Negated "pattern gone away" latched signal, latches LOW when
+ * pattern goes away after it occurred (negated version of gate
+ * source 10).
+ *
+ * INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
+ * source in data[2].
+ *
+ * Clock and gate interconnection notes:
+ *
+ * 1. Clock source OUT n-1 is the output of the preceding channel on the
+ * same counter subdevice if n > 0, or the output of channel 2 on the
+ * preceding counter subdevice (see note 3) if n = 0.
+ *
+ * 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
+ * same counter subdevice if n = 2, or the inverted output of channel n+1
+ * on the preceding counter subdevice (see note 3) if n < 2.
+ *
+ * 3. The counter subdevices are connected in a ring, so the highest
+ * counter subdevice precedes the lowest.
+ *
+ * The 'TIMER' subdevice is a free-running 32-bit timer subdevice.
+ *
+ * The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
+ * digital inputs come from the interrupt status register. The number of
+ * channels matches the number of interrupt sources. The PC214E does not
+ * have an interrupt status register; see notes on 'INTERRUPT SOURCES'
+ * below.
+ *
+ * INTERRUPT SOURCES
+ *
+ * PCI215 PCIe215 PCIe236
+ * ------------- ------------- -------------
+ * Sources 6 6 6
+ * 0 PPI-X-C0 PPI-X-C0 PPI-X-C0
+ * 1 PPI-X-C3 PPI-X-C3 PPI-X-C3
+ * 2 PPI-Y-C0 PPI-Y-C0 unused
+ * 3 PPI-Y-C3 PPI-Y-C3 unused
+ * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1
+ * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1
+ *
+ * PCI272 PCIe296
+ * ------------- -------------
+ * Sources 6 6
+ * 0 PPI-X-C0 PPI-X1-C0
+ * 1 PPI-X-C3 PPI-X1-C3
+ * 2 PPI-Y-C0 PPI-Y1-C0
+ * 3 PPI-Y-C3 PPI-Y1-C3
+ * 4 PPI-Z-C0 CTR-Z1-OUT1
+ * 5 PPI-Z-C3 CTR-Z2-OUT1
+ *
+ * When an interrupt source is enabled in the interrupt source enable
+ * register, a rising edge on the source signal latches the corresponding
+ * bit to 1 in the interrupt status register.
+ *
+ * When the interrupt status register value as a whole (actually, just the
+ * 6 least significant bits) goes from zero to non-zero, the board will
+ * generate an interrupt. The interrupt will remain asserted until the
+ * interrupt status register is cleared to zero. To clear a bit to zero in
+ * the interrupt status register, the corresponding interrupt source must
+ * be disabled in the interrupt source enable register (there is no
+ * separate interrupt clear register).
+ *
+ * COMMANDS
+ *
+ * The driver supports a read streaming acquisition command on the
+ * 'INTERRUPT' subdevice. The channel list selects the interrupt sources
+ * to be enabled. All channels will be sampled together (convert_src ==
+ * TRIG_NOW). The scan begins a short time after the hardware interrupt
+ * occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
+ * scan_begin_arg == 0). The value read from the interrupt status register
+ * is packed into a short value, one bit per requested channel, in the
+ * order they appear in the channel list.
+ */
+
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#include "../comedidev.h"
+
+#include "amplc_dio200.h"
+
+/* PCI IDs */
+#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
+#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
+#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011
+#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012
+#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014
+
+/*
+ * Board descriptions.
+ */
+
+enum dio200_pci_model {
+ pci215_model,
+ pci272_model,
+ pcie215_model,
+ pcie236_model,
+ pcie296_model
+};
+
+static const struct dio200_board dio200_pci_boards[] = {
+ [pci215_model] = {
+ .name = "pci215",
+ .bustype = pci_bustype,
+ .mainbar = 2,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 5,
+ .sdtype = {sd_8255, sd_8255, sd_8254, sd_8254, sd_intr},
+ .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ },
+ },
+ [pci272_model] = {
+ .name = "pci272",
+ .bustype = pci_bustype,
+ .mainbar = 2,
+ .mainsize = DIO200_IO_SIZE,
+ .layout = {
+ .n_subdevs = 4,
+ .sdtype = {sd_8255, sd_8255, sd_8255, sd_intr},
+ .sdinfo = {0x00, 0x08, 0x10, 0x3F},
+ .has_int_sce = true,
+ },
+ },
+ [pcie215_model] = {
+ .name = "pcie215",
+ .bustype = pci_bustype,
+ .mainbar = 1,
+ .mainshift = 3,
+ .mainsize = DIO200_PCIE_IO_SIZE,
+ .layout = {
+ .n_subdevs = 8,
+ .sdtype = {sd_8255, sd_none, sd_8255, sd_none,
+ sd_8254, sd_8254, sd_timer, sd_intr},
+ .sdinfo = {0x00, 0x00, 0x08, 0x00,
+ 0x10, 0x14, 0x00, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ .has_enhancements = true,
+ },
+ },
+ [pcie236_model] = {
+ .name = "pcie236",
+ .bustype = pci_bustype,
+ .mainbar = 1,
+ .mainshift = 3,
+ .mainsize = DIO200_PCIE_IO_SIZE,
+ .layout = {
+ .n_subdevs = 8,
+ .sdtype = {sd_8255, sd_none, sd_none, sd_none,
+ sd_8254, sd_8254, sd_timer, sd_intr},
+ .sdinfo = {0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x14, 0x00, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ .has_enhancements = true,
+ },
+ },
+ [pcie296_model] = {
+ .name = "pcie296",
+ .bustype = pci_bustype,
+ .mainbar = 1,
+ .mainshift = 3,
+ .mainsize = DIO200_PCIE_IO_SIZE,
+ .layout = {
+ .n_subdevs = 8,
+ .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255,
+ sd_8254, sd_8254, sd_timer, sd_intr},
+ .sdinfo = {0x00, 0x04, 0x08, 0x0C,
+ 0x10, 0x14, 0x00, 0x3F},
+ .has_int_sce = true,
+ .has_clk_gat_sce = true,
+ .has_enhancements = true,
+ },
+ },
+};
+
+/*
+ * This function does some special set-up for the PCIe boards
+ * PCIe215, PCIe236, PCIe296.
+ */
+static int dio200_pcie_board_setup(struct comedi_device *dev)
+{
+ struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ void __iomem *brbase;
+
+ /*
+ * The board uses Altera Cyclone IV with PCI-Express hard IP.
+ * The FPGA configuration has the PCI-Express Avalon-MM Bridge
+ * Control registers in PCI BAR 0, offset 0, and the length of
+ * these registers is 0x4000.
+ *
+ * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt
+ * Enable" register at offset 0x50 to allow generation of PCIe
+ * interrupts when RXmlrq_i is asserted in the SOPC Builder system.
+ */
+ if (pci_resource_len(pcidev, 0) < 0x4000) {
+ dev_err(dev->class_dev, "error! bad PCI region!\n");
+ return -EINVAL;
+ }
+ brbase = pci_ioremap_bar(pcidev, 0);
+ if (!brbase) {
+ dev_err(dev->class_dev, "error! failed to map registers!\n");
+ return -ENOMEM;
+ }
+ writel(0x80, brbase + 0x50);
+ iounmap(brbase);
+ /* Enable "enhanced" features of board. */
+ amplc_dio200_set_enhance(dev, 1);
+ return 0;
+}
+
+static int dio200_pci_auto_attach(struct comedi_device *dev,
+ unsigned long context_model)
+{
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ const struct dio200_board *thisboard = NULL;
+ struct dio200_private *devpriv;
+ unsigned int bar;
+ int ret;
+
+ if (context_model < ARRAY_SIZE(dio200_pci_boards))
+ thisboard = &dio200_pci_boards[context_model];
+ if (!thisboard)
+ return -EINVAL;
+ dev->board_ptr = thisboard;
+ dev->board_name = thisboard->name;
+
+ dev_info(dev->class_dev, "%s: attach pci %s (%s)\n",
+ dev->driver->driver_name, pci_name(pci_dev), dev->board_name);
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_pci_enable(dev);
+ if (ret)
+ return ret;
+
+ bar = thisboard->mainbar;
+ if (pci_resource_len(pci_dev, bar) < thisboard->mainsize) {
+ dev_err(dev->class_dev, "error! PCI region size too small!\n");
+ return -EINVAL;
+ }
+ if (pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) {
+ devpriv->io.u.membase = pci_ioremap_bar(pci_dev, bar);
+ if (!devpriv->io.u.membase) {
+ dev_err(dev->class_dev,
+ "error! cannot remap registers\n");
+ return -ENOMEM;
+ }
+ devpriv->io.regtype = mmio_regtype;
+ } else {
+ devpriv->io.u.iobase = pci_resource_start(pci_dev, bar);
+ devpriv->io.regtype = io_regtype;
+ }
+ switch (context_model) {
+ case pcie215_model:
+ case pcie236_model:
+ case pcie296_model:
+ ret = dio200_pcie_board_setup(dev);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ break;
+ }
+ return amplc_dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED);
+}
+
+static void dio200_pci_detach(struct comedi_device *dev)
+{
+ const struct dio200_board *thisboard = comedi_board(dev);
+ struct dio200_private *devpriv = dev->private;
+
+ if (!thisboard || !devpriv)
+ return;
+ amplc_dio200_common_detach(dev);
+ if (devpriv->io.regtype == mmio_regtype)
+ iounmap(devpriv->io.u.membase);
+ comedi_pci_disable(dev);
+}
+
+static struct comedi_driver dio200_pci_comedi_driver = {
+ .driver_name = "amplc_dio200_pci",
+ .module = THIS_MODULE,
+ .auto_attach = dio200_pci_auto_attach,
+ .detach = dio200_pci_detach,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
+ {
+ PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215),
+ pci215_model
+ }, {
+ PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272),
+ pci272_model
+ }, {
+ PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236),
+ pcie236_model
+ }, {
+ PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215),
+ pcie215_model
+ }, {
+ PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296),
+ pcie296_model
+ },
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, dio200_pci_table);
+
+static int dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &dio200_pci_comedi_driver,
+ id->driver_data);
+}
+
+static struct pci_driver dio200_pci_pci_driver = {
+ .name = "amplc_dio200_pci",
+ .id_table = dio200_pci_table,
+ .probe = dio200_pci_probe,
+ .remove = comedi_pci_auto_unconfig,
+};
+module_comedi_pci_driver(dio200_pci_comedi_driver, dio200_pci_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi driver for Amplicon 200 Series PCI(e) DIO boards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index 479e10fddd2..115ecd51677 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -75,23 +75,19 @@ unused.
#define PC236_IO_SIZE 4
#define PC236_LCR_IO_SIZE 128
-/*
- * INTCSR values for PCI236.
- */
-/* Disable interrupt, also clear any interrupt there */
-#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1ENAB_DISABLED \
- | PLX9052_INTCSR_LI1POL_HIGH \
- | PLX9052_INTCSR_LI2POL_HIGH \
- | PLX9052_INTCSR_PCIENAB_DISABLED \
- | PLX9052_INTCSR_LI1SEL_EDGE \
- | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
-/* Enable interrupt, also clear any interrupt there. */
-#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB_ENABLED \
- | PLX9052_INTCSR_LI1POL_HIGH \
- | PLX9052_INTCSR_LI2POL_HIGH \
- | PLX9052_INTCSR_PCIENAB_ENABLED \
- | PLX9052_INTCSR_LI1SEL_EDGE \
- | PLX9052_INTCSR_LI1CLRINT_ASSERTED)
+/* Disable, and clear, interrupts */
+#define PCI236_INTR_DISABLE (PLX9052_INTCSR_LI1POL | \
+ PLX9052_INTCSR_LI2POL | \
+ PLX9052_INTCSR_LI1SEL | \
+ PLX9052_INTCSR_LI1CLRINT)
+
+/* Enable, and clear, interrupts */
+#define PCI236_INTR_ENABLE (PLX9052_INTCSR_LI1ENAB | \
+ PLX9052_INTCSR_LI1POL | \
+ PLX9052_INTCSR_LI2POL | \
+ PLX9052_INTCSR_PCIENAB | \
+ PLX9052_INTCSR_LI1SEL | \
+ PLX9052_INTCSR_LI1CLRINT)
/*
* Board descriptions for Amplicon PC36AT and PCI236.
@@ -209,21 +205,6 @@ static struct pci_dev *pc236_find_pci_dev(struct comedi_device *dev,
}
/*
- * This function checks and requests an I/O region, reporting an error
- * if there is a conflict.
- */
-static int pc236_request_region(struct comedi_device *dev, unsigned long from,
- unsigned long extent)
-{
- if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
- dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n",
- from, extent);
- return -EIO;
- }
- return 0;
-}
-
-/*
* This function is called to mark the interrupt as disabled (no command
* configured on subdevice 1) and to physically disable the interrupt
* (not possible on the PC36AT, except by removing the IRQ jumper!).
@@ -272,14 +253,14 @@ static int pc236_intr_check(struct comedi_device *dev)
struct pc236_private *devpriv = dev->private;
int retval = 0;
unsigned long flags;
+ unsigned int intcsr;
spin_lock_irqsave(&dev->spinlock, flags);
if (devpriv->enable_irq) {
retval = 1;
if (is_pci_board(thisboard)) {
- if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
- & PLX9052_INTCSR_LI1STAT_MASK)
- == PLX9052_INTCSR_LI1STAT_INACTIVE) {
+ intcsr = inl(devpriv->lcr_iobase + PLX9052_INTCSR);
+ if (!(intcsr & PLX9052_INTCSR_LI1STAT)) {
retval = 0;
} else {
/* Clear interrupt and keep it enabled. */
@@ -470,12 +451,10 @@ static int pc236_pci_common_attach(struct comedi_device *dev,
comedi_set_hw_dev(dev, &pci_dev->dev);
- ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "error! cannot enable PCI device and request regions!\n");
+ ret = comedi_pci_enable(dev);
+ if (ret)
return ret;
- }
+
devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
iobase = pci_resource_start(pci_dev, 2);
return pc236_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED);
@@ -493,8 +472,6 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct pc236_private *devpriv;
int ret;
- dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n");
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
@@ -502,12 +479,11 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* Process options according to bus type. */
if (is_isa_board(thisboard)) {
- unsigned long iobase = it->options[0];
- unsigned int irq = it->options[1];
- ret = pc236_request_region(dev, iobase, PC236_IO_SIZE);
- if (ret < 0)
+ ret = comedi_request_region(dev, it->options[0], PC236_IO_SIZE);
+ if (ret)
return ret;
- return pc236_common_attach(dev, iobase, irq, 0);
+
+ return pc236_common_attach(dev, dev->iobase, it->options[1], 0);
} else if (is_pci_board(thisboard)) {
struct pci_dev *pci_dev;
@@ -567,20 +543,16 @@ static void pc236_detach(struct comedi_device *dev)
return;
if (dev->iobase)
pc236_intr_disable(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[0]);
+ comedi_spriv_free(dev, 0);
if (is_isa_board(thisboard)) {
- if (dev->iobase)
- release_region(dev->iobase, PC236_IO_SIZE);
+ comedi_legacy_detach(dev);
} else if (is_pci_board(thisboard)) {
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ comedi_pci_disable(dev);
+ if (pcidev)
pci_dev_put(pcidev);
- }
}
}
@@ -610,9 +582,10 @@ static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
MODULE_DEVICE_TABLE(pci, pc236_pci_table);
static int amplc_pc236_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &amplc_pc236_driver);
+ return comedi_pci_auto_config(dev, &amplc_pc236_driver,
+ id->driver_data);
}
static struct pci_driver amplc_pc236_pci_driver = {
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index 11c1f4764ea..94a752d852b 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -24,163 +24,41 @@
*/
/*
Driver: amplc_pc263
-Description: Amplicon PC263, PCI263
+Description: Amplicon PC263
Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PC263 (pc263), PCI263 (pci263 or amplc_pc263)
-Updated: Wed, 22 Oct 2008 14:10:53 +0100
+Devices: [Amplicon] PC263 (pc263)
+Updated: Fri, 12 Apr 2013 15:19:36 +0100
Status: works
-Configuration options - PC263:
+Configuration options:
[0] - I/O port base address
-Configuration options - PCI263:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, the first available PCI device will be
- used.
-
-Each board appears as one subdevice, with 16 digital outputs, each
+The board appears as one subdevice, with 16 digital outputs, each
connected to a reed-relay. Relay contacts are closed when output is 1.
The state of the outputs can be read.
*/
-#include <linux/pci.h>
-
#include "../comedidev.h"
#define PC263_DRIVER_NAME "amplc_pc263"
-#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_ISA)
-#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI)
-
-/* PCI263 PCI configuration register information */
-#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
-#define PCI_DEVICE_ID_INVALID 0xffff
-
-/* PC263 / PCI263 registers */
+/* PC263 registers */
#define PC263_IO_SIZE 2
/*
- * Board descriptions for Amplicon PC263 / PCI263.
+ * Board descriptions for Amplicon PC263.
*/
-enum pc263_bustype { isa_bustype, pci_bustype };
-enum pc263_model { pc263_model, pci263_model, anypci_model };
-
struct pc263_board {
const char *name;
- unsigned short devid;
- enum pc263_bustype bustype;
- enum pc263_model model;
};
+
static const struct pc263_board pc263_boards[] = {
-#if DO_ISA
{
.name = "pc263",
- .bustype = isa_bustype,
- .model = pc263_model,
},
-#endif
-#if DO_PCI
- {
- .name = "pci263",
- .devid = PCI_DEVICE_ID_AMPLICON_PCI263,
- .bustype = pci_bustype,
- .model = pci263_model,
- },
- {
- .name = PC263_DRIVER_NAME,
- .devid = PCI_DEVICE_ID_INVALID,
- .bustype = pci_bustype,
- .model = anypci_model, /* wildcard */
- },
-#endif
};
-/* test if ISA supported and this is an ISA board */
-static inline bool is_isa_board(const struct pc263_board *board)
-{
- return DO_ISA && board->bustype == isa_bustype;
-}
-
-/* test if PCI supported and this is a PCI board */
-static inline bool is_pci_board(const struct pc263_board *board)
-{
- return DO_PCI && board->bustype == pci_bustype;
-}
-
-/*
- * This function looks for a board matching the supplied PCI device.
- */
-static const struct pc263_board *pc263_find_pci_board(struct pci_dev *pci_dev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pc263_boards); i++)
- if (is_pci_board(&pc263_boards[i]) &&
- pci_dev->device == pc263_boards[i].devid)
- return &pc263_boards[i];
- return NULL;
-}
-
-
-/*
- * This function looks for a PCI device matching the requested board name,
- * bus and slot.
- */
-static struct pci_dev *pc263_find_pci_dev(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct pc263_board *thisboard = comedi_board(dev);
- struct pci_dev *pci_dev = NULL;
- int bus = it->options[0];
- int slot = it->options[1];
-
- for_each_pci_dev(pci_dev) {
- if (bus || slot) {
- if (bus != pci_dev->bus->number ||
- slot != PCI_SLOT(pci_dev->devfn))
- continue;
- }
- if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
- continue;
-
- if (thisboard->model == anypci_model) {
- /* Wildcard board matches any supported PCI board. */
- const struct pc263_board *foundboard;
-
- foundboard = pc263_find_pci_board(pci_dev);
- if (foundboard == NULL)
- continue;
- /* Replace wildcard board_ptr. */
- dev->board_ptr = thisboard = foundboard;
- } else {
- /* Match specific model name. */
- if (pci_dev->device != thisboard->devid)
- continue;
- }
- return pci_dev;
- }
- dev_err(dev->class_dev,
- "No supported board found! (req. bus %d, slot %d)\n",
- bus, slot);
- return NULL;
-}
-/*
- * This function checks and requests an I/O region, reporting an error
- * if there is a conflict.
- */
-static int pc263_request_region(struct comedi_device *dev, unsigned long from,
- unsigned long extent)
-{
- if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) {
- dev_err(dev->class_dev, "I/O port conflict (%#lx,%lu)!\n",
- from, extent);
- return -EIO;
- }
- return 0;
-}
-
static int pc263_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
@@ -197,30 +75,14 @@ static int pc263_do_insn_bits(struct comedi_device *dev,
return insn->n;
}
-static void pc263_report_attach(struct comedi_device *dev)
-{
- const struct pc263_board *thisboard = comedi_board(dev);
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- char tmpbuf[40];
-
- if (is_isa_board(thisboard))
- snprintf(tmpbuf, sizeof(tmpbuf), "(base %#lx) ", dev->iobase);
- else if (is_pci_board(thisboard))
- snprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ",
- pci_name(pcidev));
- else
- tmpbuf[0] = '\0';
- dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf);
-}
-
-static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase)
+static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct pc263_board *thisboard = comedi_board(dev);
struct comedi_subdevice *s;
int ret;
- dev->board_name = thisboard->name;
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], PC263_IO_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
@@ -237,154 +99,23 @@ static int pc263_common_attach(struct comedi_device *dev, unsigned long iobase)
/* read initial relay state */
s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8);
- pc263_report_attach(dev);
- return 1;
-}
-
-static int pc263_pci_common_attach(struct comedi_device *dev,
- struct pci_dev *pci_dev)
-{
- unsigned long iobase;
- int ret;
-
- comedi_set_hw_dev(dev, &pci_dev->dev);
-
- ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "error! cannot enable PCI device and request regions!\n");
- return ret;
- }
- iobase = pci_resource_start(pci_dev, 2);
- return pc263_common_attach(dev, iobase);
-}
-
-/*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board. If you specified a board_name array
- * in the driver structure, dev->board_ptr contains that
- * address.
- */
-static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
- const struct pc263_board *thisboard = comedi_board(dev);
- int ret;
-
- dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach\n");
-
- /* Process options and reserve resources according to bus type. */
- if (is_isa_board(thisboard)) {
- unsigned long iobase = it->options[0];
- ret = pc263_request_region(dev, iobase, PC263_IO_SIZE);
- if (ret < 0)
- return ret;
- return pc263_common_attach(dev, iobase);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pci_dev;
-
- pci_dev = pc263_find_pci_dev(dev, it);
- if (!pci_dev)
- return -EIO;
- return pc263_pci_common_attach(dev, pci_dev);
- } else {
- dev_err(dev->class_dev, PC263_DRIVER_NAME
- ": BUG! cannot determine board type!\n");
- return -EINVAL;
- }
-}
-
-/*
- * The auto_attach hook is called at PCI probe time via
- * comedi_pci_auto_config(). dev->board_ptr is NULL on entry.
- * There should be a board entry matching the supplied PCI device.
- */
-static int pc263_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev;
-
- if (!DO_PCI)
- return -EINVAL;
-
- pci_dev = comedi_to_pci_dev(dev);
- dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach pci %s\n",
- pci_name(pci_dev));
- dev->board_ptr = pc263_find_pci_board(pci_dev);
- if (dev->board_ptr == NULL) {
- dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
- return -EINVAL;
- }
- /*
- * Need to 'get' the PCI device to match the 'put' in pc263_detach().
- * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
- * support for manual attachment of PCI devices via pc263_attach()
- * has been removed.
- */
- pci_dev_get(pci_dev);
- return pc263_pci_common_attach(dev, pci_dev);
-}
-
-static void pc263_detach(struct comedi_device *dev)
-{
- const struct pc263_board *thisboard = comedi_board(dev);
-
- if (!thisboard)
- return;
- if (is_isa_board(thisboard)) {
- if (dev->iobase)
- release_region(dev->iobase, PC263_IO_SIZE);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
- }
- }
+ dev_info(dev->class_dev, "%s (base %#lx) attached\n", dev->board_name,
+ dev->iobase);
+ return 0;
}
-/*
- * The struct comedi_driver structure tells the Comedi core module
- * which functions to call to configure/deconfigure (attach/detach)
- * the board, and also about the kernel module that contains
- * the device code.
- */
static struct comedi_driver amplc_pc263_driver = {
.driver_name = PC263_DRIVER_NAME,
.module = THIS_MODULE,
.attach = pc263_attach,
- .auto_attach = pc263_auto_attach,
- .detach = pc263_detach,
+ .detach = comedi_legacy_detach,
.board_name = &pc263_boards[0].name,
.offset = sizeof(struct pc263_board),
.num_names = ARRAY_SIZE(pc263_boards),
};
-#if DO_PCI
-static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) },
- {0}
-};
-MODULE_DEVICE_TABLE(pci, pc263_pci_table);
-
-static int amplc_pc263_pci_probe(struct pci_dev *dev,
- const struct pci_device_id
- *ent)
-{
- return comedi_pci_auto_config(dev, &amplc_pc263_driver);
-}
-
-static struct pci_driver amplc_pc263_pci_driver = {
- .name = PC263_DRIVER_NAME,
- .id_table = pc263_pci_table,
- .probe = &amplc_pc263_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-module_comedi_pci_driver(amplc_pc263_driver, amplc_pc263_pci_driver);
-#else
module_comedi_driver(amplc_pc263_driver);
-#endif
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Amplicon PC263 relay board");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index c9da4cd74ba..4d7eab9b556 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -1280,13 +1280,10 @@ static int pci224_attach_common(struct comedi_device *dev,
comedi_set_hw_dev(dev, &pci_dev->dev);
- ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
- if (ret < 0) {
- dev_err(dev->class_dev,
- "error! cannot enable PCI device and request regions!\n"
- );
+ ret = comedi_pci_enable(dev);
+ if (ret)
return ret;
- }
+
spin_lock_init(&devpriv->ao_spinlock);
devpriv->iobase1 = pci_resource_start(pci_dev, 2);
@@ -1488,11 +1485,9 @@ static void pci224_detach(struct comedi_device *dev)
kfree(devpriv->ao_scan_vals);
kfree(devpriv->ao_scan_order);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ comedi_pci_disable(dev);
+ if (pcidev)
pci_dev_put(pcidev);
- }
}
static struct comedi_driver amplc_pci224_driver = {
@@ -1507,10 +1502,10 @@ static struct comedi_driver amplc_pci224_driver = {
};
static int amplc_pci224_pci_probe(struct pci_dev *dev,
- const struct pci_device_id
- *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &amplc_pci224_driver);
+ return comedi_pci_auto_config(dev, &amplc_pci224_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index e2244c6e536..49200fbd60b 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -2645,12 +2645,11 @@ static int pci230_attach_common(struct comedi_device *dev,
comedi_set_hw_dev(dev, &pci_dev->dev);
dev->board_name = thisboard->name;
- /* Enable PCI device and reserve I/O spaces. */
- if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
- dev_err(dev->class_dev,
- "failed to enable PCI device and request regions\n");
- return -EIO;
- }
+
+ rc = comedi_pci_enable(dev);
+ if (rc)
+ return rc;
+
/* Read base addresses of the PCI230's two I/O regions from PCI
* configuration register. */
iobase1 = pci_resource_start(pci_dev, 2);
@@ -2833,18 +2832,14 @@ static int pci230_auto_attach(struct comedi_device *dev,
static void pci230_detach(struct comedi_device *dev)
{
- const struct pci230_board *thisboard = comedi_board(dev);
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- if (dev->subdevices && thisboard->have_dio)
- subdev_8255_cleanup(dev, &dev->subdevices[2]);
+ comedi_spriv_free(dev, 2);
if (dev->irq)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ comedi_pci_disable(dev);
+ if (pcidev)
pci_dev_put(pcidev);
- }
}
static struct comedi_driver amplc_pci230_driver = {
@@ -2859,9 +2854,10 @@ static struct comedi_driver amplc_pci230_driver = {
};
static int amplc_pci230_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &amplc_pci230_driver);
+ return comedi_pci_auto_config(dev, &amplc_pci230_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c
new file mode 100644
index 00000000000..8b57533bf40
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci263.c
@@ -0,0 +1,127 @@
+/*
+ comedi/drivers/amplc_pci263.c
+ Driver for Amplicon PCI263 relay board.
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ 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: amplc_pci263
+Description: Amplicon PCI263
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PCI263 (amplc_pci263)
+Updated: Fri, 12 Apr 2013 15:19:36 +0100
+Status: works
+
+Configuration options: not applicable, uses PCI auto config
+
+The board appears as one subdevice, with 16 digital outputs, each
+connected to a reed-relay. Relay contacts are closed when output is 1.
+The state of the outputs can be read.
+*/
+
+#include <linux/pci.h>
+
+#include "../comedidev.h"
+
+#define PCI263_DRIVER_NAME "amplc_pci263"
+
+/* PCI263 PCI configuration register information */
+#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
+
+static int pci263_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ outb(s->state & 0xFF, dev->iobase);
+ outb(s->state >> 8, dev->iobase + 1);
+ }
+ return insn->n;
+}
+
+static int pci263_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ struct comedi_subdevice *s;
+ int ret;
+
+ ret = comedi_pci_enable(dev);
+ if (ret)
+ return ret;
+
+ dev->iobase = pci_resource_start(pci_dev, 2);
+ ret = comedi_alloc_subdevices(dev, 1);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[0];
+ /* digital output subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pci263_do_insn_bits;
+ /* read initial relay state */
+ s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8);
+
+ dev_info(dev->class_dev, "%s (pci %s) attached\n", dev->board_name,
+ pci_name(pci_dev));
+ return 0;
+}
+
+static struct comedi_driver amplc_pci263_driver = {
+ .driver_name = PCI263_DRIVER_NAME,
+ .module = THIS_MODULE,
+ .auto_attach = pci263_auto_attach,
+ .detach = comedi_pci_disable,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci263_pci_table) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) },
+ {0}
+};
+MODULE_DEVICE_TABLE(pci, pci263_pci_table);
+
+static int amplc_pci263_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &amplc_pci263_driver,
+ id->driver_data);
+}
+
+static struct pci_driver amplc_pci263_pci_driver = {
+ .name = PCI263_DRIVER_NAME,
+ .id_table = pci263_pci_table,
+ .probe = &amplc_pci263_pci_probe,
+ .remove = comedi_pci_auto_unconfig,
+};
+module_comedi_pci_driver(amplc_pci263_driver, amplc_pci263_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi driver for Amplicon PCI263 relay board");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
index 070037c22db..92376dc86dd 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -397,12 +397,6 @@ static void board_init(struct comedi_device *dev)
}
-/*
- options[0] - I/O port
- options[1] - irq
- options[2] - number of encoder chips installed
- */
-
static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
/* Standard LPT Printer Port */
{.id = "PNP0400", .driver_data = 0},
@@ -419,34 +413,20 @@ static struct pnp_driver c6xdigio_pnp_driver = {
static int c6xdigio_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- int result = 0;
- unsigned long iobase;
- unsigned int irq;
struct comedi_subdevice *s;
+ int ret;
- iobase = it->options[0];
- printk(KERN_DEBUG "comedi%d: c6xdigio: 0x%04lx\n", dev->minor, iobase);
- if (!request_region(iobase, C6XDIGIO_SIZE, "c6xdigio")) {
- printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor);
- return -EIO;
- }
- dev->iobase = iobase;
- dev->board_name = "c6xdigio";
+ ret = comedi_request_region(dev, it->options[0], C6XDIGIO_SIZE);
+ if (ret)
+ return ret;
- result = comedi_alloc_subdevices(dev, 2);
- if (result)
- return result;
+ ret = comedi_alloc_subdevices(dev, 2);
+ if (ret)
+ return ret;
/* Make sure that PnP ports get activated */
pnp_register_driver(&c6xdigio_pnp_driver);
- irq = it->options[1];
- if (irq > 0)
- printk(KERN_DEBUG "comedi%d: irq = %u ignored\n",
- dev->minor, irq);
- else if (irq == 0)
- printk(KERN_DEBUG "comedi%d: no irq\n", dev->minor);
-
s = &dev->subdevices[0];
/* pwm output subdevice */
s->type = COMEDI_SUBD_AO; /* Not sure what to put here */
@@ -488,10 +468,7 @@ static int c6xdigio_attach(struct comedi_device *dev,
static void c6xdigio_detach(struct comedi_device *dev)
{
- if (dev->iobase)
- release_region(dev->iobase, C6XDIGIO_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
+ comedi_legacy_detach(dev);
pnp_unregister_driver(&c6xdigio_pnp_driver);
}
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 79c72118a09..53dd298d2b5 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -231,9 +231,19 @@ enum trimpot_model {
AD8402,
};
+enum cb_pcidas_boardid {
+ BOARD_PCIDAS1602_16,
+ BOARD_PCIDAS1200,
+ BOARD_PCIDAS1602_12,
+ BOARD_PCIDAS1200_JR,
+ BOARD_PCIDAS1602_16_JR,
+ BOARD_PCIDAS1000,
+ BOARD_PCIDAS1001,
+ BOARD_PCIDAS1002,
+};
+
struct cb_pcidas_board {
const char *name;
- unsigned short device_id;
int ai_nchan; /* Inputs in single-ended mode */
int ai_bits; /* analog input resolution */
int ai_speed; /* fastest conversion period in ns */
@@ -248,9 +258,8 @@ struct cb_pcidas_board {
};
static const struct cb_pcidas_board cb_pcidas_boards[] = {
- {
+ [BOARD_PCIDAS1602_16] = {
.name = "pci-das1602/16",
- .device_id = 0x1,
.ai_nchan = 16,
.ai_bits = 16,
.ai_speed = 5000,
@@ -262,9 +271,9 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
.trimpot = AD8402,
.has_dac08 = 1,
.is_1602 = 1,
- }, {
+ },
+ [BOARD_PCIDAS1200] = {
.name = "pci-das1200",
- .device_id = 0xF,
.ai_nchan = 16,
.ai_bits = 12,
.ai_speed = 3200,
@@ -272,9 +281,9 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
.fifo_size = 1024,
.ranges = &cb_pcidas_ranges,
.trimpot = AD7376,
- }, {
+ },
+ [BOARD_PCIDAS1602_12] = {
.name = "pci-das1602/12",
- .device_id = 0x10,
.ai_nchan = 16,
.ai_bits = 12,
.ai_speed = 3200,
@@ -285,18 +294,18 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
.ranges = &cb_pcidas_ranges,
.trimpot = AD7376,
.is_1602 = 1,
- }, {
+ },
+ [BOARD_PCIDAS1200_JR] = {
.name = "pci-das1200/jr",
- .device_id = 0x19,
.ai_nchan = 16,
.ai_bits = 12,
.ai_speed = 3200,
.fifo_size = 1024,
.ranges = &cb_pcidas_ranges,
.trimpot = AD7376,
- }, {
+ },
+ [BOARD_PCIDAS1602_16_JR] = {
.name = "pci-das1602/16/jr",
- .device_id = 0x1C,
.ai_nchan = 16,
.ai_bits = 16,
.ai_speed = 5000,
@@ -305,18 +314,18 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
.trimpot = AD8402,
.has_dac08 = 1,
.is_1602 = 1,
- }, {
+ },
+ [BOARD_PCIDAS1000] = {
.name = "pci-das1000",
- .device_id = 0x4C,
.ai_nchan = 16,
.ai_bits = 12,
.ai_speed = 4000,
.fifo_size = 1024,
.ranges = &cb_pcidas_ranges,
.trimpot = AD7376,
- }, {
+ },
+ [BOARD_PCIDAS1001] = {
.name = "pci-das1001",
- .device_id = 0x1a,
.ai_nchan = 16,
.ai_bits = 12,
.ai_speed = 6800,
@@ -324,9 +333,9 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = {
.fifo_size = 1024,
.ranges = &cb_pcidas_alt_ranges,
.trimpot = AD7376,
- }, {
+ },
+ [BOARD_PCIDAS1002] = {
.name = "pci-das1002",
- .device_id = 0x1b,
.ai_nchan = 16,
.ai_bits = 12,
.ai_speed = 6800,
@@ -1332,7 +1341,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
static const int timeout = 10000;
unsigned long flags;
- if (dev->attached == 0)
+ if (!dev->attached)
return IRQ_NONE;
async = s->async;
@@ -1424,31 +1433,18 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
return IRQ_HANDLED;
}
-static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct cb_pcidas_board *thisboard;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) {
- thisboard = &cb_pcidas_boards[i];
- if (thisboard->device_id == pcidev->device)
- return thisboard;
- }
- return NULL;
-}
-
static int cb_pcidas_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct cb_pcidas_board *thisboard;
+ const struct cb_pcidas_board *thisboard = NULL;
struct cb_pcidas_private *devpriv;
struct comedi_subdevice *s;
int i;
int ret;
- thisboard = cb_pcidas_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(cb_pcidas_boards))
+ thisboard = &cb_pcidas_boards[context];
if (!thisboard)
return -ENODEV;
dev->board_ptr = thisboard;
@@ -1459,7 +1455,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -1603,7 +1599,6 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
static void cb_pcidas_detach(struct comedi_device *dev)
{
struct cb_pcidas_private *devpriv = dev->private;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
if (devpriv) {
if (devpriv->s5933_config) {
@@ -1613,12 +1608,8 @@ static void cb_pcidas_detach(struct comedi_device *dev)
}
if (dev->irq)
free_irq(dev->irq, dev);
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[2]);
- if (pcidev) {
- if (devpriv->s5933_config)
- comedi_pci_disable(pcidev);
- }
+ comedi_spriv_free(dev, 2);
+ comedi_pci_disable(dev);
}
static struct comedi_driver cb_pcidas_driver = {
@@ -1629,20 +1620,21 @@ static struct comedi_driver cb_pcidas_driver = {
};
static int cb_pcidas_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &cb_pcidas_driver);
+ return comedi_pci_auto_config(dev, &cb_pcidas_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
+ { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
+ { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
+ { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
+ { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
+ { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
+ { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
+ { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
+ { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 9f3112cb7a2..c3e5495b4f0 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -118,13 +118,6 @@ static const int max_counter_value = 0xffffff;
/* PCI-DAS64xxx base addresses */
-/* indices of base address regions */
-enum base_address_regions {
- PLX9080_BADDRINDEX = 0,
- MAIN_BADDRINDEX = 2,
- DIO_COUNTER_BADDRINDEX = 3,
-};
-
/* devpriv->main_iobase registers */
enum write_only_registers {
INTR_ENABLE_REG = 0x0, /* interrupt enable register */
@@ -543,13 +536,6 @@ static const int ao_range_code_64xx[] = {
0x3,
};
-static const struct comedi_lrange ao_ranges_60xx = {
- 1,
- {
- BIP_RANGE(10),
- }
-};
-
static const int ao_range_code_60xx[] = {
0x0,
};
@@ -593,9 +579,39 @@ struct hw_fifo_info {
uint16_t fifo_size_reg_mask;
};
+enum pcidas64_boardid {
+ BOARD_PCIDAS6402_16,
+ BOARD_PCIDAS6402_12,
+ BOARD_PCIDAS64_M1_16,
+ BOARD_PCIDAS64_M2_16,
+ BOARD_PCIDAS64_M3_16,
+ BOARD_PCIDAS6013,
+ BOARD_PCIDAS6014,
+ BOARD_PCIDAS6023,
+ BOARD_PCIDAS6025,
+ BOARD_PCIDAS6030,
+ BOARD_PCIDAS6031,
+ BOARD_PCIDAS6032,
+ BOARD_PCIDAS6033,
+ BOARD_PCIDAS6034,
+ BOARD_PCIDAS6035,
+ BOARD_PCIDAS6036,
+ BOARD_PCIDAS6040,
+ BOARD_PCIDAS6052,
+ BOARD_PCIDAS6070,
+ BOARD_PCIDAS6071,
+ BOARD_PCIDAS4020_12,
+ BOARD_PCIDAS6402_16_JR,
+ BOARD_PCIDAS64_M1_16_JR,
+ BOARD_PCIDAS64_M2_16_JR,
+ BOARD_PCIDAS64_M3_16_JR,
+ BOARD_PCIDAS64_M1_14,
+ BOARD_PCIDAS64_M2_14,
+ BOARD_PCIDAS64_M3_14,
+};
+
struct pcidas64_board {
const char *name;
- int device_id; /* pci device id */
int ai_se_chans; /* number of ai inputs in single-ended mode */
int ai_bits; /* analog input resolution */
int ai_speed; /* fastest conversion period in ns */
@@ -648,421 +664,397 @@ static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
static const int bytes_in_sample = 2;
static const struct pcidas64_board pcidas64_boards[] = {
- {
- .name = "pci-das6402/16",
- .device_id = 0x1d,
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das6402/12", /* XXX check */
- .device_id = 0x1e,
- .ai_se_chans = 64,
- .ai_bits = 12,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m1/16",
- .device_id = 0x35,
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 1000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m2/16",
- .device_id = 0x36,
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 500,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m3/16",
- .device_id = 0x37,
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 333,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ao_range_table = &ao_ranges_64xx,
- .ao_range_code = ao_range_code_64xx,
- .ai_fifo = &ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das6013",
- .device_id = 0x78,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_bits = 16,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ao_range_table = &ao_ranges_60xx,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6014",
- .device_id = 0x79,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ao_range_table = &ao_ranges_60xx,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6023",
- .device_id = 0x5d,
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ao_range_table = &ao_ranges_60xx,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das6025",
- .device_id = 0x5e,
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ao_range_table = &ao_ranges_60xx,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das6030",
- .device_id = 0x5f,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6031",
- .device_id = 0x60,
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6032",
- .device_id = 0x61,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 0,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6033",
- .device_id = 0x62,
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 10000,
- .ao_nchan = 0,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6034",
- .device_id = 0x63,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_scan_speed = 0,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6035",
- .device_id = 0x64,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ao_range_table = &ao_ranges_60xx,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6036",
- .device_id = 0x6f,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 100000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_60xx,
- .ao_range_table = &ao_ranges_60xx,
- .ao_range_code = ao_range_code_60xx,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6040",
- .device_id = 0x65,
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 2000,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 1000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6052",
- .device_id = 0x66,
- .ai_se_chans = 16,
- .ai_bits = 16,
- .ai_speed = 3333,
- .ao_nchan = 2,
- .ao_bits = 16,
- .ao_scan_speed = 3333,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6070",
- .device_id = 0x67,
- .ai_se_chans = 16,
- .ai_bits = 12,
- .ai_speed = 800,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 1000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das6071",
- .device_id = 0x68,
- .ai_se_chans = 64,
- .ai_bits = 12,
- .ai_speed = 800,
- .ao_nchan = 2,
- .ao_bits = 12,
- .ao_scan_speed = 1000,
- .layout = LAYOUT_60XX,
- .ai_range_table = &ai_ranges_6052,
- .ao_range_table = &ao_ranges_6030,
- .ao_range_code = ao_range_code_6030,
- .ai_fifo = &ai_fifo_60xx,
- .has_8255 = 0,
- },
- {
- .name = "pci-das4020/12",
- .device_id = 0x52,
- .ai_se_chans = 4,
- .ai_bits = 12,
- .ai_speed = 50,
- .ao_bits = 12,
- .ao_nchan = 2,
- .ao_scan_speed = 0, /* no hardware pacing on ao */
- .layout = LAYOUT_4020,
- .ai_range_table = &ai_ranges_4020,
- .ao_range_table = &ao_ranges_4020,
- .ao_range_code = ao_range_code_4020,
- .ai_fifo = &ai_fifo_4020,
- .has_8255 = 1,
- },
+ [BOARD_PCIDAS6402_16] = {
+ .name = "pci-das6402/16",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ao_range_table = &ao_ranges_64xx,
+ .ao_range_code = ao_range_code_64xx,
+ .ai_fifo = &ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS6402_12] = {
+ .name = "pci-das6402/12", /* XXX check */
+ .ai_se_chans = 64,
+ .ai_bits = 12,
+ .ai_speed = 5000,
+ .ao_nchan = 2,
+ .ao_bits = 12,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ao_range_table = &ao_ranges_64xx,
+ .ao_range_code = ao_range_code_64xx,
+ .ai_fifo = &ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M1_16] = {
+ .name = "pci-das64/m1/16",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 1000,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ao_range_table = &ao_ranges_64xx,
+ .ao_range_code = ao_range_code_64xx,
+ .ai_fifo = &ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M2_16] = {
+ .name = "pci-das64/m2/16",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 500,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ao_range_table = &ao_ranges_64xx,
+ .ao_range_code = ao_range_code_64xx,
+ .ai_fifo = &ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M3_16] = {
+ .name = "pci-das64/m3/16",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 333,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ao_range_table = &ao_ranges_64xx,
+ .ao_range_code = ao_range_code_64xx,
+ .ai_fifo = &ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS6013] = {
+ .name = "pci-das6013",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 0,
+ .ao_bits = 16,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &range_bipolar10,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6014] = {
+ .name = "pci-das6014",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 100000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &range_bipolar10,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6023] = {
+ .name = "pci-das6023",
+ .ai_se_chans = 16,
+ .ai_bits = 12,
+ .ai_speed = 5000,
+ .ao_nchan = 0,
+ .ao_scan_speed = 100000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &range_bipolar10,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS6025] = {
+ .name = "pci-das6025",
+ .ai_se_chans = 16,
+ .ai_bits = 12,
+ .ai_speed = 5000,
+ .ao_nchan = 2,
+ .ao_bits = 12,
+ .ao_scan_speed = 100000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &range_bipolar10,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS6030] = {
+ .name = "pci-das6030",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 10000,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6030,
+ .ao_range_table = &ao_ranges_6030,
+ .ao_range_code = ao_range_code_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6031] = {
+ .name = "pci-das6031",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 10000,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6030,
+ .ao_range_table = &ao_ranges_6030,
+ .ao_range_code = ao_range_code_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6032] = {
+ .name = "pci-das6032",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 10000,
+ .ao_nchan = 0,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6033] = {
+ .name = "pci-das6033",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 10000,
+ .ao_nchan = 0,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6034] = {
+ .name = "pci-das6034",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 0,
+ .ao_scan_speed = 0,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6035] = {
+ .name = "pci-das6035",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 2,
+ .ao_bits = 12,
+ .ao_scan_speed = 100000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &range_bipolar10,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6036] = {
+ .name = "pci-das6036",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 100000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &range_bipolar10,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6040] = {
+ .name = "pci-das6040",
+ .ai_se_chans = 16,
+ .ai_bits = 12,
+ .ai_speed = 2000,
+ .ao_nchan = 2,
+ .ao_bits = 12,
+ .ao_scan_speed = 1000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6052,
+ .ao_range_table = &ao_ranges_6030,
+ .ao_range_code = ao_range_code_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6052] = {
+ .name = "pci-das6052",
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 3333,
+ .ao_nchan = 2,
+ .ao_bits = 16,
+ .ao_scan_speed = 3333,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6052,
+ .ao_range_table = &ao_ranges_6030,
+ .ao_range_code = ao_range_code_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6070] = {
+ .name = "pci-das6070",
+ .ai_se_chans = 16,
+ .ai_bits = 12,
+ .ai_speed = 800,
+ .ao_nchan = 2,
+ .ao_bits = 12,
+ .ao_scan_speed = 1000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6052,
+ .ao_range_table = &ao_ranges_6030,
+ .ao_range_code = ao_range_code_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS6071] = {
+ .name = "pci-das6071",
+ .ai_se_chans = 64,
+ .ai_bits = 12,
+ .ai_speed = 800,
+ .ao_nchan = 2,
+ .ao_bits = 12,
+ .ao_scan_speed = 1000,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_6052,
+ .ao_range_table = &ao_ranges_6030,
+ .ao_range_code = ao_range_code_6030,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ [BOARD_PCIDAS4020_12] = {
+ .name = "pci-das4020/12",
+ .ai_se_chans = 4,
+ .ai_bits = 12,
+ .ai_speed = 50,
+ .ao_bits = 12,
+ .ao_nchan = 2,
+ .ao_scan_speed = 0, /* no hardware pacing on ao */
+ .layout = LAYOUT_4020,
+ .ai_range_table = &ai_ranges_4020,
+ .ao_range_table = &ao_ranges_4020,
+ .ao_range_code = ao_range_code_4020,
+ .ai_fifo = &ai_fifo_4020,
+ .has_8255 = 1,
+ },
#if 0
- {
- .name = "pci-das6402/16/jr",
- .device_id = 0 /* XXX, */
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 5000,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m1/16/jr",
- .device_id = 0 /* XXX, */
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 1000,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m2/16/jr",
- .device_id = 0 /* XXX, */
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 500,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m3/16/jr",
- .device_id = 0 /* XXX, */
- .ai_se_chans = 64,
- .ai_bits = 16,
- .ai_speed = 333,
- .ao_nchan = 0,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m1/14",
- .device_id = 0, /* XXX */
- .ai_se_chans = 64,
- .ai_bits = 14,
- .ai_speed = 1000,
- .ao_nchan = 2,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m2/14",
- .device_id = 0, /* XXX */
- .ai_se_chans = 64,
- .ai_bits = 14,
- .ai_speed = 500,
- .ao_nchan = 2,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
- {
- .name = "pci-das64/m3/14",
- .device_id = 0, /* XXX */
- .ai_se_chans = 64,
- .ai_bits = 14,
- .ai_speed = 333,
- .ao_nchan = 2,
- .ao_scan_speed = 10000,
- .layout = LAYOUT_64XX,
- .ai_range_table = &ai_ranges_64xx,
- .ai_fifo = ai_fifo_64xx,
- .has_8255 = 1,
- },
+ /*
+ * The device id for these boards is unknown
+ */
+
+ [BOARD_PCIDAS6402_16_JR] = {
+ .name = "pci-das6402/16/jr",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 0,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M1_16_JR] = {
+ .name = "pci-das64/m1/16/jr",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 1000,
+ .ao_nchan = 0,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M2_16_JR] = {
+ .name = "pci-das64/m2/16/jr",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 500,
+ .ao_nchan = 0,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M3_16_JR] = {
+ .name = "pci-das64/m3/16/jr",
+ .ai_se_chans = 64,
+ .ai_bits = 16,
+ .ai_speed = 333,
+ .ao_nchan = 0,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M1_14] = {
+ .name = "pci-das64/m1/14",
+ .ai_se_chans = 64,
+ .ai_bits = 14,
+ .ai_speed = 1000,
+ .ao_nchan = 2,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M2_14] = {
+ .name = "pci-das64/m2/14",
+ .ai_se_chans = 64,
+ .ai_bits = 14,
+ .ai_speed = 500,
+ .ao_nchan = 2,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
+ [BOARD_PCIDAS64_M3_14] = {
+ .name = "pci-das64/m3/14",
+ .ai_se_chans = 64,
+ .ai_bits = 14,
+ .ai_speed = 333,
+ .ao_nchan = 2,
+ .ao_scan_speed = 10000,
+ .layout = LAYOUT_64XX,
+ .ai_range_table = &ai_ranges_64xx,
+ .ai_fifo = ai_fifo_64xx,
+ .has_8255 = 1,
+ },
#endif
};
@@ -1088,7 +1080,6 @@ struct ext_clock_info {
/* this structure is for data unique to this hardware driver. */
struct pcidas64_private {
/* base addresses (physical) */
- resource_size_t plx9080_phys_iobase;
resource_size_t main_phys_iobase;
resource_size_t dio_counter_phys_iobase;
/* base addresses (ioremapped) */
@@ -1523,7 +1514,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
struct pcidas64_private *devpriv = dev->private;
int i;
- /* alocate pci dma buffers */
+ /* allocate pci dma buffers */
for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
devpriv->ai_buffer[i] =
pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
@@ -3107,7 +3098,7 @@ static irqreturn_t handle_interrupt(int irq, void *d)
/* an interrupt before all the postconfig stuff gets done could
* cause a NULL dereference if we continue through the
* interrupt handler */
- if (dev->attached == 0) {
+ if (!dev->attached) {
DEBUG_PRINT("premature interrupt, ignoring\n");
return IRQ_HANDLED;
}
@@ -4033,68 +4024,40 @@ static int setup_subdevices(struct comedi_device *dev)
return 0;
}
-static const struct pcidas64_board
-*cb_pcidas64_find_pci_board(struct pci_dev *pcidev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++)
- if (pcidev->device == pcidas64_boards[i].device_id)
- return &pcidas64_boards[i];
- return NULL;
-}
-
static int auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
- const struct pcidas64_board *thisboard;
- struct pcidas64_private *devpriv;
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct pcidas64_board *thisboard = NULL;
+ struct pcidas64_private *devpriv;
uint32_t local_range, local_decode;
int retval;
- dev->board_ptr = cb_pcidas64_find_pci_board(pcidev);
- if (!dev->board_ptr) {
- dev_err(dev->class_dev,
- "cb_pcidas64: does not support pci %s\n",
- pci_name(pcidev));
- return -EINVAL;
- }
- thisboard = comedi_board(dev);
+ if (context < ARRAY_SIZE(pcidas64_boards))
+ thisboard = &pcidas64_boards[context];
+ if (!thisboard)
+ return -ENODEV;
+ dev->board_ptr = thisboard;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
- dev_warn(dev->class_dev,
- "failed to enable PCI device and request regions\n");
- return -EIO;
- }
+ retval = comedi_pci_enable(dev);
+ if (retval)
+ return retval;
pci_set_master(pcidev);
/* Initialize dev->board_name */
dev->board_name = thisboard->name;
- dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX);
-
- devpriv->plx9080_phys_iobase =
- pci_resource_start(pcidev, PLX9080_BADDRINDEX);
- devpriv->main_phys_iobase = dev->iobase;
- devpriv->dio_counter_phys_iobase =
- pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
-
- /* remap, won't work with 2.0 kernels but who cares */
- devpriv->plx9080_iobase =
- ioremap(devpriv->plx9080_phys_iobase,
- pci_resource_len(pcidev, PLX9080_BADDRINDEX));
- devpriv->main_iobase =
- ioremap(devpriv->main_phys_iobase,
- pci_resource_len(pcidev, MAIN_BADDRINDEX));
- devpriv->dio_counter_iobase =
- ioremap(devpriv->dio_counter_phys_iobase,
- pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
+ devpriv->main_phys_iobase = pci_resource_start(pcidev, 2);
+ devpriv->dio_counter_phys_iobase = pci_resource_start(pcidev, 3);
+
+ devpriv->plx9080_iobase = pci_ioremap_bar(pcidev, 0);
+ devpriv->main_iobase = pci_ioremap_bar(pcidev, 2);
+ devpriv->dio_counter_iobase = pci_ioremap_bar(pcidev, 3);
if (!devpriv->plx9080_iobase || !devpriv->main_iobase
|| !devpriv->dio_counter_iobase) {
@@ -4200,12 +4163,8 @@ static void detach(struct comedi_device *dev)
devpriv->ao_dma_desc_bus_addr);
}
}
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[4]);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_spriv_free(dev, 4);
+ comedi_pci_disable(dev);
}
static struct comedi_driver cb_pcidas64_driver = {
@@ -4216,31 +4175,34 @@ static struct comedi_driver cb_pcidas64_driver = {
};
static int cb_pcidas64_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &cb_pcidas64_driver);
+ return comedi_pci_auto_config(dev, &cb_pcidas64_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001d) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001e) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0035) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0036) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0037) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0052) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005d) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005e) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005f) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0061) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0062) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0063) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0064) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0066) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0067) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0068) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x006f) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0078) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0079) },
+ { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 },
+ { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 },
+ { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 },
+ { PCI_VDEVICE(CB, 0x0036), BOARD_PCIDAS64_M2_16 },
+ { PCI_VDEVICE(CB, 0x0037), BOARD_PCIDAS64_M3_16 },
+ { PCI_VDEVICE(CB, 0x0052), BOARD_PCIDAS4020_12 },
+ { PCI_VDEVICE(CB, 0x005d), BOARD_PCIDAS6023 },
+ { PCI_VDEVICE(CB, 0x005e), BOARD_PCIDAS6025 },
+ { PCI_VDEVICE(CB, 0x005f), BOARD_PCIDAS6030 },
+ { PCI_VDEVICE(CB, 0x0060), BOARD_PCIDAS6031 },
+ { PCI_VDEVICE(CB, 0x0061), BOARD_PCIDAS6032 },
+ { PCI_VDEVICE(CB, 0x0062), BOARD_PCIDAS6033 },
+ { PCI_VDEVICE(CB, 0x0063), BOARD_PCIDAS6034 },
+ { PCI_VDEVICE(CB, 0x0064), BOARD_PCIDAS6035 },
+ { PCI_VDEVICE(CB, 0x0065), BOARD_PCIDAS6040 },
+ { PCI_VDEVICE(CB, 0x0066), BOARD_PCIDAS6052 },
+ { PCI_VDEVICE(CB, 0x0067), BOARD_PCIDAS6070 },
+ { PCI_VDEVICE(CB, 0x0068), BOARD_PCIDAS6071 },
+ { PCI_VDEVICE(CB, 0x006f), BOARD_PCIDAS6036 },
+ { PCI_VDEVICE(CB, 0x0078), BOARD_PCIDAS6013 },
+ { PCI_VDEVICE(CB, 0x0079), BOARD_PCIDAS6014 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index e2cadc72845..f9b459888b8 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -48,16 +48,6 @@
#include "comedi_fc.h"
#include "8255.h"
-/*
- * ComputerBoards PCI Device ID's supported by this driver
- */
-#define PCI_DEVICE_ID_DDA02_12 0x0020
-#define PCI_DEVICE_ID_DDA04_12 0x0021
-#define PCI_DEVICE_ID_DDA08_12 0x0022
-#define PCI_DEVICE_ID_DDA02_16 0x0023
-#define PCI_DEVICE_ID_DDA04_16 0x0024
-#define PCI_DEVICE_ID_DDA08_16 0x0025
-
#define EEPROM_SIZE 128 /* number of entries in eeprom */
/* maximum number of ao channels for supported boards */
#define MAX_AO_CHANNELS 8
@@ -118,42 +108,49 @@ static const struct comedi_lrange cb_pcidda_ranges = {
}
};
+enum cb_pcidda_boardid {
+ BOARD_DDA02_12,
+ BOARD_DDA04_12,
+ BOARD_DDA08_12,
+ BOARD_DDA02_16,
+ BOARD_DDA04_16,
+ BOARD_DDA08_16,
+};
+
struct cb_pcidda_board {
const char *name;
- unsigned short device_id;
int ao_chans;
int ao_bits;
};
static const struct cb_pcidda_board cb_pcidda_boards[] = {
- {
+ [BOARD_DDA02_12] = {
.name = "pci-dda02/12",
- .device_id = PCI_DEVICE_ID_DDA02_12,
.ao_chans = 2,
.ao_bits = 12,
- }, {
+ },
+ [BOARD_DDA04_12] = {
.name = "pci-dda04/12",
- .device_id = PCI_DEVICE_ID_DDA04_12,
.ao_chans = 4,
.ao_bits = 12,
- }, {
+ },
+ [BOARD_DDA08_12] = {
.name = "pci-dda08/12",
- .device_id = PCI_DEVICE_ID_DDA08_12,
.ao_chans = 8,
.ao_bits = 12,
- }, {
+ },
+ [BOARD_DDA02_16] = {
.name = "pci-dda02/16",
- .device_id = PCI_DEVICE_ID_DDA02_16,
.ao_chans = 2,
.ao_bits = 16,
- }, {
+ },
+ [BOARD_DDA04_16] = {
.name = "pci-dda04/16",
- .device_id = PCI_DEVICE_ID_DDA04_16,
.ao_chans = 4,
.ao_bits = 16,
- }, {
+ },
+ [BOARD_DDA08_16] = {
.name = "pci-dda08/16",
- .device_id = PCI_DEVICE_ID_DDA08_16,
.ao_chans = 8,
.ao_bits = 16,
},
@@ -337,32 +334,19 @@ static int cb_pcidda_ao_insn_write(struct comedi_device *dev,
return insn->n;
}
-static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct cb_pcidda_board *thisboard;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) {
- thisboard = &cb_pcidda_boards[i];
- if (thisboard->device_id != pcidev->device)
- return thisboard;
- }
- return NULL;
-}
-
static int cb_pcidda_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct cb_pcidda_board *thisboard;
+ const struct cb_pcidda_board *thisboard = NULL;
struct cb_pcidda_private *devpriv;
struct comedi_subdevice *s;
unsigned long iobase_8255;
int i;
int ret;
- thisboard = cb_pcidda_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(cb_pcidda_boards))
+ thisboard = &cb_pcidda_boards[context];
if (!thisboard)
return -ENODEV;
dev->board_ptr = thisboard;
@@ -373,7 +357,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 3);
@@ -415,16 +399,9 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev,
static void cb_pcidda_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (dev->subdevices) {
- subdev_8255_cleanup(dev, &dev->subdevices[1]);
- subdev_8255_cleanup(dev, &dev->subdevices[2]);
- }
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_spriv_free(dev, 1);
+ comedi_spriv_free(dev, 2);
+ comedi_pci_disable(dev);
}
static struct comedi_driver cb_pcidda_driver = {
@@ -435,18 +412,19 @@ static struct comedi_driver cb_pcidda_driver = {
};
static int cb_pcidda_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &cb_pcidda_driver);
+ return comedi_pci_auto_config(dev, &cb_pcidda_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_12) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_12) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_12) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_16) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_16) },
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_16) },
+ { PCI_VDEVICE(CB, 0x0020), BOARD_DDA02_12 },
+ { PCI_VDEVICE(CB, 0x0021), BOARD_DDA04_12 },
+ { PCI_VDEVICE(CB, 0x0022), BOARD_DDA08_12 },
+ { PCI_VDEVICE(CB, 0x0023), BOARD_DDA02_16 },
+ { PCI_VDEVICE(CB, 0x0024), BOARD_DDA04_16 },
+ { PCI_VDEVICE(CB, 0x0025), BOARD_DDA08_16 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index aae063ca85a..29813c9d4a2 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -215,14 +215,12 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev,
unsigned long iobase_8255;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -277,14 +275,9 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev,
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 (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver cb_pcimdas_driver = {
@@ -295,9 +288,10 @@ static struct comedi_driver cb_pcimdas_driver = {
};
static int cb_pcimdas_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &cb_pcimdas_driver);
+ return comedi_pci_auto_config(dev, &cb_pcimdas_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
index 63cfbaf3a3f..88f03ae6f3e 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -161,14 +161,12 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 3);
@@ -201,14 +199,8 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev,
static void cb_pcimdda_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[1]);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_spriv_free(dev, 1);
+ comedi_pci_disable(dev);
}
static struct comedi_driver cb_pcimdda_driver = {
@@ -219,9 +211,10 @@ static struct comedi_driver cb_pcimdda_driver = {
};
static int cb_pcimdda_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &cb_pcimdda_driver);
+ return comedi_pci_auto_config(dev, &cb_pcimdda_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index 83728298eef..37dc79637d2 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -65,7 +65,7 @@ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
return num_bytes;
}
-EXPORT_SYMBOL(cfc_write_array_to_buffer);
+EXPORT_SYMBOL_GPL(cfc_write_array_to_buffer);
unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
void *data, unsigned int num_bytes)
@@ -83,7 +83,7 @@ unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
return num_bytes;
}
-EXPORT_SYMBOL(cfc_read_array_from_buffer);
+EXPORT_SYMBOL_GPL(cfc_read_array_from_buffer);
unsigned int cfc_handle_events(struct comedi_device *dev,
struct comedi_subdevice *subd)
@@ -100,7 +100,7 @@ unsigned int cfc_handle_events(struct comedi_device *dev,
return events;
}
-EXPORT_SYMBOL(cfc_handle_events);
+EXPORT_SYMBOL_GPL(cfc_handle_events);
MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
MODULE_DESCRIPTION("Shared functions for Comedi low-level drivers");
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index 76d59dcbea0..3e061cc9b48 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -261,19 +261,13 @@ static int parport_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
struct parport_private *devpriv;
- int ret;
- unsigned int irq;
- unsigned long iobase;
struct comedi_subdevice *s;
+ unsigned int irq;
+ int ret;
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
- if (!request_region(iobase, PARPORT_SIZE, dev->board_name)) {
- dev_err(dev->class_dev, "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], PARPORT_SIZE);
+ if (ret)
+ return ret;
irq = it->options[1];
if (irq) {
@@ -341,25 +335,14 @@ static int parport_attach(struct comedi_device *dev,
devpriv->c_data = 0;
outb(devpriv->c_data, dev->iobase + PARPORT_C);
- dev_info(dev->class_dev, "%s: iobase=0x%04lx, irq %sabled",
- dev->board_name, dev->iobase, dev->irq ? "en" : "dis");
-
return 0;
}
-static void parport_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, PARPORT_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
-}
-
static struct comedi_driver parport_driver = {
.driver_name = "comedi_parport",
.module = THIS_MODULE,
.attach = parport_attach,
- .detach = parport_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(parport_driver);
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 270fea5c6b5..c1d8e86f53a 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -384,8 +384,6 @@ static int waveform_attach(struct comedi_device *dev,
int i;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index 182dea669ef..f2230bfd4eb 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -77,9 +77,7 @@ static int contec_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 0);
@@ -109,27 +107,18 @@ static int contec_auto_attach(struct comedi_device *dev,
return 0;
}
-static void contec_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
-}
-
static struct comedi_driver contec_pci_dio_driver = {
.driver_name = "contec_pci_dio",
.module = THIS_MODULE,
.auto_attach = contec_auto_attach,
- .detach = contec_detach,
+ .detach = comedi_pci_disable,
};
static int contec_pci_dio_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &contec_pci_dio_driver);
+ return comedi_pci_auto_config(dev, &contec_pci_dio_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index 50b450f09c6..b87f95c3e17 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -462,9 +462,9 @@ static void daqboard2000_resetLocalBus(struct comedi_device *dev)
struct daqboard2000_private *devpriv = dev->private;
writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);
- udelay(10000);
+ mdelay(10);
writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);
- udelay(10000);
+ mdelay(10);
}
static void daqboard2000_reloadPLX(struct comedi_device *dev)
@@ -472,11 +472,11 @@ static void daqboard2000_reloadPLX(struct comedi_device *dev)
struct daqboard2000_private *devpriv = dev->private;
writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
- udelay(10000);
+ mdelay(10);
writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);
- udelay(10000);
+ mdelay(10);
writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
- udelay(10000);
+ mdelay(10);
}
static void daqboard2000_pulseProgPin(struct comedi_device *dev)
@@ -484,9 +484,9 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev)
struct daqboard2000_private *devpriv = dev->private;
writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
- udelay(10000);
+ mdelay(10);
writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
- udelay(10000); /* Not in the original code, but I like symmetry... */
+ mdelay(10); /* Not in the original code, but I like symmetry... */
}
static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
@@ -709,15 +709,12 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- result = comedi_pci_enable(pcidev, dev->driver->driver_name);
- if (result < 0)
+ result = comedi_pci_enable(dev);
+ if (result)
return result;
- dev->iobase = 1; /* the "detach" needs this */
- devpriv->plx = ioremap(pci_resource_start(pcidev, 0),
- pci_resource_len(pcidev, 0));
- devpriv->daq = ioremap(pci_resource_start(pcidev, 2),
- pci_resource_len(pcidev, 2));
+ devpriv->plx = pci_ioremap_bar(pcidev, 0);
+ devpriv->daq = pci_ioremap_bar(pcidev, 2);
if (!devpriv->plx || !devpriv->daq)
return -ENOMEM;
@@ -767,11 +764,9 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
static void daqboard2000_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct daqboard2000_private *devpriv = dev->private;
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[2]);
+ comedi_spriv_free(dev, 2);
if (dev->irq)
free_irq(dev->irq, dev);
if (devpriv) {
@@ -780,11 +775,7 @@ static void daqboard2000_detach(struct comedi_device *dev)
if (devpriv->plx)
iounmap(devpriv->plx);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- pci_dev_put(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver daqboard2000_driver = {
@@ -795,9 +786,10 @@ static struct comedi_driver daqboard2000_driver = {
};
static int daqboard2000_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &daqboard2000_driver);
+ return comedi_pci_auto_config(dev, &daqboard2000_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index 9823aa06787..ba12c1d605f 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -568,8 +568,7 @@ EXPORT_SYMBOL_GPL(das08_common_attach);
void das08_common_detach(struct comedi_device *dev)
{
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[4]);
+ comedi_spriv_free(dev, 4);
}
EXPORT_SYMBOL_GPL(das08_common_detach);
diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h
index b102ad4918c..89bb8d6fdfc 100644
--- a/drivers/staging/comedi/drivers/das08.h
+++ b/drivers/staging/comedi/drivers/das08.h
@@ -32,7 +32,6 @@ enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl,
struct das08_board_struct {
const char *name;
- unsigned int id; /* id for pci/pcmcia boards */
bool is_jr; /* true for 'JR' boards */
unsigned int ai_nbits;
enum das08_lrange ai_pg;
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index cfeebe4d1dd..d9f3e92317d 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -59,7 +59,6 @@ Command support does not exist, but could be added for this board.
static const struct das08_board_struct das08_cs_boards[] = {
{
.name = "pcm-das08",
- .id = 0x0, /* XXX */
.ai_nbits = 12,
.ai_pg = das08_bipolar5,
.ai_encoding = das08_pcm_encode12,
diff --git a/drivers/staging/comedi/drivers/das08_isa.c b/drivers/staging/comedi/drivers/das08_isa.c
index f1207824716..f09f6966ed6 100644
--- a/drivers/staging/comedi/drivers/das08_isa.c
+++ b/drivers/staging/comedi/drivers/das08_isa.c
@@ -179,26 +179,24 @@ static int das08_isa_attach(struct comedi_device *dev,
{
const struct das08_board_struct *thisboard = comedi_board(dev);
struct das08_private_struct *devpriv;
+ int ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- if (!request_region(it->options[0], thisboard->iosize,
- thisboard->name))
- return -EIO;
+ ret = comedi_request_region(dev, it->options[0], thisboard->iosize);
+ if (ret)
+ return ret;
- return das08_common_attach(dev, it->options[0]);
+ return das08_common_attach(dev, dev->iobase);
}
static void das08_isa_detach(struct comedi_device *dev)
{
- const struct das08_board_struct *thisboard = comedi_board(dev);
-
das08_common_detach(dev);
- if (dev->iobase)
- release_region(dev->iobase, thisboard->iosize);
+ comedi_legacy_detach(dev);
}
static struct comedi_driver das08_isa_driver = {
diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c
index c405876ddcf..53fa943dd0b 100644
--- a/drivers/staging/comedi/drivers/das08_pci.c
+++ b/drivers/staging/comedi/drivers/das08_pci.c
@@ -46,7 +46,6 @@
static const struct das08_board_struct das08_pci_boards[] = {
{
.name = "pci-das08",
- .id = PCI_DEVICE_ID_PCIDAS08,
.ai_nbits = 12,
.ai_pg = das08_bipolar5,
.ai_encoding = das08_encode12,
@@ -72,7 +71,7 @@ static int das08_pci_auto_attach(struct comedi_device *dev,
/* The das08 driver needs the board_ptr */
dev->board_ptr = &das08_pci_boards[0];
- ret = comedi_pci_enable(pdev, dev->driver->driver_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pdev, 2);
@@ -82,11 +81,8 @@ static int das08_pci_auto_attach(struct comedi_device *dev,
static void das08_pci_detach(struct comedi_device *dev)
{
- struct pci_dev *pdev = comedi_to_pci_dev(dev);
-
das08_common_detach(dev);
- if (dev->iobase)
- comedi_pci_disable(pdev);
+ comedi_pci_disable(dev);
}
static struct comedi_driver das08_pci_comedi_driver = {
@@ -97,9 +93,10 @@ static struct comedi_driver das08_pci_comedi_driver = {
};
static int das08_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &das08_pci_comedi_driver);
+ return comedi_pci_auto_config(dev, &das08_pci_comedi_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index f238a1fbccb..762b5a6eac5 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -393,6 +393,8 @@ struct das16_private_struct {
struct timer_list timer; /* for timed interrupt */
volatile short timer_running;
volatile short timer_mode; /* true if using timer mode */
+
+ unsigned long extra_iobase;
};
static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
@@ -876,7 +878,7 @@ static void das16_interrupt(struct comedi_device *dev)
int num_bytes, residue;
int buffer_index;
- if (dev->attached == 0) {
+ if (!dev->attached) {
comedi_error(dev, "premature interrupt");
return;
}
@@ -1079,13 +1081,11 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
unsigned int irq;
- unsigned long iobase;
unsigned int dma_chan;
int timer_mode;
unsigned long flags;
struct comedi_krange *user_ai_range, *user_ao_range;
- iobase = it->options[0];
#if 0
irq = it->options[1];
timer_mode = it->options[8];
@@ -1097,8 +1097,6 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (timer_mode)
irq = 0;
- printk(KERN_INFO "comedi%d: das16:", dev->minor);
-
/* check that clock setting is valid */
if (it->options[3]) {
if (it->options[3] != 0 &&
@@ -1116,39 +1114,26 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->private = devpriv;
if (board->size < 0x400) {
- printk(" 0x%04lx-0x%04lx\n", iobase, iobase + board->size);
- if (!request_region(iobase, board->size, "das16")) {
- printk(KERN_ERR " I/O port conflict\n");
- return -EIO;
- }
+ ret = comedi_request_region(dev, it->options[0], board->size);
+ if (ret)
+ return ret;
} else {
- printk(KERN_INFO " 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
- iobase, iobase + 0x0f,
- iobase + 0x400,
- iobase + 0x400 + (board->size & 0x3ff));
- if (!request_region(iobase, 0x10, "das16")) {
- printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n",
- iobase, iobase + 0x0f);
- return -EIO;
- }
- if (!request_region(iobase + 0x400, board->size & 0x3ff,
- "das16")) {
- release_region(iobase, 0x10);
- printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n",
- iobase + 0x400,
- iobase + 0x400 + (board->size & 0x3ff));
- return -EIO;
- }
+ ret = comedi_request_region(dev, it->options[0], 0x10);
+ if (ret)
+ return ret;
+ /* Request an additional region for the 8255 */
+ ret = __comedi_request_region(dev, dev->iobase + 0x400,
+ board->size & 0x3ff);
+ if (ret)
+ return ret;
+ devpriv->extra_iobase = dev->iobase + 0x400;
}
- dev->iobase = iobase;
-
/* probe id bits to make sure they are consistent */
if (das16_probe(dev, it)) {
printk(KERN_ERR " id bits do not match selected board, aborting\n");
return -EINVAL;
}
- dev->board_name = board->name;
/* get master clock speed */
if (board->size < 0x400) {
@@ -1162,7 +1147,8 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
/* now for the irq */
if (irq > 1 && irq < 8) {
- ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev);
+ ret = request_irq(irq, das16_dma_interrupt, 0,
+ dev->board_name, dev);
if (ret < 0)
return ret;
@@ -1188,7 +1174,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (devpriv->dma_buffer[i] == NULL)
return -ENOMEM;
}
- if (request_dma(dma_chan, "das16")) {
+ if (request_dma(dma_chan, dev->board_name)) {
printk(KERN_ERR " failed to allocate dma channel %i\n",
dma_chan);
return -EINVAL;
@@ -1353,8 +1339,7 @@ static void das16_detach(struct comedi_device *dev)
struct das16_private_struct *devpriv = dev->private;
das16_reset(dev);
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[4]);
+ comedi_spriv_free(dev, 4);
if (devpriv) {
int i;
for (i = 0; i < 2; i++) {
@@ -1369,17 +1354,9 @@ static void das16_detach(struct comedi_device *dev)
kfree(devpriv->user_ai_range_table);
kfree(devpriv->user_ao_range_table);
}
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase) {
- if (board->size < 0x400) {
- release_region(dev->iobase, board->size);
- } else {
- release_region(dev->iobase, 0x10);
- release_region(dev->iobase + 0x400,
- board->size & 0x3ff);
- }
- }
+ if (devpriv->extra_iobase)
+ release_region(devpriv->extra_iobase, board->size & 0x3ff);
+ comedi_legacy_detach(dev);
}
static const struct das16_board das16_boards[] = {
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index b0a861a779b..9cb9c3b0479 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -143,6 +143,7 @@ struct das16m1_private_struct {
unsigned int do_bits; /* saves status of digital output bits */
unsigned int divisor1; /* divides master clock to obtain conversion speed */
unsigned int divisor2; /* divides master clock to obtain conversion speed */
+ unsigned long extra_iobase;
};
static inline short munge_sample(short data)
@@ -499,7 +500,7 @@ static irqreturn_t das16m1_interrupt(int irq, void *d)
int status;
struct comedi_device *dev = d;
- if (dev->attached == 0) {
+ if (!dev->attached) {
comedi_error(dev, "premature interrupt");
return IRQ_HANDLED;
}
@@ -571,28 +572,21 @@ static int das16m1_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
unsigned int irq;
- unsigned long iobase;
-
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- if (!request_region(iobase, DAS16M1_SIZE, dev->board_name)) {
- comedi_error(dev, "I/O port conflict\n");
- return -EIO;
- }
- if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
- dev->board_name)) {
- release_region(iobase, DAS16M1_SIZE);
- comedi_error(dev, "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], DAS16M1_SIZE);
+ if (ret)
+ return ret;
+ /* Request an additional region for the 8255 */
+ ret = __comedi_request_region(dev, dev->iobase + DAS16M1_82C55,
+ DAS16M1_SIZE2);
+ if (ret)
+ return ret;
+ devpriv->extra_iobase = dev->iobase + DAS16M1_82C55;
/* now for the irq */
irq = it->options[1];
@@ -654,7 +648,9 @@ static int das16m1_attach(struct comedi_device *dev,
s = &dev->subdevices[3];
/* 8255 */
- subdev_8255_init(dev, s, NULL, dev->iobase + DAS16M1_82C55);
+ ret = subdev_8255_init(dev, s, NULL, devpriv->extra_iobase);
+ if (ret)
+ return ret;
/* disable upper half of hardware conversion counter so it doesn't mess with us */
outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
@@ -674,14 +670,12 @@ static int das16m1_attach(struct comedi_device *dev,
static void das16m1_detach(struct comedi_device *dev)
{
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[3]);
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase) {
- release_region(dev->iobase, DAS16M1_SIZE);
- release_region(dev->iobase + DAS16M1_82C55, DAS16M1_SIZE2);
- }
+ struct das16m1_private_struct *devpriv = dev->private;
+
+ comedi_spriv_free(dev, 3);
+ if (devpriv && devpriv->extra_iobase)
+ release_region(devpriv->extra_iobase, DAS16M1_SIZE2);
+ comedi_legacy_detach(dev);
}
static struct comedi_driver das16m1_driver = {
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 7900f959555..abf7638a9f7 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -429,11 +429,6 @@ static const struct das1800_board das1800_boards[] = {
},
};
-/*
- * Useful for shorthand access to the particular board structure
- */
-#define thisboard ((const struct das1800_board *)dev->board_ptr)
-
struct das1800_private {
volatile unsigned int count; /* number of data points left to be taken */
unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
@@ -454,14 +449,6 @@ struct das1800_private {
short ao_update_bits; /* remembers the last write to the 'update' dac */
};
-/* analog out range for boards with basic analog out */
-static const struct comedi_lrange range_ao_1 = {
- 1,
- {
- RANGE(-10, 10),
- }
-};
-
/* analog out range for 'ao' boards */
/*
static const struct comedi_lrange range_ao_2 = {
@@ -476,6 +463,8 @@ static const struct comedi_lrange range_ao_2 = {
static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
uint16_t sample)
{
+ const struct das1800_board *thisboard = comedi_board(dev);
+
sample += 1 << (thisboard->resolution - 1);
return sample;
}
@@ -731,7 +720,7 @@ static irqreturn_t das1800_interrupt(int irq, void *d)
struct comedi_device *dev = d;
unsigned int status;
- if (dev->attached == 0) {
+ if (!dev->attached) {
comedi_error(dev, "premature interrupt");
return IRQ_HANDLED;
}
@@ -789,6 +778,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ const struct das1800_board *thisboard = comedi_board(dev);
struct das1800_private *devpriv = dev->private;
int err = 0;
unsigned int tmp_arg;
@@ -1232,6 +1222,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct das1800_board *thisboard = comedi_board(dev);
int i, n;
int chan, range, aref, chan_range;
int timeout = 1000;
@@ -1295,6 +1286,7 @@ static int das1800_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct das1800_board *thisboard = comedi_board(dev);
struct das1800_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
/* int range = CR_RANGE(insn->chanspec); */
@@ -1516,46 +1508,23 @@ static int das1800_probe(struct comedi_device *dev)
static int das1800_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ const struct das1800_board *thisboard = comedi_board(dev);
struct das1800_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase = it->options[0];
unsigned int irq = it->options[1];
unsigned int dma0 = it->options[2];
unsigned int dma1 = it->options[3];
- unsigned long iobase2;
int board;
- int retval;
+ int ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor,
- dev->driver->driver_name, iobase);
- if (irq) {
- printk(KERN_CONT ", irq %u", irq);
- if (dma0) {
- printk(KERN_CONT ", dma %u", dma0);
- if (dma1)
- printk(KERN_CONT " and %u", dma1);
- }
- }
- printk(KERN_CONT "\n");
-
- if (iobase == 0) {
- dev_err(dev->class_dev, "io base address required\n");
- return -EINVAL;
- }
-
- /* check if io addresses are available */
- if (!request_region(iobase, DAS1800_SIZE, dev->driver->driver_name)) {
- printk
- (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
- iobase, iobase + DAS1800_SIZE - 1);
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
+ if (ret)
+ return ret;
board = das1800_probe(dev);
if (board < 0) {
@@ -1564,18 +1533,16 @@ static int das1800_attach(struct comedi_device *dev,
}
dev->board_ptr = das1800_boards + board;
+ thisboard = comedi_board(dev);
dev->board_name = thisboard->name;
/* if it is an 'ao' board with fancy analog out then we need extra io ports */
if (thisboard->ao_ability == 2) {
- iobase2 = iobase + IOBASE2;
- if (!request_region(iobase2, DAS1800_SIZE,
- dev->driver->driver_name)) {
- printk
- (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
- iobase2, iobase2 + DAS1800_SIZE - 1);
- return -EIO;
- }
+ unsigned long iobase2 = dev->iobase + IOBASE2;
+
+ ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
+ if (ret)
+ return ret;
devpriv->iobase2 = iobase2;
}
@@ -1618,9 +1585,9 @@ static int das1800_attach(struct comedi_device *dev,
break;
}
- retval = das1800_init_dma(dev, dma0, dma1);
- if (retval < 0)
- return retval;
+ ret = das1800_init_dma(dev, dma0, dma1);
+ if (ret < 0)
+ return ret;
if (devpriv->ai_buf0 == NULL) {
devpriv->ai_buf0 =
@@ -1629,9 +1596,9 @@ static int das1800_attach(struct comedi_device *dev,
return -ENOMEM;
}
- retval = comedi_alloc_subdevices(dev, 4);
- if (retval)
- return retval;
+ ret = comedi_alloc_subdevices(dev, 4);
+ if (ret)
+ return ret;
/* analog input subdevice */
s = &dev->subdevices[0];
@@ -1657,7 +1624,7 @@ static int das1800_attach(struct comedi_device *dev,
s->subdev_flags = SDF_WRITABLE;
s->n_chan = thisboard->ao_n_chan;
s->maxdata = (1 << thisboard->resolution) - 1;
- s->range_table = &range_ao_1;
+ s->range_table = &range_bipolar10;
s->insn_write = das1800_ao_winsn;
} else {
s->type = COMEDI_SUBD_UNUSED;
@@ -1701,21 +1668,18 @@ static void das1800_detach(struct comedi_device *dev)
{
struct das1800_private *devpriv = dev->private;
- if (dev->iobase)
- release_region(dev->iobase, DAS1800_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
if (devpriv) {
- if (devpriv->iobase2)
- release_region(devpriv->iobase2, DAS1800_SIZE);
if (devpriv->dma0)
free_dma(devpriv->dma0);
if (devpriv->dma1)
free_dma(devpriv->dma1);
kfree(devpriv->ai_buf0);
kfree(devpriv->ai_buf1);
+ if (devpriv->iobase2)
+ release_region(devpriv->iobase2, DAS1800_SIZE);
}
-};
+ comedi_legacy_detach(dev);
+}
static struct comedi_driver das1800_driver = {
.driver_name = "das1800",
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 2efddb89bbc..11424fb5b4d 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -284,23 +284,12 @@ static int das6402_attach(struct comedi_device *dev,
{
struct das6402_private *devpriv;
unsigned int irq;
- unsigned long iobase;
int ret;
struct comedi_subdevice *s;
- dev->board_name = "das6402";
-
- iobase = it->options[0];
- if (iobase == 0)
- iobase = 0x300;
-
- if (!request_region(iobase, DAS6402_SIZE, "das6402")) {
- dev_err(dev->class_dev, "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- /* should do a probe here */
+ ret = comedi_request_region(dev, it->options[0], DAS6402_SIZE);
+ if (ret)
+ return ret;
irq = it->options[0];
dev_dbg(dev->class_dev, "( irq = %u )\n", irq);
@@ -335,19 +324,11 @@ static int das6402_attach(struct comedi_device *dev,
return 0;
}
-static void das6402_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, DAS6402_SIZE);
-}
-
static struct comedi_driver das6402_driver = {
.driver_name = "das6402",
.module = THIS_MODULE,
.attach = das6402_attach,
- .detach = das6402_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(das6402_driver)
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 38f625be812..9ce6cbcc7ee 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -95,8 +95,8 @@ cmd triggers supported:
#define IRQ 0x8
#define BUSY 0x80
#define DAS800_GAIN 3
-#define CIO_FFOV 0x8 /* fifo overflow for cio-das802/16 */
-#define CIO_ENHF 0x90 /* interrupt fifo half full for cio-das802/16 */
+#define CIO_FFOV 0x8 /* cio-das802/16 fifo overflow */
+#define CIO_ENHF 0x90 /* cio-das802/16 fifo half full int ena */
#define CONTROL1 0x80
#define CONV_CONTROL 0xa0
#define SCAN_LIMITS 0xc0
@@ -107,6 +107,8 @@ cmd triggers supported:
#define STATUS2_INTE 0X20
#define DAS800_ID 7
+#define DAS802_16_HALF_FIFO_SZ 128
+
struct das800_board {
const char *name;
int ai_speed;
@@ -114,491 +116,204 @@ struct das800_board {
int resolution;
};
-/* analog input ranges */
-static const struct comedi_lrange range_das800_ai = {
- 1,
- {
- RANGE(-5, 5),
- }
-};
-
static const struct comedi_lrange range_das801_ai = {
- 9,
- {
- RANGE(-5, 5),
- RANGE(-10, 10),
- RANGE(0, 10),
- RANGE(-0.5, 0.5),
- RANGE(0, 1),
- RANGE(-0.05, 0.05),
- RANGE(0, 0.1),
- RANGE(-0.01, 0.01),
- RANGE(0, 0.02),
- }
+ 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ BIP_RANGE(0.5),
+ UNI_RANGE(1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(0.1),
+ BIP_RANGE(0.01),
+ UNI_RANGE(0.02)
+ }
};
static const struct comedi_lrange range_cio_das801_ai = {
- 9,
- {
- RANGE(-5, 5),
- RANGE(-10, 10),
- RANGE(0, 10),
- RANGE(-0.5, 0.5),
- RANGE(0, 1),
- RANGE(-0.05, 0.05),
- RANGE(0, 0.1),
- RANGE(-0.005, 0.005),
- RANGE(0, 0.01),
- }
+ 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ BIP_RANGE(0.5),
+ UNI_RANGE(1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(0.1),
+ BIP_RANGE(0.005),
+ UNI_RANGE(0.01)
+ }
};
static const struct comedi_lrange range_das802_ai = {
- 9,
- {
- RANGE(-5, 5),
- RANGE(-10, 10),
- RANGE(0, 10),
- RANGE(-2.5, 2.5),
- RANGE(0, 5),
- RANGE(-1.25, 1.25),
- RANGE(0, 2.5),
- RANGE(-0.625, 0.625),
- RANGE(0, 1.25),
- }
+ 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ BIP_RANGE(2.5),
+ UNI_RANGE(5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(2.5),
+ BIP_RANGE(0.625),
+ UNI_RANGE(1.25)
+ }
};
static const struct comedi_lrange range_das80216_ai = {
- 8,
- {
- RANGE(-10, 10),
- RANGE(0, 10),
- RANGE(-5, 5),
- RANGE(0, 5),
- RANGE(-2.5, 2.5),
- RANGE(0, 2.5),
- RANGE(-1.25, 1.25),
- RANGE(0, 1.25),
- }
+ 8, {
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ BIP_RANGE(5),
+ UNI_RANGE(5),
+ BIP_RANGE(2.5),
+ UNI_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(1.25)
+ }
};
-enum { das800, ciodas800, das801, ciodas801, das802, ciodas802, ciodas80216 };
+enum das800_boardinfo {
+ BOARD_DAS800,
+ BOARD_CIODAS800,
+ BOARD_DAS801,
+ BOARD_CIODAS801,
+ BOARD_DAS802,
+ BOARD_CIODAS802,
+ BOARD_CIODAS80216,
+};
static const struct das800_board das800_boards[] = {
- {
- .name = "das-800",
- .ai_speed = 25000,
- .ai_range = &range_das800_ai,
- .resolution = 12,
- },
- {
- .name = "cio-das800",
- .ai_speed = 20000,
- .ai_range = &range_das800_ai,
- .resolution = 12,
- },
- {
- .name = "das-801",
- .ai_speed = 25000,
- .ai_range = &range_das801_ai,
- .resolution = 12,
- },
- {
- .name = "cio-das801",
- .ai_speed = 20000,
- .ai_range = &range_cio_das801_ai,
- .resolution = 12,
- },
- {
- .name = "das-802",
- .ai_speed = 25000,
- .ai_range = &range_das802_ai,
- .resolution = 12,
- },
- {
- .name = "cio-das802",
- .ai_speed = 20000,
- .ai_range = &range_das802_ai,
- .resolution = 12,
- },
- {
- .name = "cio-das802/16",
- .ai_speed = 10000,
- .ai_range = &range_das80216_ai,
- .resolution = 16,
- },
+ [BOARD_DAS800] = {
+ .name = "das-800",
+ .ai_speed = 25000,
+ .ai_range = &range_bipolar5,
+ .resolution = 12,
+ },
+ [BOARD_CIODAS800] = {
+ .name = "cio-das800",
+ .ai_speed = 20000,
+ .ai_range = &range_bipolar5,
+ .resolution = 12,
+ },
+ [BOARD_DAS801] = {
+ .name = "das-801",
+ .ai_speed = 25000,
+ .ai_range = &range_das801_ai,
+ .resolution = 12,
+ },
+ [BOARD_CIODAS801] = {
+ .name = "cio-das801",
+ .ai_speed = 20000,
+ .ai_range = &range_cio_das801_ai,
+ .resolution = 12,
+ },
+ [BOARD_DAS802] = {
+ .name = "das-802",
+ .ai_speed = 25000,
+ .ai_range = &range_das802_ai,
+ .resolution = 12,
+ },
+ [BOARD_CIODAS802] = {
+ .name = "cio-das802",
+ .ai_speed = 20000,
+ .ai_range = &range_das802_ai,
+ .resolution = 12,
+ },
+ [BOARD_CIODAS80216] = {
+ .name = "cio-das802/16",
+ .ai_speed = 10000,
+ .ai_range = &range_das80216_ai,
+ .resolution = 16,
+ },
};
-/*
- * Useful for shorthand access to the particular board structure
- */
-#define thisboard ((const struct das800_board *)dev->board_ptr)
-
struct das800_private {
- volatile unsigned int count; /* number of data points left to be taken */
- volatile int forever; /* flag indicating whether we should take data forever */
- unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
- unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
- volatile int do_bits; /* digital output bits */
-};
-
-static int das800_attach(struct comedi_device *dev,
- struct comedi_devconfig *it);
-static void das800_detach(struct comedi_device *dev);
-static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-
-static struct comedi_driver driver_das800 = {
- .driver_name = "das800",
- .module = THIS_MODULE,
- .attach = das800_attach,
- .detach = das800_detach,
- .num_names = ARRAY_SIZE(das800_boards),
- .board_name = &das800_boards[0].name,
- .offset = sizeof(struct das800_board),
+ unsigned int count; /* number of data points left to be taken */
+ unsigned int divisor1; /* counter 1 value for timed conversions */
+ unsigned int divisor2; /* counter 2 value for timed conversions */
+ unsigned int do_bits; /* digital output bits */
+ bool forever; /* flag that we should take data forever */
};
-static irqreturn_t das800_interrupt(int irq, void *d);
-static void enable_das800(struct comedi_device *dev);
-static void disable_das800(struct comedi_device *dev);
-static int das800_ai_do_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-static int das800_ai_do_cmd(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static int das800_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-static int das800_di_rbits(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-static int das800_do_wbits(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data);
-static int das800_probe(struct comedi_device *dev);
-static int das800_set_frequency(struct comedi_device *dev);
-
-/* checks and probes das-800 series board type */
-static int das800_probe(struct comedi_device *dev)
+static void das800_ind_write(struct comedi_device *dev,
+ unsigned val, unsigned reg)
{
- int id_bits;
- unsigned long irq_flags;
- int board;
-
- /* 'comedi spin lock irqsave' disables even rt interrupts, we use them to protect indirect addressing */
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(ID, dev->iobase + DAS800_GAIN); /* select base address + 7 to be ID register */
- id_bits = inb(dev->iobase + DAS800_ID) & 0x3; /* get id bits */
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- board = thisboard - das800_boards;
-
- switch (id_bits) {
- case 0x0:
- if (board == das800) {
- dev_dbg(dev->class_dev, "Board model: DAS-800\n");
- return board;
- }
- if (board == ciodas800) {
- dev_dbg(dev->class_dev, "Board model: CIO-DAS800\n");
- return board;
- }
- dev_dbg(dev->class_dev, "Board model (probed): DAS-800\n");
- return das800;
- break;
- case 0x2:
- if (board == das801) {
- dev_dbg(dev->class_dev, "Board model: DAS-801\n");
- return board;
- }
- if (board == ciodas801) {
- dev_dbg(dev->class_dev, "Board model: CIO-DAS801\n");
- return board;
- }
- dev_dbg(dev->class_dev, "Board model (probed): DAS-801\n");
- return das801;
- break;
- case 0x3:
- if (board == das802) {
- dev_dbg(dev->class_dev, "Board model: DAS-802\n");
- return board;
- }
- if (board == ciodas802) {
- dev_dbg(dev->class_dev, "Board model: CIO-DAS802\n");
- return board;
- }
- if (board == ciodas80216) {
- dev_dbg(dev->class_dev, "Board model: CIO-DAS802/16\n");
- return board;
- }
- dev_dbg(dev->class_dev, "Board model (probed): DAS-802\n");
- return das802;
- break;
- default:
- dev_dbg(dev->class_dev,
- "Board model: probe returned 0x%x (unknown)\n",
- id_bits);
- return board;
- break;
- }
- return -1;
+ /*
+ * Select dev->iobase + 2 to be desired register
+ * then write to that register.
+ */
+ outb(reg, dev->iobase + DAS800_GAIN);
+ outb(val, dev->iobase + 2);
}
-module_comedi_driver(driver_das800);
+static unsigned das800_ind_read(struct comedi_device *dev, unsigned reg)
+{
+ /*
+ * Select dev->iobase + 7 to be desired register
+ * then read from that register.
+ */
+ outb(reg, dev->iobase + DAS800_GAIN);
+ return inb(dev->iobase + 7);
+}
-/* interrupt service routine */
-static irqreturn_t das800_interrupt(int irq, void *d)
+static void das800_enable(struct comedi_device *dev)
{
- short i; /* loop index */
- short dataPoint = 0;
- struct comedi_device *dev = d;
+ const struct das800_board *thisboard = comedi_board(dev);
struct das800_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
- struct comedi_async *async;
- int status;
unsigned long irq_flags;
- static const int max_loops = 128; /* half-fifo size for cio-das802/16 */
- /* flags */
- int fifo_empty = 0;
- int fifo_overflow = 0;
- status = inb(dev->iobase + DAS800_STATUS);
- /* if interrupt was not generated by board or driver not attached, quit */
- if (!(status & IRQ))
- return IRQ_NONE;
- if (!(dev->attached))
- return IRQ_HANDLED;
-
- /* wait until here to initialize async, since we will get null dereference
- * if interrupt occurs before driver is fully attached!
- */
- async = s->async;
-
- /* if hardware conversions are not enabled, then quit */
spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select base address + 7 to be STATUS2 register */
- status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN;
- /* don't release spinlock yet since we want to make sure no one else disables hardware conversions */
- if (status == 0) {
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- return IRQ_HANDLED;
- }
-
- /* loop while card's fifo is not empty (and limit to half fifo for cio-das802/16) */
- for (i = 0; i < max_loops; i++) {
- /* read 16 bits from dev->iobase and dev->iobase + 1 */
- dataPoint = inb(dev->iobase + DAS800_LSB);
- dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
- if (thisboard->resolution == 12) {
- fifo_empty = dataPoint & FIFO_EMPTY;
- fifo_overflow = dataPoint & FIFO_OVF;
- if (fifo_overflow)
- break;
- } else {
- fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */
- }
- if (fifo_empty)
- break;
- /* strip off extraneous bits for 12 bit cards */
- if (thisboard->resolution == 12)
- dataPoint = (dataPoint >> 4) & 0xfff;
- /* if there are more data points to collect */
- if (devpriv->count > 0 || devpriv->forever == 1) {
- /* write data point to buffer */
- cfc_write_to_buffer(s, dataPoint);
- if (devpriv->count > 0)
- devpriv->count--;
- }
- }
- async->events |= COMEDI_CB_BLOCK;
- /* check for fifo overflow */
- if (thisboard->resolution == 12) {
- fifo_overflow = dataPoint & FIFO_OVF;
- /* else cio-das802/16 */
- } else {
- fifo_overflow = inb(dev->iobase + DAS800_GAIN) & CIO_FFOV;
- }
- if (fifo_overflow) {
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- comedi_error(dev, "DAS800 FIFO overflow");
- das800_cancel(dev, s);
- async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s);
- async->events = 0;
- return IRQ_HANDLED;
- }
- if (devpriv->count > 0 || devpriv->forever == 1) {
- /* Re-enable card's interrupt.
- * We already have spinlock, so indirect addressing is safe */
- outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
- outb(CONTROL1_INTE | devpriv->do_bits,
- dev->iobase + DAS800_CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- /* otherwise, stop taking data */
- } else {
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- disable_das800(dev); /* disable hardware triggered conversions */
- async->events |= COMEDI_CB_EOA;
- }
- comedi_event(dev, s);
- async->events = 0;
- return IRQ_HANDLED;
+ /* enable fifo-half full interrupts for cio-das802/16 */
+ if (thisboard->resolution == 16)
+ outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
+ /* enable hardware triggering */
+ das800_ind_write(dev, CONV_HCEN, CONV_CONTROL);
+ /* enable card's interrupt */
+ das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
}
-static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static void das800_disable(struct comedi_device *dev)
{
- struct das800_private *devpriv;
- struct comedi_subdevice *s;
- unsigned long iobase = it->options[0];
- unsigned int irq = it->options[1];
unsigned long irq_flags;
- int board;
- int ret;
-
- dev_info(dev->class_dev, "das800: io 0x%lx\n", iobase);
- if (irq)
- dev_dbg(dev->class_dev, "irq %u\n", irq);
- devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
- if (!devpriv)
- return -ENOMEM;
- dev->private = devpriv;
-
- if (iobase == 0) {
- dev_err(dev->class_dev,
- "io base address required for das800\n");
- return -EINVAL;
- }
-
- /* check if io addresses are available */
- if (!request_region(iobase, DAS800_SIZE, "das800")) {
- dev_err(dev->class_dev, "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- board = das800_probe(dev);
- if (board < 0) {
- dev_dbg(dev->class_dev, "unable to determine board type\n");
- return -ENODEV;
- }
- dev->board_ptr = das800_boards + board;
-
- /* grab our IRQ */
- if (irq == 1 || irq > 7) {
- dev_err(dev->class_dev, "irq out of range\n");
- return -EINVAL;
- }
- if (irq) {
- if (request_irq(irq, das800_interrupt, 0, "das800", dev)) {
- dev_err(dev->class_dev, "unable to allocate irq %u\n",
- irq);
- return -EINVAL;
- }
- }
- dev->irq = irq;
-
- dev->board_name = thisboard->name;
-
- ret = comedi_alloc_subdevices(dev, 3);
- if (ret)
- return ret;
-
- /* analog input subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
- s->n_chan = 8;
- s->len_chanlist = 8;
- s->maxdata = (1 << thisboard->resolution) - 1;
- s->range_table = thisboard->ai_range;
- s->do_cmd = das800_ai_do_cmd;
- s->do_cmdtest = das800_ai_do_cmdtest;
- s->insn_read = das800_ai_rinsn;
- s->cancel = das800_cancel;
-
- /* di */
- s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 3;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das800_di_rbits;
-
- /* do */
- s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 4;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = das800_do_wbits;
-
- disable_das800(dev);
-
- /* initialize digital out channels */
spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
- outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+ /* disable hardware triggering of conversions */
+ das800_ind_write(dev, 0x0, CONV_CONTROL);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
- return 0;
-};
-
-static void das800_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, DAS800_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
-};
-
-static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int das800_set_frequency(struct comedi_device *dev)
{
struct das800_private *devpriv = dev->private;
+ int err = 0;
+
+ if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
+ err++;
+ if (i8254_load(dev->iobase + DAS800_8254, 0, 2, devpriv->divisor2, 2))
+ err++;
+ if (err)
+ return -1;
- devpriv->forever = 0;
- devpriv->count = 0;
- disable_das800(dev);
return 0;
}
-/* enable_das800 makes the card start taking hardware triggered conversions */
-static void enable_das800(struct comedi_device *dev)
+static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct das800_private *devpriv = dev->private;
- unsigned long irq_flags;
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- /* enable fifo-half full interrupts for cio-das802/16 */
- if (thisboard->resolution == 16)
- outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
- outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
- outb(CONV_HCEN, dev->iobase + DAS800_CONV_CONTROL); /* enable hardware triggering */
- outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
- outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1); /* enable card's interrupt */
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-}
-
-/* disable_das800 stops hardware triggered conversions */
-static void disable_das800(struct comedi_device *dev)
-{
- unsigned long irq_flags;
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
- outb(0x0, dev->iobase + DAS800_CONV_CONTROL); /* disable hardware triggering of conversions */
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ devpriv->forever = false;
+ devpriv->count = 0;
+ das800_disable(dev);
+ return 0;
}
static int das800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ const struct das800_board *thisboard = comedi_board(dev);
struct das800_private *devpriv = dev->private;
int err = 0;
- int tmp;
- int gain, startChan;
- int i;
/* Step 1 : check if triggers are trivially valid */
@@ -644,11 +359,13 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
if (cmd->convert_src == TRIG_TIMER) {
- tmp = cmd->convert_arg;
+ int tmp = cmd->convert_arg;
+
/* calculate counter values that give desired timing */
- i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
- &(devpriv->divisor2),
- &(cmd->convert_arg),
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &devpriv->divisor1,
+ &devpriv->divisor2,
+ &cmd->convert_arg,
cmd->flags & TRIG_ROUND_MASK);
if (tmp != cmd->convert_arg)
err++;
@@ -659,18 +376,21 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
/* check channel/gain list against card's limitations */
if (cmd->chanlist) {
- gain = CR_RANGE(cmd->chanlist[0]);
- startChan = CR_CHAN(cmd->chanlist[0]);
+ unsigned int chan = CR_CHAN(cmd->chanlist[0]);
+ unsigned int range = CR_RANGE(cmd->chanlist[0]);
+ unsigned int next;
+ int i;
+
for (i = 1; i < cmd->chanlist_len; i++) {
- if (CR_CHAN(cmd->chanlist[i]) !=
- (startChan + i) % N_CHAN_AI) {
- comedi_error(dev,
- "entries in chanlist must be consecutive channels, counting upwards\n");
+ next = cmd->chanlist[i];
+ if (CR_CHAN(next) != (chan + i) % N_CHAN_AI) {
+ dev_err(dev->class_dev,
+ "chanlist must be consecutive, counting upwards\n");
err++;
}
- if (CR_RANGE(cmd->chanlist[i]) != gain) {
- comedi_error(dev,
- "entries in chanlist must all have the same gain\n");
+ if (CR_RANGE(next) != range) {
+ dev_err(dev->class_dev,
+ "chanlist must all have the same gain\n");
err++;
}
}
@@ -685,32 +405,24 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
static int das800_ai_do_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ const struct das800_board *thisboard = comedi_board(dev);
struct das800_private *devpriv = dev->private;
- int startChan, endChan, scan, gain;
+ struct comedi_async *async = s->async;
+ unsigned int gain = CR_RANGE(async->cmd.chanlist[0]);
+ unsigned int start_chan = CR_CHAN(async->cmd.chanlist[0]);
+ unsigned int end_chan = (start_chan + async->cmd.chanlist_len - 1) % 8;
+ unsigned int scan_chans = (end_chan << 3) | start_chan;
int conv_bits;
unsigned long irq_flags;
- struct comedi_async *async = s->async;
- if (!dev->irq) {
- comedi_error(dev,
- "no irq assigned for das-800, cannot do hardware conversions");
- return -1;
- }
-
- disable_das800(dev);
-
- /* set channel scan limits */
- startChan = CR_CHAN(async->cmd.chanlist[0]);
- endChan = (startChan + async->cmd.chanlist_len - 1) % 8;
- scan = (endChan << 3) | startChan;
+ das800_disable(dev);
spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(SCAN_LIMITS, dev->iobase + DAS800_GAIN); /* select base address + 2 to be scan limits register */
- outb(scan, dev->iobase + DAS800_SCAN_LIMITS); /* set scan limits */
+ /* set scan limits */
+ das800_ind_write(dev, scan_chans, SCAN_LIMITS);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
/* set gain */
- gain = CR_RANGE(async->cmd.chanlist[0]);
if (thisboard->resolution == 12 && gain > 0)
gain += 0x7;
gain &= 0xf;
@@ -719,10 +431,10 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
switch (async->cmd.stop_src) {
case TRIG_COUNT:
devpriv->count = async->cmd.stop_arg * async->cmd.chanlist_len;
- devpriv->forever = 0;
+ devpriv->forever = false;
break;
case TRIG_NONE:
- devpriv->forever = 1;
+ devpriv->forever = true;
devpriv->count = 0;
break;
default:
@@ -740,11 +452,6 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
case TRIG_TIMER:
conv_bits |= CASC | ITE;
/* set conversion frequency */
- i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
- &(devpriv->divisor2),
- &(async->cmd.convert_arg),
- async->cmd.
- flags & TRIG_ROUND_MASK);
if (das800_set_frequency(dev) < 0) {
comedi_error(dev, "Error setting up counters");
return -1;
@@ -757,125 +464,333 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
}
spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
- outb(conv_bits, dev->iobase + DAS800_CONV_CONTROL);
+ das800_ind_write(dev, conv_bits, CONV_CONTROL);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
async->events = 0;
- enable_das800(dev);
+ das800_enable(dev);
return 0;
}
-static int das800_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
+static unsigned int das800_ai_get_sample(struct comedi_device *dev)
{
+ unsigned int lsb = inb(dev->iobase + DAS800_LSB);
+ unsigned int msb = inb(dev->iobase + DAS800_MSB);
+
+ return (msb << 8) | lsb;
+}
+
+static irqreturn_t das800_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
struct das800_private *devpriv = dev->private;
- int i, n;
- int chan;
- int range;
- int lsb, msb;
- int timeout = 1000;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s ? s->async : NULL;
unsigned long irq_flags;
+ unsigned int status;
+ unsigned int val;
+ bool fifo_empty;
+ bool fifo_overflow;
+ int i;
- disable_das800(dev); /* disable hardware conversions (enables software conversions) */
+ status = inb(dev->iobase + DAS800_STATUS);
+ if (!(status & IRQ))
+ return IRQ_NONE;
+ if (!dev->attached)
+ return IRQ_HANDLED;
- /* set multiplexer */
- chan = CR_CHAN(insn->chanspec);
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+ status = das800_ind_read(dev, CONTROL1) & STATUS2_HCEN;
+ /*
+ * Don't release spinlock yet since we want to make sure
+ * no one else disables hardware conversions.
+ */
+ /* if hardware conversions are not enabled, then quit */
+ if (status == 0) {
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ return IRQ_HANDLED;
+ }
+
+ for (i = 0; i < DAS802_16_HALF_FIFO_SZ; i++) {
+ val = das800_ai_get_sample(dev);
+ if (s->maxdata == 0x0fff) {
+ fifo_empty = !!(val & FIFO_EMPTY);
+ fifo_overflow = !!(val & FIFO_OVF);
+ } else {
+ /* cio-das802/16 has no fifo empty status bit */
+ fifo_empty = false;
+ fifo_overflow = !!(inb(dev->iobase + DAS800_GAIN) &
+ CIO_FFOV);
+ }
+ if (fifo_empty || fifo_overflow)
+ break;
+
+ if (s->maxdata == 0x0fff)
+ val >>= 4; /* 12-bit sample */
+
+ /* if there are more data points to collect */
+ if (devpriv->count > 0 || devpriv->forever) {
+ /* write data point to buffer */
+ cfc_write_to_buffer(s, val & s->maxdata);
+ devpriv->count--;
+ }
+ }
+ async->events |= COMEDI_CB_BLOCK;
+
+ if (fifo_overflow) {
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ das800_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ async->events = 0;
+ return IRQ_HANDLED;
+ }
+
+ if (devpriv->count > 0 || devpriv->forever) {
+ /* Re-enable card's interrupt.
+ * We already have spinlock, so indirect addressing is safe */
+ das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits,
+ CONTROL1);
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ } else {
+ /* otherwise, stop taking data */
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ das800_disable(dev);
+ async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ async->events = 0;
+ return IRQ_HANDLED;
+}
+
+static int das800_wait_for_conv(struct comedi_device *dev, int timeout)
+{
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
+ return 0;
+ }
+ return -ETIME;
+}
+
+static int das800_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct das800_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned long irq_flags;
+ unsigned int val;
+ int ret;
+ int i;
+
+ das800_disable(dev);
+
+ /* set multiplexer */
spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
- outb(chan | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+ das800_ind_write(dev, chan | devpriv->do_bits, CONTROL1);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
/* set gain / range */
- range = CR_RANGE(insn->chanspec);
- if (thisboard->resolution == 12 && range)
+ if (s->maxdata == 0x0fff && range)
range += 0x7;
range &= 0xf;
outb(range, dev->iobase + DAS800_GAIN);
udelay(5);
- for (n = 0; n < insn->n; n++) {
+ for (i = 0; i < insn->n; i++) {
/* trigger conversion */
outb_p(0, dev->iobase + DAS800_MSB);
- for (i = 0; i < timeout; i++) {
- if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
- break;
- }
- if (i == timeout) {
- comedi_error(dev, "timeout");
- return -ETIME;
- }
- lsb = inb(dev->iobase + DAS800_LSB);
- msb = inb(dev->iobase + DAS800_MSB);
- if (thisboard->resolution == 12) {
- data[n] = (lsb >> 4) & 0xff;
- data[n] |= (msb << 4);
- } else {
- data[n] = (msb << 8) | lsb;
- }
+ ret = das800_wait_for_conv(dev, 1000);
+ if (ret)
+ return ret;
+
+ val = das800_ai_get_sample(dev);
+ if (s->maxdata == 0x0fff)
+ val >>= 4; /* 12-bit sample */
+ data[i] = val & s->maxdata;
}
- return n;
+ return insn->n;
}
-static int das800_di_rbits(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
+static int das800_di_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int bits;
-
- bits = inb(dev->iobase + DAS800_STATUS) >> 4;
- bits &= 0x7;
- data[1] = bits;
- data[0] = 0;
+ data[1] = (inb(dev->iobase + DAS800_STATUS) >> 4) & 0x7;
return insn->n;
}
-static int das800_do_wbits(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
+static int das800_do_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct das800_private *devpriv = dev->private;
- int wbits;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
unsigned long irq_flags;
- /* only set bits that have been masked */
- data[0] &= 0xf;
- wbits = devpriv->do_bits >> 4;
- wbits &= ~data[0];
- wbits |= data[0] & data[1];
- devpriv->do_bits = wbits << 4;
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
+ devpriv->do_bits = s->state << 4;
- spin_lock_irqsave(&dev->spinlock, irq_flags);
- outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
- outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
- spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+ das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits,
+ CONTROL1);
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ }
- data[1] = wbits;
+ data[1] = s->state;
return insn->n;
}
-/* loads counters with divisor1, divisor2 from private structure */
-static int das800_set_frequency(struct comedi_device *dev)
+static int das800_probe(struct comedi_device *dev)
{
- struct das800_private *devpriv = dev->private;
- int err = 0;
+ const struct das800_board *thisboard = comedi_board(dev);
+ int board = thisboard ? thisboard - das800_boards : -EINVAL;
+ int id_bits;
+ unsigned long irq_flags;
- if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
- err++;
- if (i8254_load(dev->iobase + DAS800_8254, 0, 2, devpriv->divisor2, 2))
- err++;
- if (err)
- return -1;
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+ id_bits = das800_ind_read(dev, ID) & 0x3;
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- return 0;
+ switch (id_bits) {
+ case 0x0:
+ if (board == BOARD_DAS800 || board == BOARD_CIODAS800)
+ break;
+ dev_dbg(dev->class_dev, "Board model (probed): DAS-800\n");
+ board = BOARD_DAS800;
+ break;
+ case 0x2:
+ if (board == BOARD_DAS801 || board == BOARD_CIODAS801)
+ break;
+ dev_dbg(dev->class_dev, "Board model (probed): DAS-801\n");
+ board = BOARD_DAS801;
+ break;
+ case 0x3:
+ if (board == BOARD_DAS802 || board == BOARD_CIODAS802 ||
+ board == BOARD_CIODAS80216)
+ break;
+ dev_dbg(dev->class_dev, "Board model (probed): DAS-802\n");
+ board = BOARD_DAS802;
+ break;
+ default:
+ dev_dbg(dev->class_dev, "Board model: 0x%x (unknown)\n",
+ id_bits);
+ board = -EINVAL;
+ break;
+ }
+ return board;
}
+static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+ const struct das800_board *thisboard = comedi_board(dev);
+ struct das800_private *devpriv;
+ struct comedi_subdevice *s;
+ unsigned int irq = it->options[1];
+ unsigned long irq_flags;
+ int board;
+ int ret;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_request_region(dev, it->options[0], DAS800_SIZE);
+ if (ret)
+ return ret;
+
+ board = das800_probe(dev);
+ if (board < 0) {
+ dev_dbg(dev->class_dev, "unable to determine board type\n");
+ return -ENODEV;
+ }
+ dev->board_ptr = das800_boards + board;
+ thisboard = comedi_board(dev);
+ dev->board_name = thisboard->name;
+
+ if (irq > 1 && irq <= 7) {
+ ret = request_irq(irq, das800_interrupt, 0, dev->board_name,
+ dev);
+ if (ret == 0)
+ dev->irq = irq;
+ }
+
+ ret = comedi_alloc_subdevices(dev, 3);
+ if (ret)
+ return ret;
+
+ /* Analog Input subdevice */
+ s = &dev->subdevices[0];
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = thisboard->ai_range;
+ s->insn_read = das800_ai_insn_read;
+ if (dev->irq) {
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = 8;
+ s->do_cmdtest = das800_ai_do_cmdtest;
+ s->do_cmd = das800_ai_do_cmd;
+ s->cancel = das800_cancel;
+ }
+
+ /* Digital Input subdevice */
+ s = &dev->subdevices[1];
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das800_di_insn_bits;
+
+ /* Digital Output subdevice */
+ s = &dev->subdevices[2];
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das800_do_insn_bits;
+
+ das800_disable(dev);
+
+ /* initialize digital out channels */
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+ das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return 0;
+};
+
+static struct comedi_driver driver_das800 = {
+ .driver_name = "das800",
+ .module = THIS_MODULE,
+ .attach = das800_attach,
+ .detach = comedi_legacy_detach,
+ .num_names = ARRAY_SIZE(das800_boards),
+ .board_name = &das800_boards[0].name,
+ .offset = sizeof(struct das800_board),
+};
+module_comedi_driver(driver_das800);
+
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 9e2124179a0..6c85dd2d549 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -695,25 +695,13 @@ static int dmm32at_attach(struct comedi_device *dev,
int ret;
struct comedi_subdevice *s;
unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
- unsigned long iobase;
unsigned int irq;
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
irq = it->options[1];
- printk(KERN_INFO "comedi%d: dmm32at: attaching\n", dev->minor);
- printk(KERN_DEBUG "dmm32at: probing at address 0x%04lx, irq %u\n",
- iobase, irq);
-
- /* register address space */
- if (!request_region(iobase, DMM32AT_MEMSIZE, dev->board_name)) {
- printk(KERN_ERR "comedi%d: dmm32at: I/O port conflict\n",
- dev->minor);
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], DMM32AT_MEMSIZE);
+ if (ret)
+ return ret;
/* the following just makes sure the board is there and gets
it to a known state */
@@ -832,19 +820,11 @@ static int dmm32at_attach(struct comedi_device *dev,
}
-static void dmm32at_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, DMM32AT_MEMSIZE);
-}
-
static struct comedi_driver dmm32at_driver = {
.driver_name = "dmm32at",
.module = THIS_MODULE,
.attach = dmm32at_attach,
- .detach = dmm32at_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(dmm32at_driver);
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index f6942aaf0ec..8f5006d70da 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -225,8 +225,6 @@ static const struct dt2801_board boardtypes[] = {
.dabits = 12},
};
-#define boardtype (*(const struct dt2801_board *)dev->board_ptr)
-
struct dt2801_private {
const struct comedi_lrange *dac_range_types[2];
@@ -592,19 +590,16 @@ static int dt2801_dio_insn_config(struct comedi_device *dev,
*/
static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ const struct dt2801_board *board = comedi_board(dev);
struct dt2801_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
int board_code, type;
int ret = 0;
int n_ai_chans;
- iobase = it->options[0];
- if (!request_region(iobase, DT2801_IOSIZE, "dt2801")) {
- comedi_error(dev, "I/O port conflict");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], DT2801_IOSIZE);
+ if (ret)
+ return ret;
/* do some checking */
@@ -624,10 +619,9 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
havetype:
dev->board_ptr = boardtypes + type;
- printk("dt2801: %s at port 0x%lx", boardtype.name, iobase);
+ board = comedi_board(dev);
n_ai_chans = probe_number_of_ai_chans(dev);
- printk(" (ai channels = %d)\n", n_ai_chans);
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@@ -638,7 +632,7 @@ havetype:
return -ENOMEM;
dev->private = devpriv;
- dev->board_name = boardtype.name;
+ dev->board_name = board->name;
s = &dev->subdevices[0];
/* ai subdevice */
@@ -648,12 +642,12 @@ havetype:
s->n_chan = n_ai_chans;
#else
if (it->options[2])
- s->n_chan = boardtype.ad_chan;
+ s->n_chan = board->ad_chan;
else
- s->n_chan = boardtype.ad_chan / 2;
+ s->n_chan = board->ad_chan / 2;
#endif
- s->maxdata = (1 << boardtype.adbits) - 1;
- s->range_table = ai_range_lkup(boardtype.adrangetype, it->options[3]);
+ s->maxdata = (1 << board->adbits) - 1;
+ s->range_table = ai_range_lkup(board->adrangetype, it->options[3]);
s->insn_read = dt2801_ai_insn_read;
s = &dev->subdevices[1];
@@ -661,7 +655,7 @@ havetype:
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITABLE;
s->n_chan = 2;
- s->maxdata = (1 << boardtype.dabits) - 1;
+ s->maxdata = (1 << board->dabits) - 1;
s->range_table_list = devpriv->dac_range_types;
devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]);
devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]);
@@ -693,17 +687,11 @@ out:
return ret;
}
-static void dt2801_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, DT2801_IOSIZE);
-}
-
static struct comedi_driver dt2801_driver = {
.driver_name = "dt2801",
.module = THIS_MODULE,
.attach = dt2801_attach,
- .detach = dt2801_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(dt2801_driver);
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
index f90ecf494aa..8757b54ad4a 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -50,8 +50,6 @@ Configuration options:
#include <linux/ioport.h>
-static const char *driver_name = "dt2811";
-
static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = {
4, {
RANGE(0, 5),
@@ -401,19 +399,10 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct dt2811_private *devpriv;
int ret;
struct comedi_subdevice *s;
- unsigned long iobase;
-
- iobase = it->options[0];
-
- printk(KERN_INFO "comedi%d: dt2811:base=0x%04lx\n", dev->minor, iobase);
-
- if (!request_region(iobase, DT2811_SIZE, driver_name)) {
- printk(KERN_ERR "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0], DT2811_SIZE);
+ if (ret)
+ return ret;
#if 0
outb(0, dev->iobase + DT2811_ADCSR);
@@ -449,7 +438,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
i = inb(dev->iobase + DT2811_ADDATHI);
printk(KERN_INFO "(irq = %d)\n", irq);
ret = request_irq(irq, dt2811_interrupt, 0,
- driver_name, dev);
+ dev->board_name, dev);
if (ret < 0)
return -EIO;
dev->irq = irq;
@@ -567,14 +556,6 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void dt2811_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, DT2811_SIZE);
-}
-
static const struct dt2811_board boardtypes[] = {
{
.name = "dt2811-pgh",
@@ -593,7 +574,7 @@ static struct comedi_driver dt2811_driver = {
.driver_name = "dt2811",
.module = THIS_MODULE,
.attach = dt2811_attach,
- .detach = dt2811_detach,
+ .detach = comedi_legacy_detach,
.board_name = &boardtypes[0].name,
.num_names = ARRAY_SIZE(boardtypes),
.offset = sizeof(struct dt2811_board),
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index e520dbaaa19..7c95b3b6813 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -246,16 +246,10 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int i, irq;
int ret;
struct comedi_subdevice *s;
- unsigned long iobase;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: dt2814: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, DT2814_SIZE, "dt2814")) {
- printk(KERN_ERR "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
- dev->board_name = "dt2814";
+ ret = comedi_request_region(dev, it->options[0], DT2814_SIZE);
+ if (ret)
+ return ret;
outb(0, dev->iobase + DT2814_CSR);
udelay(100);
@@ -329,19 +323,11 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void dt2814_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, DT2814_SIZE);
-}
-
static struct comedi_driver dt2814_driver = {
.driver_name = "dt2814",
.module = THIS_MODULE,
.attach = dt2814_attach,
- .detach = dt2814_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(dt2814_driver);
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index 1e0cfe4972a..b24e87681fe 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -61,12 +61,6 @@ Configuration options:
#include <linux/ioport.h>
#include <linux/delay.h>
-static const struct comedi_lrange
- range_dt2815_ao_32_current = {1, {RANGE_mA(0, 32)} };
-
-static const struct comedi_lrange
- range_dt2815_ao_20_current = {1, {RANGE_mA(4, 20)} };
-
#define DT2815_SIZE 2
#define DT2815_DATA 0
@@ -166,18 +160,11 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int i;
const struct comedi_lrange *current_range_type, *voltage_range_type;
- unsigned long iobase;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
- printk(KERN_WARNING "I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
- dev->board_name = "dt2815";
+ ret = comedi_request_region(dev, it->options[0], DT2815_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
@@ -199,7 +186,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->range_table_list = devpriv->range_type_list;
current_range_type = (it->options[3])
- ? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
+ ? &range_4_20mA : &range_0_32mA;
voltage_range_type = (it->options[2])
? &range_bipolar5 : &range_unipolar5;
for (i = 0; i < 8; i++) {
@@ -233,17 +220,11 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void dt2815_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, DT2815_SIZE);
-}
-
static struct comedi_driver dt2815_driver = {
.driver_name = "dt2815",
.module = THIS_MODULE,
.attach = dt2815_attach,
- .detach = dt2815_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(dt2815_driver);
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
index 502e42e0753..b5c8e8213fa 100644
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -126,16 +126,10 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
struct comedi_subdevice *s;
- unsigned long iobase;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: dt2817: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, DT2817_SIZE, "dt2817")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
- dev->board_name = "dt2817";
+ ret = comedi_request_region(dev, it->options[0], DT2817_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
@@ -154,22 +148,14 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->state = 0;
outb(0, dev->iobase + DT2817_CR);
- printk(KERN_INFO "\n");
-
return 0;
}
-static void dt2817_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, DT2817_SIZE);
-}
-
static struct comedi_driver dt2817_driver = {
.driver_name = "dt2817",
.module = THIS_MODULE,
.attach = dt2817_attach,
- .detach = dt2817_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(dt2817_driver);
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 122d980a95a..90f2de9bc40 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -248,8 +248,6 @@ struct dt282x_private {
int dma_dir;
};
-#define boardtype (*(const struct dt282x_board *)dev->board_ptr)
-
/*
* Some useless abstractions
*/
@@ -289,14 +287,15 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
static void dt282x_munge(struct comedi_device *dev, short *buf,
unsigned int nbytes)
{
+ const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
unsigned int i;
- unsigned short mask = (1 << boardtype.adbits) - 1;
- unsigned short sign = 1 << (boardtype.adbits - 1);
+ unsigned short mask = (1 << board->adbits) - 1;
+ unsigned short sign = 1 << (board->adbits - 1);
int n;
if (devpriv->ad_2scomp)
- sign = 1 << (boardtype.adbits - 1);
+ sign = 1 << (board->adbits - 1);
else
sign = 0;
@@ -501,10 +500,10 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
short data;
data = (short)inw(dev->iobase + DT2821_ADDAT);
- data &= (1 << boardtype.adbits) - 1;
+ data &= (1 << board->adbits) - 1;
if (devpriv->ad_2scomp)
- data ^= 1 << (boardtype.adbits - 1);
+ data ^= 1 << (board->adbits - 1);
ret = comedi_buf_put(s->async, data);
if (ret == 0)
@@ -554,6 +553,7 @@ static int dt282x_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
int i;
@@ -574,9 +574,9 @@ static int dt282x_ai_insn_read(struct comedi_device *dev,
data[i] =
inw(dev->iobase +
- DT2821_ADDAT) & ((1 << boardtype.adbits) - 1);
+ DT2821_ADDAT) & ((1 << board->adbits) - 1);
if (devpriv->ad_2scomp)
- data[i] ^= (1 << (boardtype.adbits - 1));
+ data[i] ^= (1 << (board->adbits - 1));
}
return i;
@@ -795,13 +795,14 @@ static int dt282x_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
short d;
unsigned int chan;
chan = CR_CHAN(insn->chanspec);
d = data[0];
- d &= (1 << boardtype.dabits) - 1;
+ d &= (1 << board->dabits) - 1;
devpriv->ao[chan] = d;
devpriv->dacsr |= DT2821_SSEL;
@@ -810,11 +811,11 @@ static int dt282x_ao_insn_write(struct comedi_device *dev,
/* select channel */
devpriv->dacsr |= DT2821_YSEL;
if (devpriv->da0_2scomp)
- d ^= (1 << (boardtype.dabits - 1));
+ d ^= (1 << (board->dabits - 1));
} else {
devpriv->dacsr &= ~DT2821_YSEL;
if (devpriv->da1_2scomp)
- d ^= (1 << (boardtype.dabits - 1));
+ d ^= (1 << (board->dabits - 1));
}
outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
@@ -1122,20 +1123,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int i, irq;
int ret;
struct comedi_subdevice *s;
- unsigned long iobase;
-
- dev->board_name = board->name;
- iobase = it->options[opt_iobase];
- if (!iobase)
- iobase = 0x240;
-
- printk(KERN_INFO "comedi%d: dt282x: 0x%04lx", dev->minor, iobase);
- if (!request_region(iobase, DT2821_SIZE, "dt282x")) {
- printk(KERN_INFO " I/O port conflict\n");
- return -EBUSY;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], DT2821_SIZE);
+ if (ret)
+ return ret;
outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
i = inw(dev->iobase + DT2821_ADCSR);
@@ -1185,7 +1176,8 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
#endif
if (irq > 0) {
printk(KERN_INFO " ( irq = %d )", irq);
- ret = request_irq(irq, dt282x_interrupt, 0, "dt282x", dev);
+ ret = request_irq(irq, dt282x_interrupt, 0,
+ dev->board_name, dev);
if (ret < 0) {
printk(KERN_ERR " failed to get irq\n");
return -EIO;
@@ -1223,20 +1215,20 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->subdev_flags = SDF_READABLE | SDF_CMD_READ |
((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
s->n_chan =
- (it->options[opt_diff]) ? boardtype.adchan_di : boardtype.adchan_se;
+ (it->options[opt_diff]) ? board->adchan_di : board->adchan_se;
s->insn_read = dt282x_ai_insn_read;
s->do_cmdtest = dt282x_ai_cmdtest;
s->do_cmd = dt282x_ai_cmd;
s->cancel = dt282x_ai_cancel;
- s->maxdata = (1 << boardtype.adbits) - 1;
+ s->maxdata = (1 << board->adbits) - 1;
s->len_chanlist = 16;
s->range_table =
- opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
+ opt_ai_range_lkup(board->ispgl, it->options[opt_ai_range]);
devpriv->ad_2scomp = it->options[opt_ai_twos];
s = &dev->subdevices[1];
- s->n_chan = boardtype.dachan;
+ s->n_chan = board->dachan;
if (s->n_chan) {
/* ao subsystem */
s->type = COMEDI_SUBD_AO;
@@ -1247,7 +1239,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->do_cmdtest = dt282x_ao_cmdtest;
s->do_cmd = dt282x_ao_cmd;
s->cancel = dt282x_ao_cancel;
- s->maxdata = (1 << boardtype.dabits) - 1;
+ s->maxdata = (1 << board->dabits) - 1;
s->len_chanlist = 2;
s->range_table_list = devpriv->darangelist;
devpriv->darangelist[0] =
@@ -1279,10 +1271,6 @@ static void dt282x_detach(struct comedi_device *dev)
{
struct dt282x_private *devpriv = dev->private;
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, DT2821_SIZE);
if (dev->private) {
if (devpriv->dma[0].chan)
free_dma(devpriv->dma[0].chan);
@@ -1293,6 +1281,7 @@ static void dt282x_detach(struct comedi_device *dev)
if (devpriv->dma[1].buf)
free_page((unsigned long)devpriv->dma[1].buf);
}
+ comedi_legacy_detach(dev);
}
static const struct dt282x_board boardtypes[] = {
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 3ce499fa5db..7e03929c9a1 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -63,17 +63,6 @@ AO commands are not supported.
#include "comedi_fc.h"
-/*
- * PCI device id's supported by this driver
- */
-#define PCI_DEVICE_ID_DT3001 0x0022
-#define PCI_DEVICE_ID_DT3002 0x0023
-#define PCI_DEVICE_ID_DT3003 0x0024
-#define PCI_DEVICE_ID_DT3004 0x0025
-#define PCI_DEVICE_ID_DT3005 0x0026
-#define PCI_DEVICE_ID_DT3001_PGL 0x0027
-#define PCI_DEVICE_ID_DT3003_PGL 0x0028
-
static const struct comedi_lrange range_dt3000_ai = {
4, {
BIP_RANGE(10),
@@ -92,9 +81,18 @@ static const struct comedi_lrange range_dt3000_ai_pgl = {
}
};
+enum dt3k_boardid {
+ BOARD_DT3001,
+ BOARD_DT3001_PGL,
+ BOARD_DT3002,
+ BOARD_DT3003,
+ BOARD_DT3003_PGL,
+ BOARD_DT3004,
+ BOARD_DT3005,
+};
+
struct dt3k_boardtype {
const char *name;
- unsigned int device_id;
int adchan;
int adbits;
int ai_speed;
@@ -104,61 +102,60 @@ struct dt3k_boardtype {
};
static const struct dt3k_boardtype dt3k_boardtypes[] = {
- {
+ [BOARD_DT3001] = {
.name = "dt3001",
- .device_id = PCI_DEVICE_ID_DT3001,
.adchan = 16,
.adbits = 12,
.adrange = &range_dt3000_ai,
.ai_speed = 3000,
.dachan = 2,
.dabits = 12,
- }, {
+ },
+ [BOARD_DT3001_PGL] = {
.name = "dt3001-pgl",
- .device_id = PCI_DEVICE_ID_DT3001_PGL,
.adchan = 16,
.adbits = 12,
.adrange = &range_dt3000_ai_pgl,
.ai_speed = 3000,
.dachan = 2,
.dabits = 12,
- }, {
+ },
+ [BOARD_DT3002] = {
.name = "dt3002",
- .device_id = PCI_DEVICE_ID_DT3002,
.adchan = 32,
.adbits = 12,
.adrange = &range_dt3000_ai,
.ai_speed = 3000,
- }, {
+ },
+ [BOARD_DT3003] = {
.name = "dt3003",
- .device_id = PCI_DEVICE_ID_DT3003,
.adchan = 64,
.adbits = 12,
.adrange = &range_dt3000_ai,
.ai_speed = 3000,
.dachan = 2,
.dabits = 12,
- }, {
+ },
+ [BOARD_DT3003_PGL] = {
.name = "dt3003-pgl",
- .device_id = PCI_DEVICE_ID_DT3003_PGL,
.adchan = 64,
.adbits = 12,
.adrange = &range_dt3000_ai_pgl,
.ai_speed = 3000,
.dachan = 2,
.dabits = 12,
- }, {
+ },
+ [BOARD_DT3004] = {
.name = "dt3004",
- .device_id = PCI_DEVICE_ID_DT3004,
.adchan = 16,
.adbits = 16,
.adrange = &range_dt3000_ai,
.ai_speed = 10000,
.dachan = 2,
.dabits = 12,
- }, {
+ },
+ [BOARD_DT3005] = {
.name = "dt3005", /* a.k.a. 3004-200 */
- .device_id = PCI_DEVICE_ID_DT3005,
.adchan = 16,
.adbits = 16,
.adrange = &range_dt3000_ai,
@@ -168,8 +165,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
},
};
-#define DT3000_SIZE (4*0x1000)
-
/* dual-ported RAM location definitions */
#define DPR_DAC_buffer (4*0x000)
@@ -716,31 +711,17 @@ static int dt3k_mem_insn_read(struct comedi_device *dev,
return i;
}
-static const void *dt3000_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct dt3k_boardtype *this_board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) {
- this_board = &dt3k_boardtypes[i];
- if (this_board->device_id == pcidev->device)
- return this_board;
- }
- return NULL;
-}
-
static int dt3000_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct dt3k_boardtype *this_board;
+ const struct dt3k_boardtype *this_board = NULL;
struct dt3k_private *devpriv;
struct comedi_subdevice *s;
- resource_size_t pci_base;
int ret = 0;
- this_board = dt3000_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(dt3k_boardtypes))
+ this_board = &dt3k_boardtypes[context];
if (!this_board)
return -ENODEV;
dev->board_ptr = this_board;
@@ -751,13 +732,11 @@ static int dt3000_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret < 0)
return ret;
- dev->iobase = 1; /* the "detach" needs this */
- pci_base = pci_resource_start(pcidev, 0);
- devpriv->io_addr = ioremap(pci_base, DT3000_SIZE);
+ devpriv->io_addr = pci_ioremap_bar(pcidev, 0);
if (!devpriv->io_addr)
return -ENOMEM;
@@ -830,7 +809,6 @@ static int dt3000_auto_attach(struct comedi_device *dev,
static void dt3000_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct dt3k_private *devpriv = dev->private;
if (dev->irq)
@@ -839,10 +817,7 @@ static void dt3000_detach(struct comedi_device *dev)
if (devpriv->io_addr)
iounmap(devpriv->io_addr);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver dt3000_driver = {
@@ -853,19 +828,19 @@ static struct comedi_driver dt3000_driver = {
};
static int dt3000_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &dt3000_driver);
+ return comedi_pci_auto_config(dev, &dt3000_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001_PGL) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3002) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003_PGL) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3004) },
- { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3005) },
+ { PCI_VDEVICE(DT, 0x0022), BOARD_DT3001 },
+ { PCI_VDEVICE(DT, 0x0023), BOARD_DT3002 },
+ { PCI_VDEVICE(DT, 0x0024), BOARD_DT3003 },
+ { PCI_VDEVICE(DT, 0x0025), BOARD_DT3004 },
+ { PCI_VDEVICE(DT, 0x0026), BOARD_DT3005 },
+ { PCI_VDEVICE(DT, 0x0027), BOARD_DT3001_PGL },
+ { PCI_VDEVICE(DT, 0x0028), BOARD_DT3003_PGL },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, dt3000_pci_table);
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 192cf088f83..81eb5ed6ec9 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -303,26 +303,6 @@ struct slot_dt9812 {
struct comedi_dt9812 *comedi;
};
-static const struct comedi_lrange dt9812_10_ain_range = { 1, {
- BIP_RANGE(10),
- }
-};
-
-static const struct comedi_lrange dt9812_2pt5_ain_range = { 1, {
- UNI_RANGE(2.5),
- }
-};
-
-static const struct comedi_lrange dt9812_10_aout_range = { 1, {
- BIP_RANGE(10),
- }
-};
-
-static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
- UNI_RANGE(2.5),
- }
-};
-
static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS];
static inline struct usb_dt9812 *to_dt9812_dev(struct kref *d)
@@ -912,12 +892,12 @@ static int dt9812_comedi_open(struct comedi_device *dev)
switch (devpriv->slot->usb->device) {
case 0:{
s->maxdata = 4095;
- s->range_table = &dt9812_10_ain_range;
+ s->range_table = &range_bipolar10;
}
break;
case 1:{
s->maxdata = 4095;
- s->range_table = &dt9812_2pt5_ain_range;
+ s->range_table = &range_unipolar2_5;
}
break;
}
@@ -927,12 +907,12 @@ static int dt9812_comedi_open(struct comedi_device *dev)
switch (devpriv->slot->usb->device) {
case 0:{
s->maxdata = 4095;
- s->range_table = &dt9812_10_aout_range;
+ s->range_table = &range_bipolar10;
}
break;
case 1:{
s->maxdata = 4095;
- s->range_table = &dt9812_2pt5_aout_range;
+ s->range_table = &range_unipolar2_5;
}
break;
}
@@ -947,12 +927,13 @@ static int dt9812_di_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u8 bits = 0;
dt9812_digital_in(devpriv->slot, &bits);
for (n = 0; n < insn->n; n++)
- data[n] = ((1 << insn->chanspec) & bits) != 0;
+ data[n] = ((1 << channel) & bits) != 0;
return n;
}
@@ -961,12 +942,13 @@ static int dt9812_do_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u8 bits = 0;
dt9812_digital_out_shadow(devpriv->slot, &bits);
for (n = 0; n < insn->n; n++) {
- u8 mask = 1 << insn->chanspec;
+ u8 mask = 1 << channel;
bits &= ~mask;
if (data[n])
@@ -981,13 +963,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
for (n = 0; n < insn->n; n++) {
u16 value = 0;
- dt9812_analog_in(devpriv->slot, insn->chanspec, &value,
- DT9812_GAIN_1);
+ dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1);
data[n] = value;
}
return n;
@@ -998,12 +980,13 @@ static int dt9812_ao_rinsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
u16 value;
for (n = 0; n < insn->n; n++) {
value = 0;
- dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value);
+ dt9812_analog_out_shadow(devpriv->slot, channel, &value);
data[n] = value;
}
return n;
@@ -1014,10 +997,11 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct comedi_dt9812 *devpriv = dev->private;
+ unsigned int channel = CR_CHAN(insn->chanspec);
int n;
for (n = 0; n < insn->n; n++)
- dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]);
+ dt9812_analog_out(devpriv->slot, channel, data[n]);
return n;
}
@@ -1028,8 +1012,6 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- dev->board_name = "dt9812";
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c
index decc17f1867..93ec8e492cc 100644
--- a/drivers/staging/comedi/drivers/dyna_pci10xx.c
+++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c
@@ -187,14 +187,12 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
@@ -254,15 +252,11 @@ static int dyna_pci10xx_auto_attach(struct comedi_device *dev,
static void dyna_pci10xx_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct dyna_pci10xx_private *devpriv = dev->private;
if (devpriv)
mutex_destroy(&devpriv->mutex);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver dyna_pci10xx_driver = {
@@ -273,9 +267,10 @@ static struct comedi_driver dyna_pci10xx_driver = {
};
static int dyna_pci10xx_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &dyna_pci10xx_driver);
+ return comedi_pci_auto_config(dev, &dyna_pci10xx_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
index 019c96eda6f..ff6f0bd7c86 100644
--- a/drivers/staging/comedi/drivers/fl512.c
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -111,31 +111,18 @@ static int fl512_ao_insn_readback(struct comedi_device *dev,
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct fl512_private *devpriv;
- unsigned long iobase;
- int ret;
-
- /* pointer to the subdevice: Analog in, Analog out,
- (not made ->and Digital IO) */
struct comedi_subdevice *s;
+ int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi:%d fl512: 0x%04lx", dev->minor, iobase);
- if (!request_region(iobase, FL512_SIZE, "fl512")) {
- printk(KERN_WARNING " I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
- dev->board_name = "fl512";
+ ret = comedi_request_region(dev, it->options[0], FL512_SIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
-#if DEBUG
- printk(KERN_DEBUG "malloc ok\n");
-#endif
-
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
return ret;
@@ -157,7 +144,6 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->range_table = &range_fl512;
/* function to call when read AD */
s->insn_read = fl512_ai_insn;
- printk(KERN_INFO "comedi: fl512: subdevice 0 initialized\n");
/* Analog output */
s = &dev->subdevices[1];
@@ -175,22 +161,15 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->insn_write = fl512_ao_insn;
/* function to call when reading DA */
s->insn_read = fl512_ao_insn_readback;
- printk(KERN_INFO "comedi: fl512: subdevice 1 initialized\n");
return 1;
}
-static void fl512_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, FL512_SIZE);
-}
-
static struct comedi_driver fl512_driver = {
.driver_name = "fl512",
.module = THIS_MODULE,
.attach = fl512_attach,
- .detach = fl512_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(fl512_driver);
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index b60c9756267..0c061df0978 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -78,12 +78,6 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
#define NUM_DMA_BUFFERS 4
#define NUM_DMA_DESCRIPTORS 256
-/* indices of base address regions */
-enum base_address_regions {
- PLX9080_BADDRINDEX = 0,
- HPDI_BADDRINDEX = 2,
-};
-
enum hpdi_registers {
FIRMWARE_REV_REG = 0x0,
BOARD_CONTROL_REG = 0x4,
@@ -499,20 +493,13 @@ static int hpdi_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = devpriv;
- if (comedi_pci_enable(pcidev, dev->board_name)) {
- dev_warn(dev->class_dev,
- "failed enable PCI device and request regions\n");
- return -EIO;
- }
- dev->iobase = 1; /* the "detach" needs this */
+ retval = comedi_pci_enable(dev);
+ if (retval)
+ return retval;
pci_set_master(pcidev);
- devpriv->plx9080_iobase =
- ioremap(pci_resource_start(pcidev, PLX9080_BADDRINDEX),
- pci_resource_len(pcidev, PLX9080_BADDRINDEX));
- devpriv->hpdi_iobase =
- ioremap(pci_resource_start(pcidev, HPDI_BADDRINDEX),
- pci_resource_len(pcidev, HPDI_BADDRINDEX));
+ devpriv->plx9080_iobase = pci_ioremap_bar(pcidev, 0);
+ devpriv->hpdi_iobase = pci_ioremap_bar(pcidev, 2);
if (!devpriv->plx9080_iobase || !devpriv->hpdi_iobase) {
dev_warn(dev->class_dev, "failed to remap io memory\n");
return -ENOMEM;
@@ -596,9 +583,8 @@ static void hpdi_detach(struct comedi_device *dev)
NUM_DMA_DESCRIPTORS,
devpriv->dma_desc,
devpriv->dma_desc_phys_addr);
- if (dev->iobase)
- comedi_pci_disable(pcidev);
}
+ comedi_pci_disable(dev);
}
static int dio_config_block_size(struct comedi_device *dev, unsigned int *data)
@@ -943,9 +929,9 @@ static struct comedi_driver gsc_hpdi_driver = {
};
static int gsc_hpdi_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &gsc_hpdi_driver);
+ return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(gsc_hpdi_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 1e08f9141fa..08ab9d6e719 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -68,8 +68,6 @@ Configuration options: not applicable, uses PCI auto config
#define ICP_MULTI_CNTR2 0x14 /* R/W: Counter 2 */
#define ICP_MULTI_CNTR3 0x16 /* R/W: Counter 3 */
-#define ICP_MULTI_SIZE 0x20 /* 32 bytes */
-
/* Define bits from ADC command/status register */
#define ADC_ST 0x0001 /* Start ADC */
#define ADC_BSY 0x0001 /* ADC busy */
@@ -120,7 +118,7 @@ struct icp_multi_private {
unsigned int DacCmdStatus; /* DAC Command/Status register */
unsigned int IntEnable; /* Interrupt Enable register */
unsigned int IntStatus; /* Interrupt Status register */
- unsigned int act_chanlist[32]; /* list of scaned channel */
+ unsigned int act_chanlist[32]; /* list of scanned channel */
unsigned char act_chanlist_len; /* len of scanlist */
unsigned char act_chanlist_pos; /* actual position in MUX list */
unsigned int *ai_chanlist; /* actaul chanlist */
@@ -500,23 +498,18 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct icp_multi_private *devpriv;
struct comedi_subdevice *s;
- resource_size_t iobase;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
- iobase = pci_resource_start(pcidev, 2);
- dev->iobase = iobase;
- devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE);
+ devpriv->io_addr = pci_ioremap_bar(pcidev, 2);
if (!devpriv->io_addr)
return -ENOMEM;
@@ -594,7 +587,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
static void icp_multi_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct icp_multi_private *devpriv = dev->private;
if (devpriv)
@@ -604,10 +596,7 @@ static void icp_multi_detach(struct comedi_device *dev)
free_irq(dev->irq, dev);
if (devpriv && devpriv->io_addr)
iounmap(devpriv->io_addr);
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver icp_multi_driver = {
@@ -618,9 +607,9 @@ static struct comedi_driver icp_multi_driver = {
};
static int icp_multi_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &icp_multi_driver);
+ return comedi_pci_auto_config(dev, &icp_multi_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(icp_multi_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 93584e2be35..ee7537daf47 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -77,9 +77,6 @@ options for PCI-20341M:
3 200
*/
-/* XXX needs to use ioremap() for compatibility with 2.4 kernels. Should also
- * check_mem_region() etc. - fmhess */
-
#include "../comedidev.h"
#define PCI20000_ID 0x1d
@@ -212,7 +209,6 @@ static int pci20xxx_attach(struct comedi_device *dev,
dev->private = devpriv;
devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0];
- dev->board_name = "pci20kc";
/* Check PCI-20001 C-2A Carrier Board ID */
if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 17ba75e0ab8..90b303ab230 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -700,16 +700,12 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
return -EINVAL;
break;
}
- dev->board_name = "jr3_pci";
- result = comedi_pci_enable(pcidev, "jr3_pci");
- if (result < 0)
+ result = comedi_pci_enable(dev);
+ if (result)
return result;
- dev->iobase = 1; /* the "detach" needs this */
- devpriv->iobase = ioremap(pci_resource_start(pcidev, 0),
- offsetof(struct jr3_t,
- channel[devpriv->n_channels]));
+ devpriv->iobase = pci_ioremap_bar(pcidev, 0);
if (!devpriv->iobase)
return -ENOMEM;
@@ -816,7 +812,6 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
static void jr3_pci_detach(struct comedi_device *dev)
{
int i;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct jr3_pci_dev_private *devpriv = dev->private;
if (devpriv) {
@@ -828,9 +823,8 @@ static void jr3_pci_detach(struct comedi_device *dev)
}
if (devpriv->iobase)
iounmap(devpriv->iobase);
- if (dev->iobase)
- comedi_pci_disable(pcidev);
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver jr3_pci_driver = {
@@ -841,9 +835,9 @@ static struct comedi_driver jr3_pci_driver = {
};
static int jr3_pci_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &jr3_pci_driver);
+ return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index 8c09c026508..e0e64752e31 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -96,9 +96,7 @@ static int cnt_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
dev->iobase = pci_resource_start(pcidev, 0);
@@ -131,27 +129,18 @@ static int cnt_auto_attach(struct comedi_device *dev,
return 0;
}
-static void cnt_detach(struct comedi_device *dev)
-{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
-}
-
static struct comedi_driver ke_counter_driver = {
.driver_name = "ke_counter",
.module = THIS_MODULE,
.auto_attach = cnt_auto_attach,
- .detach = cnt_detach,
+ .detach = comedi_pci_disable,
};
static int ke_counter_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &ke_counter_driver);
+ return comedi_pci_auto_config(dev, &ke_counter_driver,
+ id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(ke_counter_pci_table) = {
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index b766bb93efd..641e693d5d0 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -55,26 +55,13 @@ broken.
#include "comedi_fc.h"
#include "8253.h"
+#include "plx9052.h"
#if 0
/* file removed due to GPL incompatibility */
#include "me4000_fw.h"
#endif
-#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650
-#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660
-#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661
-#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662
-#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663
-#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670
-#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671
-#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672
-#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673
-#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680
-#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681
-#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682
-#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683
-
/*
* ME4000 Register map and bit defines
*/
@@ -183,28 +170,6 @@ broken.
#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
#define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
-/*
- * PLX Register map and bit defines
- */
-#define PLX_INTCSR 0x4c
-#define PLX_INTCSR_LOCAL_INT1_EN (1 << 0)
-#define PLX_INTCSR_LOCAL_INT1_POL (1 << 1)
-#define PLX_INTCSR_LOCAL_INT1_STATE (1 << 2)
-#define PLX_INTCSR_LOCAL_INT2_EN (1 << 3)
-#define PLX_INTCSR_LOCAL_INT2_POL (1 << 4)
-#define PLX_INTCSR_LOCAL_INT2_STATE (1 << 5)
-#define PLX_INTCSR_PCI_INT_EN (1 << 6)
-#define PLX_INTCSR_SOFT_INT (1 << 7)
-#define PLX_ICR 0x50
-#define PLX_ICR_BIT_EEPROM_CLOCK_SET (1 << 24)
-#define PLX_ICR_BIT_EEPROM_CHIP_SELECT (1 << 25)
-#define PLX_ICR_BIT_EEPROM_WRITE (1 << 26)
-#define PLX_ICR_BIT_EEPROM_READ (1 << 27)
-#define PLX_ICR_BIT_EEPROM_VALID (1 << 28)
-#define PLX_ICR_MASK_EEPROM (0x1f << 24)
-
-#define EEPROM_DELAY 1
-
#define ME4000_AI_FIFO_COUNT 2048
#define ME4000_AI_MIN_TICKS 66
@@ -220,9 +185,24 @@ struct me4000_info {
unsigned int ao_readback[4];
};
+enum me4000_boardid {
+ BOARD_ME4650,
+ BOARD_ME4660,
+ BOARD_ME4660I,
+ BOARD_ME4660S,
+ BOARD_ME4660IS,
+ BOARD_ME4670,
+ BOARD_ME4670I,
+ BOARD_ME4670S,
+ BOARD_ME4670IS,
+ BOARD_ME4680,
+ BOARD_ME4680I,
+ BOARD_ME4680S,
+ BOARD_ME4680IS,
+};
+
struct me4000_board {
const char *name;
- unsigned short device_id;
int ao_nchan;
int ao_fifo;
int ai_nchan;
@@ -234,62 +214,61 @@ struct me4000_board {
};
static const struct me4000_board me4000_boards[] = {
- {
+ [BOARD_ME4650] = {
.name = "ME-4650",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4650,
.ai_nchan = 16,
.dio_nchan = 32,
- }, {
+ },
+ [BOARD_ME4660] = {
.name = "ME-4660",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660,
.ai_nchan = 32,
.ai_diff_nchan = 16,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4660I] = {
.name = "ME-4660i",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660I,
.ai_nchan = 32,
.ai_diff_nchan = 16,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4660S] = {
.name = "ME-4660s",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660S,
.ai_nchan = 32,
.ai_diff_nchan = 16,
.ai_sh_nchan = 8,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4660IS] = {
.name = "ME-4660is",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4660IS,
.ai_nchan = 32,
.ai_diff_nchan = 16,
.ai_sh_nchan = 8,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4670] = {
.name = "ME-4670",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670,
.ao_nchan = 4,
.ai_nchan = 32,
.ai_diff_nchan = 16,
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4670I] = {
.name = "ME-4670i",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670I,
.ao_nchan = 4,
.ai_nchan = 32,
.ai_diff_nchan = 16,
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4670S] = {
.name = "ME-4670s",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670S,
.ao_nchan = 4,
.ai_nchan = 32,
.ai_diff_nchan = 16,
@@ -297,9 +276,9 @@ static const struct me4000_board me4000_boards[] = {
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4670IS] = {
.name = "ME-4670is",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4670IS,
.ao_nchan = 4,
.ai_nchan = 32,
.ai_diff_nchan = 16,
@@ -307,9 +286,9 @@ static const struct me4000_board me4000_boards[] = {
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4680] = {
.name = "ME-4680",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680,
.ao_nchan = 4,
.ao_fifo = 4,
.ai_nchan = 32,
@@ -317,9 +296,9 @@ static const struct me4000_board me4000_boards[] = {
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4680I] = {
.name = "ME-4680i",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680I,
.ao_nchan = 4,
.ao_fifo = 4,
.ai_nchan = 32,
@@ -327,9 +306,9 @@ static const struct me4000_board me4000_boards[] = {
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4680S] = {
.name = "ME-4680s",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680S,
.ao_nchan = 4,
.ao_fifo = 4,
.ai_nchan = 32,
@@ -338,9 +317,9 @@ static const struct me4000_board me4000_boards[] = {
.ex_trig_analog = 1,
.dio_nchan = 32,
.has_counter = 1,
- }, {
+ },
+ [BOARD_ME4680IS] = {
.name = "ME-4680is",
- .device_id = PCI_DEVICE_ID_MEILHAUS_ME4680IS,
.ao_nchan = 4,
.ao_fifo = 4,
.ai_nchan = 32,
@@ -376,6 +355,7 @@ static int xilinx_download(struct comedi_device *dev)
wait_queue_head_t queue;
int idx = 0;
int size = 0;
+ unsigned int intcsr;
if (!xilinx_iobase)
return -ENODEV;
@@ -386,27 +366,28 @@ static int xilinx_download(struct comedi_device *dev)
* Set PLX local interrupt 2 polarity to high.
* Interrupt is thrown by init pin of xilinx.
*/
- outl(0x10, info->plx_regbase + PLX_INTCSR);
+ outl(PLX9052_INTCSR_LI2POL, info->plx_regbase + PLX9052_INTCSR);
/* Set /CS and /WRITE of the Xilinx */
- value = inl(info->plx_regbase + PLX_ICR);
- value |= 0x100;
- outl(value, info->plx_regbase + PLX_ICR);
+ value = inl(info->plx_regbase + PLX9052_CNTRL);
+ value |= PLX9052_CNTRL_UIO2_DATA;
+ outl(value, info->plx_regbase + PLX9052_CNTRL);
/* Init Xilinx with CS1 */
inb(xilinx_iobase + 0xC8);
/* Wait until /INIT pin is set */
udelay(20);
- if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
+ intcsr = inl(info->plx_regbase + PLX9052_INTCSR);
+ if (!(intcsr & PLX9052_INTCSR_LI2STAT)) {
dev_err(dev->class_dev, "Can't init Xilinx\n");
return -EIO;
}
/* Reset /CS and /WRITE of the Xilinx */
- value = inl(info->plx_regbase + PLX_ICR);
- value &= ~0x100;
- outl(value, info->plx_regbase + PLX_ICR);
+ value = inl(info->plx_regbase + PLX9052_CNTRL);
+ value &= ~PLX9052_CNTRL_UIO2_DATA;
+ outl(value, info->plx_regbase + PLX9052_CNTRL);
if (FIRMWARE_NOT_AVAILABLE) {
dev_err(dev->class_dev,
"xilinx firmware unavailable due to licensing, aborting");
@@ -422,7 +403,7 @@ static int xilinx_download(struct comedi_device *dev)
udelay(10);
/* Check if BUSY flag is low */
- if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
+ if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO1_DATA) {
dev_err(dev->class_dev,
"Xilinx is still busy (idx = %d)\n",
idx);
@@ -432,7 +413,7 @@ static int xilinx_download(struct comedi_device *dev)
}
/* If done flag is high download was successful */
- if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
+ if (inl(info->plx_regbase + PLX9052_CNTRL) & PLX9052_CNTRL_UIO0_DATA) {
} else {
dev_err(dev->class_dev, "DONE flag is not set\n");
dev_err(dev->class_dev, "Download not successful\n");
@@ -440,9 +421,9 @@ static int xilinx_download(struct comedi_device *dev)
}
/* Set /CS and /WRITE */
- value = inl(info->plx_regbase + PLX_ICR);
- value |= 0x100;
- outl(value, info->plx_regbase + PLX_ICR);
+ value = inl(info->plx_regbase + PLX9052_CNTRL);
+ value |= PLX9052_CNTRL_UIO2_DATA;
+ outl(value, info->plx_regbase + PLX9052_CNTRL);
return 0;
}
@@ -454,11 +435,11 @@ static void me4000_reset(struct comedi_device *dev)
int chan;
/* Make a hardware reset */
- val = inl(info->plx_regbase + PLX_ICR);
- val |= 0x40000000;
- outl(val, info->plx_regbase + PLX_ICR);
- val &= ~0x40000000;
- outl(val , info->plx_regbase + PLX_ICR);
+ val = inl(info->plx_regbase + PLX9052_CNTRL);
+ val |= PLX9052_CNTRL_PCI_RESET;
+ outl(val, info->plx_regbase + PLX9052_CNTRL);
+ val &= ~PLX9052_CNTRL_PCI_RESET;
+ outl(val , info->plx_regbase + PLX9052_CNTRL);
/* 0x8000 to the DACs means an output voltage of 0V */
for (chan = 0; chan < 4; chan++)
@@ -474,7 +455,9 @@ static void me4000_reset(struct comedi_device *dev)
outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan));
/* Enable interrupts on the PLX */
- outl(0x43, info->plx_regbase + PLX_INTCSR);
+ outl(PLX9052_INTCSR_LI1ENAB |
+ PLX9052_INTCSR_LI1POL |
+ PLX9052_INTCSR_PCIENAB, info->plx_regbase + PLX9052_INTCSR);
/* Set the adustment register for AO demux */
outl(ME4000_AO_DEMUX_ADJUST_VALUE,
@@ -1550,30 +1533,17 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
return 1;
}
-static const void *me4000_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct me4000_board *thisboard;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) {
- thisboard = &me4000_boards[i];
- if (thisboard->device_id == pcidev->device)
- return thisboard;
- }
- return NULL;
-}
-
static int me4000_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct me4000_board *thisboard;
+ const struct me4000_board *thisboard = NULL;
struct me4000_info *info;
struct comedi_subdevice *s;
int result;
- thisboard = me4000_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(me4000_boards))
+ thisboard = &me4000_boards[context];
if (!thisboard)
return -ENODEV;
dev->board_ptr = thisboard;
@@ -1584,7 +1554,7 @@ static int me4000_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = info;
- result = comedi_pci_enable(pcidev, dev->board_name);
+ result = comedi_pci_enable(dev);
if (result)
return result;
@@ -1710,16 +1680,11 @@ static int me4000_auto_attach(struct comedi_device *dev,
static void me4000_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-
if (dev->irq)
free_irq(dev->irq, dev);
- if (pcidev) {
- if (dev->iobase) {
- me4000_reset(dev);
- comedi_pci_disable(pcidev);
- }
- }
+ if (dev->iobase)
+ me4000_reset(dev);
+ comedi_pci_disable(dev);
}
static struct comedi_driver me4000_driver = {
@@ -1730,26 +1695,26 @@ static struct comedi_driver me4000_driver = {
};
static int me4000_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &me4000_driver);
+ return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660S)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660IS)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S)},
- {PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS)},
- {0}
+ { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 },
+ { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 },
+ { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I },
+ { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S },
+ { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS },
+ { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 },
+ { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I },
+ { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S },
+ { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS },
+ { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 },
+ { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I },
+ { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S },
+ { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS },
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, me4000_pci_table);
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 06490ebc8cc..09f2a9feaf7 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -41,12 +41,10 @@
#include "../comedidev.h"
-#define ME2600_FIRMWARE "me2600_firmware.bin"
+#include "plx9052.h"
-#define ME2000_DEVICE_ID 0x2000
-#define ME2600_DEVICE_ID 0x2600
+#define ME2600_FIRMWARE "me2600_firmware.bin"
-#define PLX_INTCSR 0x4C /* PLX interrupt status register */
#define XILINX_DOWNLOAD_RESET 0x42 /* Xilinx registers */
#define ME_CONTROL_1 0x0000 /* - | W */
@@ -149,21 +147,26 @@ static const struct comedi_lrange me_ao_range = {
}
};
+enum me_boardid {
+ BOARD_ME2600,
+ BOARD_ME2000,
+};
+
struct me_board {
const char *name;
- int device_id;
+ int needs_firmware;
int has_ao;
};
static const struct me_board me_boards[] = {
- {
+ [BOARD_ME2600] = {
.name = "me-2600i",
- .device_id = ME2600_DEVICE_ID,
+ .needs_firmware = 1,
.has_ao = 1,
- }, {
+ },
+ [BOARD_ME2000] = {
.name = "me-2000i",
- .device_id = ME2000_DEVICE_ID,
- }
+ },
};
struct me_private_data {
@@ -396,7 +399,7 @@ static int me2600_xilinx_download(struct comedi_device *dev,
unsigned int i;
/* disable irq's on PLX */
- writel(0x00, dev_private->plx_regbase + PLX_INTCSR);
+ writel(0x00, dev_private->plx_regbase + PLX9052_INTCSR);
/* First, make a dummy read to reset xilinx */
value = readw(dev_private->me_regbase + XILINX_DOWNLOAD_RESET);
@@ -426,7 +429,7 @@ static int me2600_xilinx_download(struct comedi_device *dev,
/*
* Loop for writing firmware byte by byte to xilinx
- * Firmware data start at offfset 16
+ * Firmware data start at offset 16
*/
for (i = 0; i < file_length; i++)
writeb((data[16 + i] & 0xff),
@@ -437,10 +440,10 @@ static int me2600_xilinx_download(struct comedi_device *dev,
writeb(0x00, dev_private->me_regbase + 0x0);
/* Test if there was an error during download -> INTB was thrown */
- value = readl(dev_private->plx_regbase + PLX_INTCSR);
- if (value & 0x20) {
+ value = readl(dev_private->plx_regbase + PLX9052_INTCSR);
+ if (value & PLX9052_INTCSR_LI2STAT) {
/* Disable interrupt */
- writel(0x00, dev_private->plx_regbase + PLX_INTCSR);
+ writel(0x00, dev_private->plx_regbase + PLX9052_INTCSR);
dev_err(dev->class_dev, "Xilinx download failed\n");
return -EIO;
}
@@ -449,7 +452,10 @@ static int me2600_xilinx_download(struct comedi_device *dev,
sleep(1);
/* Enable PLX-Interrupts */
- writel(0x43, dev_private->plx_regbase + PLX_INTCSR);
+ writel(PLX9052_INTCSR_LI1ENAB |
+ PLX9052_INTCSR_LI1POL |
+ PLX9052_INTCSR_PCIENAB,
+ dev_private->plx_regbase + PLX9052_INTCSR);
return 0;
}
@@ -488,30 +494,17 @@ static int me_reset(struct comedi_device *dev)
return 0;
}
-static const void *me_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct me_board *board;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(me_boards); i++) {
- board = &me_boards[i];
- if (board->device_id == pcidev->device)
- return board;
- }
- return NULL;
-}
-
static int me_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct me_board *board;
+ const struct me_board *board = NULL;
struct me_private_data *dev_private;
struct comedi_subdevice *s;
int ret;
- board = me_find_boardinfo(dev, pcidev);
+ if (context < ARRAY_SIZE(me_boards))
+ board = &me_boards[context];
if (!board)
return -ENODEV;
dev->board_ptr = board;
@@ -522,23 +515,20 @@ static int me_auto_attach(struct comedi_device *dev,
return -ENOMEM;
dev->private = dev_private;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
- dev->iobase = 1; /* detach needs this */
- dev_private->plx_regbase = ioremap(pci_resource_start(pcidev, 0),
- pci_resource_len(pcidev, 0));
+ dev_private->plx_regbase = pci_ioremap_bar(pcidev, 0);
if (!dev_private->plx_regbase)
return -ENOMEM;
- dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2),
- pci_resource_len(pcidev, 2));
+ dev_private->me_regbase = pci_ioremap_bar(pcidev, 2);
if (!dev_private->me_regbase)
return -ENOMEM;
/* Download firmware and reset card */
- if (board->device_id == ME2600_DEVICE_ID) {
+ if (board->needs_firmware) {
ret = me2600_upload_firmware(dev);
if (ret < 0)
return ret;
@@ -591,7 +581,6 @@ static int me_auto_attach(struct comedi_device *dev,
static void me_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct me_private_data *dev_private = dev->private;
if (dev_private) {
@@ -602,10 +591,7 @@ static void me_detach(struct comedi_device *dev)
if (dev_private->plx_regbase)
iounmap(dev_private->plx_regbase);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver me_daq_driver = {
@@ -616,14 +602,14 @@ static struct comedi_driver me_daq_driver = {
};
static int me_daq_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &me_daq_driver);
+ return comedi_pci_auto_config(dev, &me_daq_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(me_daq_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) },
- { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) },
+ { PCI_VDEVICE(MEILHAUS, 0x2600), BOARD_ME2600 },
+ { PCI_VDEVICE(MEILHAUS, 0x2000), BOARD_ME2000 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, me_daq_pci_table);
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index be2c15f8461..523c6564ffc 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -58,10 +58,6 @@
#include "comedi_fc.h"
#include "mite.h"
-#define PCI_MITE_SIZE 4096
-#define PCI_DAQ_SIZE 4096
-#define PCI_DAQ_SIZE_660X 8192
-
#define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK)))
struct mite_struct *mite_alloc(struct pci_dev *pcidev)
@@ -81,7 +77,7 @@ struct mite_struct *mite_alloc(struct pci_dev *pcidev)
}
return mite;
}
-EXPORT_SYMBOL(mite_alloc);
+EXPORT_SYMBOL_GPL(mite_alloc);
static void dump_chip_signature(u32 csigr_bits)
{
@@ -104,40 +100,28 @@ static unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
{
unsigned long length;
- resource_size_t addr;
int i;
u32 csigr_bits;
unsigned unknown_dma_burst_bits;
- if (comedi_pci_enable(mite->pcidev, "mite")) {
- dev_err(&mite->pcidev->dev,
- "error enabling mite and requesting io regions\n");
- return -EIO;
- }
pci_set_master(mite->pcidev);
- addr = pci_resource_start(mite->pcidev, 0);
- mite->mite_phys_addr = addr;
- mite->mite_io_addr = ioremap(addr, PCI_MITE_SIZE);
+ mite->mite_io_addr = pci_ioremap_bar(mite->pcidev, 0);
if (!mite->mite_io_addr) {
dev_err(&mite->pcidev->dev,
"Failed to remap mite io memory address\n");
return -ENOMEM;
}
+ mite->mite_phys_addr = pci_resource_start(mite->pcidev, 0);
- addr = pci_resource_start(mite->pcidev, 1);
- mite->daq_phys_addr = addr;
- length = pci_resource_len(mite->pcidev, 1);
- /*
- * In case of a 660x board, DAQ size is 8k instead of 4k
- * (see as shown by lspci output)
- */
- mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
+ mite->daq_io_addr = pci_ioremap_bar(mite->pcidev, 1);
if (!mite->daq_io_addr) {
dev_err(&mite->pcidev->dev,
"Failed to remap daq io memory address\n");
return -ENOMEM;
}
+ mite->daq_phys_addr = pci_resource_start(mite->pcidev, 1);
+ length = pci_resource_len(mite->pcidev, 1);
if (use_iodwbsr_1) {
writel(0, mite->mite_io_addr + MITE_IODWBSR);
@@ -185,13 +169,13 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
dev_info(&mite->pcidev->dev, "fifo size is %i.\n", mite->fifo_size);
return 0;
}
-EXPORT_SYMBOL(mite_setup2);
+EXPORT_SYMBOL_GPL(mite_setup2);
int mite_setup(struct mite_struct *mite)
{
return mite_setup2(mite, 0);
}
-EXPORT_SYMBOL(mite_setup);
+EXPORT_SYMBOL_GPL(mite_setup);
void mite_unsetup(struct mite_struct *mite)
{
@@ -208,12 +192,10 @@ void mite_unsetup(struct mite_struct *mite)
iounmap(mite->daq_io_addr);
mite->daq_io_addr = NULL;
}
- if (mite->mite_phys_addr) {
- comedi_pci_disable(mite->pcidev);
+ if (mite->mite_phys_addr)
mite->mite_phys_addr = 0;
- }
}
-EXPORT_SYMBOL(mite_unsetup);
+EXPORT_SYMBOL_GPL(mite_unsetup);
struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite)
{
@@ -232,7 +214,7 @@ struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite)
ring->descriptors_dma_addr = 0;
return ring;
};
-EXPORT_SYMBOL(mite_alloc_ring);
+EXPORT_SYMBOL_GPL(mite_alloc_ring);
void mite_free_ring(struct mite_dma_descriptor_ring *ring)
{
@@ -248,7 +230,7 @@ void mite_free_ring(struct mite_dma_descriptor_ring *ring)
kfree(ring);
}
};
-EXPORT_SYMBOL(mite_free_ring);
+EXPORT_SYMBOL_GPL(mite_free_ring);
struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
struct
@@ -275,7 +257,7 @@ struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
spin_unlock_irqrestore(&mite->lock, flags);
return channel;
}
-EXPORT_SYMBOL(mite_request_channel_in_range);
+EXPORT_SYMBOL_GPL(mite_request_channel_in_range);
void mite_release_channel(struct mite_channel *mite_chan)
{
@@ -302,7 +284,7 @@ void mite_release_channel(struct mite_channel *mite_chan)
}
spin_unlock_irqrestore(&mite->lock, flags);
}
-EXPORT_SYMBOL(mite_release_channel);
+EXPORT_SYMBOL_GPL(mite_release_channel);
void mite_dma_arm(struct mite_channel *mite_chan)
{
@@ -325,7 +307,7 @@ void mite_dma_arm(struct mite_channel *mite_chan)
spin_unlock_irqrestore(&mite->lock, flags);
/* mite_dma_tcr(mite, channel); */
}
-EXPORT_SYMBOL(mite_dma_arm);
+EXPORT_SYMBOL_GPL(mite_dma_arm);
/**************************************/
@@ -382,7 +364,7 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring,
smp_wmb();
return 0;
}
-EXPORT_SYMBOL(mite_buf_change);
+EXPORT_SYMBOL_GPL(mite_buf_change);
void mite_prep_dma(struct mite_channel *mite_chan,
unsigned int num_device_bits, unsigned int num_memory_bits)
@@ -473,7 +455,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
MDPRINTK("exit mite_prep_dma\n");
}
-EXPORT_SYMBOL(mite_prep_dma);
+EXPORT_SYMBOL_GPL(mite_prep_dma);
static u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
{
@@ -487,7 +469,7 @@ u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
return readl(mite->mite_io_addr +
MITE_FCR(mite_chan->channel)) & 0x000000FF;
}
-EXPORT_SYMBOL(mite_bytes_in_transit);
+EXPORT_SYMBOL_GPL(mite_bytes_in_transit);
/* returns lower bound for number of bytes transferred from device to memory */
u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
@@ -497,7 +479,7 @@ u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
device_byte_count = mite_device_bytes_transferred(mite_chan);
return device_byte_count - mite_bytes_in_transit(mite_chan);
}
-EXPORT_SYMBOL(mite_bytes_written_to_memory_lb);
+EXPORT_SYMBOL_GPL(mite_bytes_written_to_memory_lb);
/* returns upper bound for number of bytes transferred from device to memory */
u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
@@ -507,7 +489,7 @@ u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
in_transit_count = mite_bytes_in_transit(mite_chan);
return mite_device_bytes_transferred(mite_chan) - in_transit_count;
}
-EXPORT_SYMBOL(mite_bytes_written_to_memory_ub);
+EXPORT_SYMBOL_GPL(mite_bytes_written_to_memory_ub);
/* returns lower bound for number of bytes read from memory to device */
u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
@@ -517,7 +499,7 @@ u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
device_byte_count = mite_device_bytes_transferred(mite_chan);
return device_byte_count + mite_bytes_in_transit(mite_chan);
}
-EXPORT_SYMBOL(mite_bytes_read_from_memory_lb);
+EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_lb);
/* returns upper bound for number of bytes read from memory to device */
u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
@@ -527,7 +509,7 @@ u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
in_transit_count = mite_bytes_in_transit(mite_chan);
return mite_device_bytes_transferred(mite_chan) + in_transit_count;
}
-EXPORT_SYMBOL(mite_bytes_read_from_memory_ub);
+EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_ub);
unsigned mite_dma_tcr(struct mite_channel *mite_chan)
{
@@ -542,7 +524,7 @@ unsigned mite_dma_tcr(struct mite_channel *mite_chan)
return tcr;
}
-EXPORT_SYMBOL(mite_dma_tcr);
+EXPORT_SYMBOL_GPL(mite_dma_tcr);
void mite_dma_disarm(struct mite_channel *mite_chan)
{
@@ -553,7 +535,7 @@ void mite_dma_disarm(struct mite_channel *mite_chan)
chor = CHOR_ABORT;
writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
}
-EXPORT_SYMBOL(mite_dma_disarm);
+EXPORT_SYMBOL_GPL(mite_dma_disarm);
int mite_sync_input_dma(struct mite_channel *mite_chan,
struct comedi_async *async)
@@ -591,7 +573,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan,
async->events |= COMEDI_CB_BLOCK;
return 0;
}
-EXPORT_SYMBOL(mite_sync_input_dma);
+EXPORT_SYMBOL_GPL(mite_sync_input_dma);
int mite_sync_output_dma(struct mite_channel *mite_chan,
struct comedi_async *async)
@@ -629,7 +611,7 @@ int mite_sync_output_dma(struct mite_channel *mite_chan,
}
return 0;
}
-EXPORT_SYMBOL(mite_sync_output_dma);
+EXPORT_SYMBOL_GPL(mite_sync_output_dma);
unsigned mite_get_status(struct mite_channel *mite_chan)
{
@@ -648,7 +630,7 @@ unsigned mite_get_status(struct mite_channel *mite_chan)
spin_unlock_irqrestore(&mite->lock, flags);
return status;
}
-EXPORT_SYMBOL(mite_get_status);
+EXPORT_SYMBOL_GPL(mite_get_status);
int mite_done(struct mite_channel *mite_chan)
{
@@ -662,7 +644,7 @@ int mite_done(struct mite_channel *mite_chan)
spin_unlock_irqrestore(&mite->lock, flags);
return done;
}
-EXPORT_SYMBOL(mite_done);
+EXPORT_SYMBOL_GPL(mite_done);
#ifdef DEBUG_MITE
@@ -795,7 +777,7 @@ void mite_dump_regs(struct mite_channel *mite_chan)
value = readl(mite_io_addr + offset);
pr_debug("mite status[FCR] at 0x%08x =0x%08x\n", offset, value);
}
-EXPORT_SYMBOL(mite_dump_regs);
+EXPORT_SYMBOL_GPL(mite_dump_regs);
#endif
static int __init mite_module_init(void)
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index 67dc5ad81b0..4717be4ad26 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -285,18 +285,11 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct mpc624_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase);
- if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) {
- printk(KERN_ERR "I/O port(s) in use\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
- dev->board_name = "mpc624";
+ ret = comedi_request_region(dev, it->options[0], MPC624_SIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -306,48 +299,35 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
switch (it->options[1]) {
case 0:
devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
- printk(KERN_INFO "3.52 kHz, ");
break;
case 1:
devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz;
- printk(KERN_INFO "1.76 kHz, ");
break;
case 2:
devpriv->ulConvertionRate = MPC624_SPEED_880_Hz;
- printk(KERN_INFO "880 Hz, ");
break;
case 3:
devpriv->ulConvertionRate = MPC624_SPEED_440_Hz;
- printk(KERN_INFO "440 Hz, ");
break;
case 4:
devpriv->ulConvertionRate = MPC624_SPEED_220_Hz;
- printk(KERN_INFO "220 Hz, ");
break;
case 5:
devpriv->ulConvertionRate = MPC624_SPEED_110_Hz;
- printk(KERN_INFO "110 Hz, ");
break;
case 6:
devpriv->ulConvertionRate = MPC624_SPEED_55_Hz;
- printk(KERN_INFO "55 Hz, ");
break;
case 7:
devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz;
- printk(KERN_INFO "27.5 Hz, ");
break;
case 8:
devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz;
- printk(KERN_INFO "13.75 Hz, ");
break;
case 9:
devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz;
- printk(KERN_INFO "6.875 Hz, ");
break;
default:
- printk
- (KERN_ERR "illegal conversion rate setting!"
- " Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
}
@@ -362,37 +342,26 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
switch (it->options[1]) {
default:
s->maxdata = 0x3FFFFFFF;
- printk(KERN_INFO "30 bit, ");
}
switch (it->options[1]) {
case 0:
s->range_table = &range_mpc624_bipolar1;
- printk(KERN_INFO "1.01V]: ");
break;
default:
s->range_table = &range_mpc624_bipolar10;
- printk(KERN_INFO "10.1V]: ");
}
s->len_chanlist = 1;
s->insn_read = mpc624_ai_rinsn;
- printk(KERN_INFO "attached\n");
-
return 1;
}
-static void mpc624_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, MPC624_SIZE);
-}
-
static struct comedi_driver mpc624_driver = {
.driver_name = "mpc624",
.module = THIS_MODULE,
.attach = mpc624_attach,
- .detach = mpc624_detach
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(mpc624_driver);
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
index 1f5f402f3d1..7a8292086e1 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -222,41 +222,20 @@ static void encoder_reset(struct comedi_device *dev)
}
}
-/*
- options[0] - I/O port
- options[1] - irq
- options[2] - number of encoder chips installed
- */
-
static int multiq3_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
struct multiq3_private *devpriv;
- int result = 0;
- unsigned long iobase;
- unsigned int irq;
struct comedi_subdevice *s;
+ int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: multiq3: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) {
- printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor);
- return -EIO;
- }
-
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], MULTIQ3_SIZE);
+ if (ret)
+ return ret;
- irq = it->options[1];
- if (irq)
- printk(KERN_WARNING "comedi%d: irq = %u ignored\n",
- dev->minor, irq);
- else
- printk(KERN_WARNING "comedi%d: no irq\n", dev->minor);
- dev->board_name = "multiq3";
-
- result = comedi_alloc_subdevices(dev, 5);
- if (result)
- return result;
+ ret = comedi_alloc_subdevices(dev, 5);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -315,19 +294,11 @@ static int multiq3_attach(struct comedi_device *dev,
return 0;
}
-static void multiq3_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, MULTIQ3_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
-}
-
static struct comedi_driver multiq3_driver = {
.driver_name = "multiq3",
.module = THIS_MODULE,
.attach = multiq3_attach,
- .detach = multiq3_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(multiq3_driver);
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index bcd4df290ec..d10f777b7f1 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -81,33 +81,24 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
#define Rising_Edge_Detection_Enable(x) (0x018+(x))
#define Falling_Edge_Detection_Enable(x) (0x020+(x))
-struct ni6527_board {
+enum ni6527_boardid {
+ BOARD_PCI6527,
+ BOARD_PXI6527,
+};
- int dev_id;
+struct ni6527_board {
const char *name;
};
static const struct ni6527_board ni6527_boards[] = {
- {
- .dev_id = 0x2b20,
- .name = "pci-6527",
- },
- {
- .dev_id = 0x2b10,
- .name = "pxi-6527",
- },
-};
-
-#define this_board ((const struct ni6527_board *)dev->board_ptr)
-
-static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b10)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b20)},
- {0}
+ [BOARD_PCI6527] = {
+ .name = "pci-6527",
+ },
+ [BOARD_PXI6527] = {
+ .name = "pxi-6527",
+ },
};
-MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
-
struct ni6527_private {
struct mite_struct *mite;
unsigned int filter_interval;
@@ -329,37 +320,31 @@ static int ni6527_intr_insn_config(struct comedi_device *dev,
return 2;
}
-static const struct ni6527_board *
-ni6527_find_boardinfo(struct pci_dev *pcidev)
-{
- unsigned int dev_id = pcidev->device;
- unsigned int n;
-
- for (n = 0; n < ARRAY_SIZE(ni6527_boards); n++) {
- const struct ni6527_board *board = &ni6527_boards[n];
- if (board->dev_id == dev_id)
- return board;
- }
- return NULL;
-}
-
static int ni6527_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct ni6527_board *board = NULL;
struct ni6527_private *devpriv;
struct comedi_subdevice *s;
int ret;
+ if (context < ARRAY_SIZE(ni6527_boards))
+ board = &ni6527_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;
- dev->board_ptr = ni6527_find_boardinfo(pcidev);
- if (!dev->board_ptr)
- return -ENODEV;
-
devpriv->mite = mite_alloc(pcidev);
if (!devpriv->mite)
return -ENOMEM;
@@ -370,7 +355,6 @@ static int ni6527_auto_attach(struct comedi_device *dev,
return ret;
}
- dev->board_name = this_board->name;
dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name,
readb(devpriv->mite->daq_io_addr + ID_Register));
@@ -439,6 +423,7 @@ static void ni6527_detach(struct comedi_device *dev)
mite_unsetup(devpriv->mite);
mite_free(devpriv->mite);
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver ni6527_driver = {
@@ -449,15 +434,22 @@ static struct comedi_driver ni6527_driver = {
};
static int ni6527_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &ni6527_driver);
+ return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data);
}
+static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
+ { PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 },
+ { PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
+
static struct pci_driver ni6527_pci_driver = {
- .name = DRIVER_NAME,
- .id_table = ni6527_pci_table,
- .probe = ni6527_pci_probe,
+ .name = DRIVER_NAME,
+ .id_table = ni6527_pci_table,
+ .probe = ni6527_pci_probe,
.remove = comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index bfa790ecf41..3f71f0f54d3 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -112,8 +112,32 @@ static inline unsigned Filter_Enable(unsigned port)
#define OverflowIntEnable 0x02
#define EdgeIntEnable 0x01
+enum ni_65xx_boardid {
+ BOARD_PCI6509,
+ BOARD_PXI6509,
+ BOARD_PCI6510,
+ BOARD_PCI6511,
+ BOARD_PXI6511,
+ BOARD_PCI6512,
+ BOARD_PXI6512,
+ BOARD_PCI6513,
+ BOARD_PXI6513,
+ BOARD_PCI6514,
+ BOARD_PXI6514,
+ BOARD_PCI6515,
+ BOARD_PXI6515,
+ BOARD_PCI6516,
+ BOARD_PCI6517,
+ BOARD_PCI6518,
+ BOARD_PCI6519,
+ BOARD_PCI6520,
+ BOARD_PCI6521,
+ BOARD_PXI6521,
+ BOARD_PCI6528,
+ BOARD_PXI6528,
+};
+
struct ni_65xx_board {
- int dev_id;
const char *name;
unsigned num_dio_ports;
unsigned num_di_ports;
@@ -122,130 +146,117 @@ struct ni_65xx_board {
};
static const struct ni_65xx_board ni_65xx_boards[] = {
- {
- .dev_id = 0x7085,
- .name = "pci-6509",
- .num_dio_ports = 12,
- .invert_outputs = 0},
- {
- .dev_id = 0x1710,
- .name = "pxi-6509",
- .num_dio_ports = 12,
- .invert_outputs = 0},
- {
- .dev_id = 0x7124,
- .name = "pci-6510",
- .num_di_ports = 4},
- {
- .dev_id = 0x70c3,
- .name = "pci-6511",
- .num_di_ports = 8},
- {
- .dev_id = 0x70d3,
- .name = "pxi-6511",
- .num_di_ports = 8},
- {
- .dev_id = 0x70cc,
- .name = "pci-6512",
- .num_do_ports = 8},
- {
- .dev_id = 0x70d2,
- .name = "pxi-6512",
- .num_do_ports = 8},
- {
- .dev_id = 0x70c8,
- .name = "pci-6513",
- .num_do_ports = 8,
- .invert_outputs = 1},
- {
- .dev_id = 0x70d1,
- .name = "pxi-6513",
- .num_do_ports = 8,
- .invert_outputs = 1},
- {
- .dev_id = 0x7088,
- .name = "pci-6514",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .invert_outputs = 1},
- {
- .dev_id = 0x70CD,
- .name = "pxi-6514",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .invert_outputs = 1},
- {
- .dev_id = 0x7087,
- .name = "pci-6515",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .invert_outputs = 1},
- {
- .dev_id = 0x70c9,
- .name = "pxi-6515",
- .num_di_ports = 4,
- .num_do_ports = 4,
- .invert_outputs = 1},
- {
- .dev_id = 0x7125,
- .name = "pci-6516",
- .num_do_ports = 4,
- .invert_outputs = 1},
- {
- .dev_id = 0x7126,
- .name = "pci-6517",
- .num_do_ports = 4,
- .invert_outputs = 1},
- {
- .dev_id = 0x7127,
- .name = "pci-6518",
- .num_di_ports = 2,
- .num_do_ports = 2,
- .invert_outputs = 1},
- {
- .dev_id = 0x7128,
- .name = "pci-6519",
- .num_di_ports = 2,
- .num_do_ports = 2,
- .invert_outputs = 1},
- {
- .dev_id = 0x71c5,
- .name = "pci-6520",
- .num_di_ports = 1,
- .num_do_ports = 1,
- },
- {
- .dev_id = 0x718b,
- .name = "pci-6521",
- .num_di_ports = 1,
- .num_do_ports = 1,
- },
- {
- .dev_id = 0x718c,
- .name = "pxi-6521",
- .num_di_ports = 1,
- .num_do_ports = 1,
- },
- {
- .dev_id = 0x70a9,
- .name = "pci-6528",
- .num_di_ports = 3,
- .num_do_ports = 3,
- },
- {
- .dev_id = 0x7086,
- .name = "pxi-6528",
- .num_di_ports = 3,
- .num_do_ports = 3,
- },
+ [BOARD_PCI6509] = {
+ .name = "pci-6509",
+ .num_dio_ports = 12,
+ },
+ [BOARD_PXI6509] = {
+ .name = "pxi-6509",
+ .num_dio_ports = 12,
+ },
+ [BOARD_PCI6510] = {
+ .name = "pci-6510",
+ .num_di_ports = 4,
+ },
+ [BOARD_PCI6511] = {
+ .name = "pci-6511",
+ .num_di_ports = 8,
+ },
+ [BOARD_PXI6511] = {
+ .name = "pxi-6511",
+ .num_di_ports = 8,
+ },
+ [BOARD_PCI6512] = {
+ .name = "pci-6512",
+ .num_do_ports = 8,
+ },
+ [BOARD_PXI6512] = {
+ .name = "pxi-6512",
+ .num_do_ports = 8,
+ },
+ [BOARD_PCI6513] = {
+ .name = "pci-6513",
+ .num_do_ports = 8,
+ .invert_outputs = 1,
+ },
+ [BOARD_PXI6513] = {
+ .name = "pxi-6513",
+ .num_do_ports = 8,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6514] = {
+ .name = "pci-6514",
+ .num_di_ports = 4,
+ .num_do_ports = 4,
+ .invert_outputs = 1,
+ },
+ [BOARD_PXI6514] = {
+ .name = "pxi-6514",
+ .num_di_ports = 4,
+ .num_do_ports = 4,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6515] = {
+ .name = "pci-6515",
+ .num_di_ports = 4,
+ .num_do_ports = 4,
+ .invert_outputs = 1,
+ },
+ [BOARD_PXI6515] = {
+ .name = "pxi-6515",
+ .num_di_ports = 4,
+ .num_do_ports = 4,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6516] = {
+ .name = "pci-6516",
+ .num_do_ports = 4,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6517] = {
+ .name = "pci-6517",
+ .num_do_ports = 4,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6518] = {
+ .name = "pci-6518",
+ .num_di_ports = 2,
+ .num_do_ports = 2,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6519] = {
+ .name = "pci-6519",
+ .num_di_ports = 2,
+ .num_do_ports = 2,
+ .invert_outputs = 1,
+ },
+ [BOARD_PCI6520] = {
+ .name = "pci-6520",
+ .num_di_ports = 1,
+ .num_do_ports = 1,
+ },
+ [BOARD_PCI6521] = {
+ .name = "pci-6521",
+ .num_di_ports = 1,
+ .num_do_ports = 1,
+ },
+ [BOARD_PXI6521] = {
+ .name = "pxi-6521",
+ .num_di_ports = 1,
+ .num_do_ports = 1,
+ },
+ [BOARD_PCI6528] = {
+ .name = "pci-6528",
+ .num_di_ports = 3,
+ .num_do_ports = 3,
+ },
+ [BOARD_PXI6528] = {
+ .name = "pxi-6528",
+ .num_di_ports = 3,
+ .num_do_ports = 3,
+ },
};
-#define n_ni_65xx_boards ARRAY_SIZE(ni_65xx_boards)
-static inline const struct ni_65xx_board *board(struct comedi_device *dev)
-{
- return dev->board_ptr;
-}
-
static inline unsigned ni_65xx_port_by_channel(unsigned channel)
{
return channel / ni_65xx_channels_per_port;
@@ -257,34 +268,6 @@ static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board
return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
}
-static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = {
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1710)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7085)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7086)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7087)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7088)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70a9)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c3)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c8)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c9)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70cc)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70CD)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d1)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d2)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70d3)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7124)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7125)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7126)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7127)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x7128)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718b)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x718c)},
- {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71c5)},
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
-
struct ni_65xx_private {
struct mite_struct *mite;
unsigned int filter_interval;
@@ -398,6 +381,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_65xx_board *board = comedi_board(dev);
struct ni_65xx_private *devpriv = dev->private;
unsigned base_bitfield_channel;
const unsigned max_ports_per_bitfield = 5;
@@ -413,7 +397,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
unsigned base_port_channel;
unsigned port_mask, port_data, port_read_bits;
int bitshift;
- if (port >= ni_65xx_total_num_ports(board(dev)))
+ if (port >= ni_65xx_total_num_ports(board))
break;
base_port_channel = port_offset * ni_65xx_channels_per_port;
port_mask = data[0];
@@ -436,7 +420,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
devpriv->output_bits[port] |=
port_data & port_mask;
bits = devpriv->output_bits[port];
- if (board(dev)->invert_outputs)
+ if (board->invert_outputs)
bits = ~bits;
writeb(bits,
devpriv->mite->daq_io_addr +
@@ -444,7 +428,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
}
port_read_bits =
readb(devpriv->mite->daq_io_addr + Port_Data(port));
- if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) {
+ if (s->type == COMEDI_SUBD_DO && board->invert_outputs) {
/* Outputs inverted, so invert value read back from
* DO subdevice. (Does not apply to boards with DIO
* subdevice.) */
@@ -599,38 +583,32 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev,
return 2;
}
-static const struct ni_65xx_board *
-ni_65xx_find_boardinfo(struct pci_dev *pcidev)
-{
- unsigned int dev_id = pcidev->device;
- unsigned int n;
-
- for (n = 0; n < ARRAY_SIZE(ni_65xx_boards); n++) {
- const struct ni_65xx_board *board = &ni_65xx_boards[n];
- if (board->dev_id == dev_id)
- return board;
- }
- return NULL;
-}
-
static int ni_65xx_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_65xx_board *board = NULL;
struct ni_65xx_private *devpriv;
struct comedi_subdevice *s;
unsigned i;
int ret;
+ if (context < ARRAY_SIZE(ni_65xx_boards))
+ board = &ni_65xx_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;
- dev->board_ptr = ni_65xx_find_boardinfo(pcidev);
- if (!dev->board_ptr)
- return -ENODEV;
-
devpriv->mite = mite_alloc(pcidev);
if (!devpriv->mite)
return -ENOMEM;
@@ -641,7 +619,6 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
return ret;
}
- dev->board_name = board(dev)->name;
dev->irq = mite_irq(devpriv->mite);
dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name,
readb(devpriv->mite->daq_io_addr + ID_Register));
@@ -651,11 +628,11 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
return ret;
s = &dev->subdevices[0];
- if (board(dev)->num_di_ports) {
+ if (board->num_di_ports) {
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
s->n_chan =
- board(dev)->num_di_ports * ni_65xx_channels_per_port;
+ board->num_di_ports * ni_65xx_channels_per_port;
s->range_table = &range_digital;
s->maxdata = 1;
s->insn_config = ni_65xx_dio_insn_config;
@@ -669,28 +646,28 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
}
s = &dev->subdevices[1];
- if (board(dev)->num_do_ports) {
+ if (board->num_do_ports) {
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan =
- board(dev)->num_do_ports * ni_65xx_channels_per_port;
+ board->num_do_ports * ni_65xx_channels_per_port;
s->range_table = &range_digital;
s->maxdata = 1;
s->insn_bits = ni_65xx_dio_insn_bits;
s->private = ni_65xx_alloc_subdevice_private();
if (s->private == NULL)
return -ENOMEM;
- sprivate(s)->base_port = board(dev)->num_di_ports;
+ sprivate(s)->base_port = board->num_di_ports;
} else {
s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[2];
- if (board(dev)->num_dio_ports) {
+ if (board->num_dio_ports) {
s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan =
- board(dev)->num_dio_ports * ni_65xx_channels_per_port;
+ board->num_dio_ports * ni_65xx_channels_per_port;
s->range_table = &range_digital;
s->maxdata = 1;
s->insn_config = ni_65xx_dio_insn_config;
@@ -699,7 +676,7 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
if (s->private == NULL)
return -ENOMEM;
sprivate(s)->base_port = 0;
- for (i = 0; i < board(dev)->num_dio_ports; ++i) {
+ for (i = 0; i < board->num_dio_ports; ++i) {
/* configure all ports for input */
writeb(0x1,
devpriv->mite->daq_io_addr +
@@ -722,10 +699,10 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
s->insn_bits = ni_65xx_intr_insn_bits;
s->insn_config = ni_65xx_intr_insn_config;
- for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
+ for (i = 0; i < ni_65xx_total_num_ports(board); ++i) {
writeb(0x00,
devpriv->mite->daq_io_addr + Filter_Enable(i));
- if (board(dev)->invert_outputs)
+ if (board->invert_outputs)
writeb(0x01,
devpriv->mite->daq_io_addr + Port_Data(i));
else
@@ -753,6 +730,7 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
static void ni_65xx_detach(struct comedi_device *dev)
{
struct ni_65xx_private *devpriv = dev->private;
+ int i;
if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
writeb(0x00,
@@ -761,20 +739,15 @@ static void ni_65xx_detach(struct comedi_device *dev)
}
if (dev->irq)
free_irq(dev->irq, dev);
+ for (i = 0; i < dev->n_subdevices; ++i)
+ comedi_spriv_free(dev, i);
if (devpriv) {
- struct comedi_subdevice *s;
- unsigned i;
-
- for (i = 0; i < dev->n_subdevices; ++i) {
- s = &dev->subdevices[i];
- kfree(s->private);
- s->private = NULL;
- }
if (devpriv->mite) {
mite_unsetup(devpriv->mite);
mite_free(devpriv->mite);
}
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver ni_65xx_driver = {
@@ -785,15 +758,42 @@ static struct comedi_driver ni_65xx_driver = {
};
static int ni_65xx_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_65xx_driver);
+ return comedi_pci_auto_config(dev, &ni_65xx_driver, id->driver_data);
}
+static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = {
+ { PCI_VDEVICE(NI, 0x1710), BOARD_PXI6509 },
+ { PCI_VDEVICE(NI, 0x7085), BOARD_PCI6509 },
+ { PCI_VDEVICE(NI, 0x7086), BOARD_PXI6528 },
+ { PCI_VDEVICE(NI, 0x7087), BOARD_PCI6515 },
+ { PCI_VDEVICE(NI, 0x7088), BOARD_PCI6514 },
+ { PCI_VDEVICE(NI, 0x70a9), BOARD_PCI6528 },
+ { PCI_VDEVICE(NI, 0x70c3), BOARD_PCI6511 },
+ { PCI_VDEVICE(NI, 0x70c8), BOARD_PCI6513 },
+ { PCI_VDEVICE(NI, 0x70c9), BOARD_PXI6515 },
+ { PCI_VDEVICE(NI, 0x70cc), BOARD_PCI6512 },
+ { PCI_VDEVICE(NI, 0x70cd), BOARD_PXI6514 },
+ { PCI_VDEVICE(NI, 0x70d1), BOARD_PXI6513 },
+ { PCI_VDEVICE(NI, 0x70d2), BOARD_PXI6512 },
+ { PCI_VDEVICE(NI, 0x70d3), BOARD_PXI6511 },
+ { PCI_VDEVICE(NI, 0x7124), BOARD_PCI6510 },
+ { PCI_VDEVICE(NI, 0x7125), BOARD_PCI6516 },
+ { PCI_VDEVICE(NI, 0x7126), BOARD_PCI6517 },
+ { PCI_VDEVICE(NI, 0x7127), BOARD_PCI6518 },
+ { PCI_VDEVICE(NI, 0x7128), BOARD_PCI6519 },
+ { PCI_VDEVICE(NI, 0x718b), BOARD_PCI6521 },
+ { PCI_VDEVICE(NI, 0x718c), BOARD_PXI6521 },
+ { PCI_VDEVICE(NI, 0x71c5), BOARD_PCI6520 },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
+
static struct pci_driver ni_65xx_pci_driver = {
- .name = "ni_65xx",
- .id_table = ni_65xx_pci_table,
- .probe = ni_65xx_pci_probe,
+ .name = "ni_65xx",
+ .id_table = ni_65xx_pci_table,
+ .probe = ni_65xx_pci_probe,
.remove = comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index e46dd7a1a72..5cdda7fe97a 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);
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 2faf86c83dc..42ab6dbf9d3 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -60,26 +60,28 @@ Commands are not supported.
#define MISC_STATUS_OFFSET 0x14
#define MISC_CONTROL_OFFSET 0x14
-/* Board description*/
+enum ni_670x_boardid {
+ BOARD_PCI6703,
+ BOARD_PXI6704,
+ BOARD_PCI6704,
+};
struct ni_670x_board {
const char *name;
- unsigned short dev_id;
unsigned short ao_chans;
};
static const struct ni_670x_board ni_670x_boards[] = {
- {
+ [BOARD_PCI6703] = {
.name = "PCI-6703",
- .dev_id = 0x2c90,
.ao_chans = 16,
- }, {
+ },
+ [BOARD_PXI6704] = {
.name = "PXI-6704",
- .dev_id = 0x1920,
.ao_chans = 32,
- }, {
+ },
+ [BOARD_PCI6704] = {
.name = "PCI-6704",
- .dev_id = 0x1290,
.ao_chans = 32,
},
};
@@ -92,8 +94,6 @@ struct ni_670x_private {
unsigned int ao_readback[32];
};
-static struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
-
static int ni_670x_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
@@ -189,49 +189,41 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev,
return insn->n;
}
-static const struct ni_670x_board *
-ni_670x_find_boardinfo(struct pci_dev *pcidev)
-{
- unsigned int dev_id = pcidev->device;
- unsigned int n;
-
- for (n = 0; n < ARRAY_SIZE(ni_670x_boards); n++) {
- const struct ni_670x_board *board = &ni_670x_boards[n];
- if (board->dev_id == dev_id)
- return board;
- }
- return NULL;
-}
-
static int ni_670x_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_670x_board *thisboard;
+ const struct ni_670x_board *thisboard = NULL;
struct ni_670x_private *devpriv;
struct comedi_subdevice *s;
int ret;
int i;
+ if (context < ARRAY_SIZE(ni_670x_boards))
+ thisboard = &ni_670x_boards[context];
+ if (!thisboard)
+ return -ENODEV;
+ dev->board_ptr = thisboard;
+ dev->board_name = thisboard->name;
+
+ 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 = ni_670x_find_boardinfo(pcidev);
- if (!dev->board_ptr)
- return -ENODEV;
devpriv->mite = mite_alloc(pcidev);
if (!devpriv->mite)
return -ENOMEM;
- thisboard = comedi_board(dev);
ret = mite_setup(devpriv->mite);
if (ret < 0) {
dev_warn(dev->class_dev, "error setting up mite\n");
return ret;
}
- dev->board_name = thisboard->name;
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
@@ -296,6 +288,7 @@ static void ni_670x_detach(struct comedi_device *dev)
mite_unsetup(devpriv->mite);
mite_free(devpriv->mite);
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver ni_670x_driver = {
@@ -306,14 +299,15 @@ static struct comedi_driver ni_670x_driver = {
};
static int ni_670x_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_670x_driver);
+ return comedi_pci_auto_config(dev, &ni_670x_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c90) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1920) },
+ { PCI_VDEVICE(NI, 0x1290), BOARD_PCI6704 },
+ { PCI_VDEVICE(NI, 0x1920), BOARD_PXI6704 },
+ { PCI_VDEVICE(NI, 0x2c90), BOARD_PCI6703 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 06de25bb2f5..2d375168f36 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -154,11 +154,6 @@ static const struct a2150_board a2150_boards[] = {
},
};
-/*
- * Useful for shorthand access to the particular board structure
- */
-#define thisboard ((const struct a2150_board *)dev->board_ptr)
-
struct a2150_private {
volatile unsigned int count; /* number of data points left to be taken */
@@ -204,7 +199,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
short dpnt;
static const int sample_size = sizeof(devpriv->dma_buffer[0]);
- if (dev->attached == 0) {
+ if (!dev->attached) {
comedi_error(dev, "premature interrupt");
return IRQ_HANDLED;
}
@@ -319,6 +314,7 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static int a2150_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
+ const struct a2150_board *thisboard = comedi_board(dev);
int err = 0;
int tmp;
int startChan;
@@ -604,6 +600,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
int flags)
{
+ const struct a2150_board *thisboard = comedi_board(dev);
struct a2150_private *devpriv = dev->private;
int lub, glb, temp;
int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
@@ -719,45 +716,23 @@ static int a2150_probe(struct comedi_device *dev)
static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
+ const struct a2150_board *thisboard = comedi_board(dev);
struct a2150_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase = it->options[0];
unsigned int irq = it->options[1];
unsigned int dma = it->options[2];
static const int timeout = 2000;
int i;
int ret;
- printk("comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name,
- iobase);
- if (irq) {
- printk(", irq %u", irq);
- } else {
- printk(", no irq");
- }
- if (dma) {
- printk(", dma %u", dma);
- } else {
- printk(", no dma");
- }
- printk("\n");
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- if (iobase == 0) {
- printk(" io base address required\n");
- return -EINVAL;
- }
-
- /* check if io addresses are available */
- if (!request_region(iobase, A2150_SIZE, dev->driver->driver_name)) {
- printk(" I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], A2150_SIZE);
+ if (ret)
+ return ret;
/* grab our IRQ */
if (irq) {
@@ -797,6 +772,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
dev->board_ptr = a2150_boards + a2150_probe(dev);
+ thisboard = comedi_board(dev);
dev->board_name = thisboard->name;
ret = comedi_alloc_subdevices(dev, 1);
@@ -851,17 +827,14 @@ static void a2150_detach(struct comedi_device *dev)
{
struct a2150_private *devpriv = dev->private;
- if (dev->iobase) {
+ if (dev->iobase)
outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
- release_region(dev->iobase, A2150_SIZE);
- }
- if (dev->irq)
- free_irq(dev->irq, dev);
if (devpriv) {
if (devpriv->dma)
free_dma(devpriv->dma);
kfree(devpriv->dma_buffer);
}
+ comedi_legacy_detach(dev);
};
static struct comedi_driver ni_at_a2150_driver = {
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index 907f65cdbdc..7e5783a4f4e 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -337,24 +337,14 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct atao_board *board = comedi_board(dev);
struct atao_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
int ao_unipolar;
int ret;
- iobase = it->options[0];
- if (iobase == 0)
- iobase = 0x1c0;
ao_unipolar = it->options[3];
- printk(KERN_INFO "comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase);
-
- if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) {
- printk(" I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0], ATAO_SIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -409,12 +399,6 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void atao_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, ATAO_SIZE);
-}
-
static const struct atao_board atao_boards[] = {
{
.name = "ai-ao-6",
@@ -429,7 +413,7 @@ static struct comedi_driver ni_at_ao_driver = {
.driver_name = "ni_at_ao",
.module = THIS_MODULE,
.attach = atao_attach,
- .detach = atao_detach,
+ .detach = comedi_legacy_detach,
.board_name = &atao_boards[0].name,
.offset = sizeof(struct atao_board),
.num_names = ARRAY_SIZE(atao_boards),
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index 2cc29965e15..4ced7ba119b 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -350,7 +350,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
struct pnp_dev *isapnp_dev = NULL;
int i;
- for (i = 0; i < n_ni_boards; i++) {
+ for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
isapnp_dev = pnp_find_dev(NULL,
ISAPNP_VENDOR('N', 'I', 'C'),
ISAPNP_FUNCTION(ni_boards[i].
@@ -377,7 +377,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
}
break;
}
- if (i == n_ni_boards)
+ if (i == ARRAY_SIZE(ni_boards))
return -ENODEV;
*dev = isapnp_dev;
return 0;
@@ -388,7 +388,7 @@ static int ni_getboardtype(struct comedi_device *dev)
int device_id = ni_read_eeprom(dev, 511);
int i;
- for (i = 0; i < n_ni_boards; i++) {
+ for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
if (ni_boards[i].device_id == device_id)
return i;
@@ -406,6 +406,7 @@ static int ni_getboardtype(struct comedi_device *dev)
static int ni_atmio_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ const struct ni_board_struct *boardtype;
struct ni_private *devpriv;
struct pnp_dev *isapnp_dev;
int ret;
@@ -436,15 +437,9 @@ static int ni_atmio_attach(struct comedi_device *dev,
devpriv->isapnp_dev = isapnp_dev;
}
- /* reserve our I/O region */
-
- printk("comedi%d: ni_atmio: 0x%04lx", dev->minor, iobase);
- if (!request_region(iobase, NI_SIZE, "ni_atmio")) {
- printk(" I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, iobase, NI_SIZE);
+ if (ret)
+ return ret;
#ifdef DEBUG
/* board existence sanity check */
@@ -466,9 +461,10 @@ static int ni_atmio_attach(struct comedi_device *dev,
return -EIO;
dev->board_ptr = ni_boards + board;
+ boardtype = comedi_board(dev);
- printk(" %s", boardtype.name);
- dev->board_name = boardtype.name;
+ printk(" %s", boardtype->name);
+ dev->board_name = boardtype->name;
/* irq stuff */
@@ -503,10 +499,7 @@ static void ni_atmio_detach(struct comedi_device *dev)
struct ni_private *devpriv = dev->private;
mio_common_detach(dev);
- if (dev->iobase)
- release_region(dev->iobase, NI_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
+ comedi_legacy_detach(dev);
if (devpriv->isapnp_dev)
pnp_device_detach(devpriv->isapnp_dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index 4a17494f55e..6c97a0925aa 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -638,22 +638,13 @@ static int atmio16d_attach(struct comedi_device *dev,
{
const struct atmio16_board_t *board = comedi_board(dev);
struct atmio16d_private *devpriv;
+ struct comedi_subdevice *s;
unsigned int irq;
- unsigned long iobase;
int ret;
- struct comedi_subdevice *s;
-
- /* make sure the address range is free and allocate it */
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0], ATMIO16D_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@@ -776,18 +767,9 @@ static int atmio16d_attach(struct comedi_device *dev,
static void atmio16d_detach(struct comedi_device *dev)
{
- const struct atmio16_board_t *board = comedi_board(dev);
- struct comedi_subdevice *s;
-
- if (dev->subdevices && board->has_8255) {
- s = &dev->subdevices[3];
- subdev_8255_cleanup(dev, s);
- }
- if (dev->irq)
- free_irq(dev->irq, dev);
+ comedi_spriv_free(dev, 3);
reset_atmio16d(dev);
- if (dev->iobase)
- release_region(dev->iobase, ATMIO16D_SIZE);
+ comedi_legacy_detach(dev);
}
static const struct atmio16_board_t atmio16_boards[] = {
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 9cc6092eacd..d067ef70e19 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -202,8 +202,6 @@ static int daq700_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
link->config_flags |= CONF_AUTO_SET_IO;
ret = comedi_pcmcia_enable(dev, NULL);
if (ret)
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index e1cc9d01f20..9b7805fda93 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -52,8 +52,6 @@ static int dio24_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
link->config_flags |= CONF_AUTO_SET_IO;
ret = comedi_pcmcia_enable(dev, NULL);
if (ret)
@@ -75,8 +73,7 @@ static int dio24_auto_attach(struct comedi_device *dev,
static void dio24_detach(struct comedi_device *dev)
{
- if (dev->subdevices)
- subdev_8255_cleanup(dev, &dev->subdevices[0]);
+ comedi_spriv_free(dev, 0);
comedi_pcmcia_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index f957b8859b3..3d978f34d21 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -1,79 +1,66 @@
/*
- comedi/drivers/ni_labpc.c
- Driver for National Instruments Lab-PC series boards and compatibles
- Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
-
- 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@users.sourceforge.net>
-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
+ * Driver for National Instruments Lab-PC series boards and compatibles
+ * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * 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)
+ * 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@users.sourceforge.net>
+ * Status: works
+ *
+ * Configuration options - ISA boards:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional, required for timed or externally triggered
+ * conversions)
+ * [2] - DMA channel (optional)
+ *
+ * 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.
+ *
+ * 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)
+ * 320502b (lab-pc+)
+ */
-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,128 +72,79 @@ 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
-
-/* Registers for the lab-pc+ */
-
-/* write-only registers */
-#define COMMAND1_REG 0x0
-#define ADC_GAIN_MASK (0x7 << 4)
-#define ADC_CHAN_BITS(x) ((x) & 0x7)
-/* enables multi channel scans */
-#define ADC_SCAN_EN_BIT 0x80
-#define COMMAND2_REG 0x1
-/* enable pretriggering (used in conjunction with SWTRIG) */
-#define PRETRIG_BIT 0x1
-/* enable paced conversions on external trigger */
-#define HWTRIG_BIT 0x2
-/* enable paced conversions */
-#define SWTRIG_BIT 0x4
-/* use two cascaded counters for pacing */
-#define CASCADE_BIT 0x8
-#define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1))
-#define COMMAND3_REG 0x2
-/* enable dma transfers */
-#define DMA_EN_BIT 0x1
-/* enable interrupts for 8255 */
-#define DIO_INTR_EN_BIT 0x2
-/* enable dma terminal count interrupt */
-#define DMATC_INTR_EN_BIT 0x4
-/* enable timer interrupt */
-#define TIMER_INTR_EN_BIT 0x8
-/* enable error interrupt */
-#define ERR_INTR_EN_BIT 0x10
-/* enable fifo not empty interrupt */
-#define ADC_FNE_INTR_EN_BIT 0x20
-#define ADC_CONVERT_REG 0x3
-#define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1))
-#define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1))
-#define ADC_CLEAR_REG 0x8
-#define DMATC_CLEAR_REG 0xa
-#define TIMER_CLEAR_REG 0xc
-/* 1200 boards only */
-#define COMMAND6_REG 0xe
-/* select ground or common-mode reference */
-#define ADC_COMMON_BIT 0x1
-/* adc unipolar */
-#define ADC_UNIP_BIT 0x2
-/* dac unipolar */
-#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1))
-/* enable fifo half full interrupt */
-#define ADC_FHF_INTR_EN_BIT 0x20
-/* enable interrupt on end of hardware count */
-#define A1_INTR_EN_BIT 0x40
-/* scan up from channel zero instead of down to zero */
-#define ADC_SCAN_UP_BIT 0x80
-#define COMMAND4_REG 0xf
-/* enables 'interval' scanning */
-#define INTERVAL_SCAN_EN_BIT 0x1
-/* enables external signal on counter b1 output to trigger scan */
-#define EXT_SCAN_EN_BIT 0x2
-/* chooses direction (output or input) for EXTCONV* line */
-#define EXT_CONVERT_OUT_BIT 0x4
-/* chooses differential inputs for adc (in conjunction with board jumper) */
-#define ADC_DIFF_BIT 0x8
-#define EXT_CONVERT_DISABLE_BIT 0x10
-/* 1200 boards only, calibration stuff */
-#define COMMAND5_REG 0x1c
-/* enable eeprom for write */
-#define EEPROM_WRITE_UNPROTECT_BIT 0x4
-/* enable dithering */
-#define DITHER_EN_BIT 0x8
-/* load calibration dac */
-#define CALDAC_LOAD_BIT 0x10
-/* serial clock - rising edge writes, falling edge reads */
-#define SCLOCK_BIT 0x20
-/* serial data bit for writing to eeprom or calibration dacs */
-#define SDATA_BIT 0x40
-/* enable eeprom for read/write */
-#define EEPROM_EN_BIT 0x80
-#define INTERVAL_COUNT_REG 0x1e
-#define INTERVAL_LOAD_REG 0x1f
-#define INTERVAL_LOAD_BITS 0x1
-
-/* read-only registers */
-#define STATUS1_REG 0x0
-/* data is available in fifo */
-#define DATA_AVAIL_BIT 0x1
-/* overrun has occurred */
-#define OVERRUN_BIT 0x2
-/* fifo overflow */
-#define OVERFLOW_BIT 0x4
-/* timer interrupt has occurred */
-#define TIMER_BIT 0x8
-/* dma terminal count has occurred */
-#define DMATC_BIT 0x10
-/* external trigger has occurred */
-#define EXT_TRIG_BIT 0x40
-/* 1200 boards only */
-#define STATUS2_REG 0x1d
-/* programmable eeprom serial output */
-#define EEPROM_OUT_BIT 0x1
-/* counter A1 terminal count */
-#define A1_TC_BIT 0x2
-/* fifo not half full */
-#define FNHF_BIT 0x4
-#define ADC_FIFO_REG 0xa
-
-#define DIO_BASE_REG 0x10
-#define COUNTER_A_BASE_REG 0x14
-#define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3)
-/* check modes put conversion pacer output in harmless state (a0 mode 2) */
-#define INIT_A0_BITS 0x14
-/* put hardware conversion counter output in harmless state (a1 mode 0) */
-#define INIT_A1_BITS 0x70
-#define COUNTER_B_BASE_REG 0x18
+/*
+ * Register map (all registers are 8-bit)
+ */
+#define STAT1_REG 0x00 /* R: Status 1 reg */
+#define STAT1_DAVAIL (1 << 0)
+#define STAT1_OVERRUN (1 << 1)
+#define STAT1_OVERFLOW (1 << 2)
+#define STAT1_CNTINT (1 << 3)
+#define STAT1_GATA0 (1 << 5)
+#define STAT1_EXTGATA0 (1 << 6)
+#define CMD1_REG 0x00 /* W: Command 1 reg */
+#define CMD1_MA(x) (((x) & 0x7) << 0)
+#define CMD1_TWOSCMP (1 << 3)
+#define CMD1_GAIN_MASK (7 << 4)
+#define CMD1_SCANEN (1 << 7)
+#define CMD2_REG 0x01 /* W: Command 2 reg */
+#define CMD2_PRETRIG (1 << 0)
+#define CMD2_HWTRIG (1 << 1)
+#define CMD2_SWTRIG (1 << 2)
+#define CMD2_TBSEL (1 << 3)
+#define CMD2_2SDAC0 (1 << 4)
+#define CMD2_2SDAC1 (1 << 5)
+#define CMD2_LDAC(x) (1 << (6 + (x)))
+#define CMD3_REG 0x02 /* W: Command 3 reg */
+#define CMD3_DMAEN (1 << 0)
+#define CMD3_DIOINTEN (1 << 1)
+#define CMD3_DMATCINTEN (1 << 2)
+#define CMD3_CNTINTEN (1 << 3)
+#define CMD3_ERRINTEN (1 << 4)
+#define CMD3_FIFOINTEN (1 << 5)
+#define ADC_START_CONVERT_REG 0x03 /* W: Start Convert reg */
+#define DAC_LSB_REG(x) (0x04 + 2 * (x)) /* W: DAC0/1 LSB reg */
+#define DAC_MSB_REG(x) (0x05 + 2 * (x)) /* W: DAC0/1 MSB reg */
+#define ADC_FIFO_CLEAR_REG 0x08 /* W: A/D FIFO Clear reg */
+#define ADC_FIFO_REG 0x0a /* R: A/D FIFO reg */
+#define DMATC_CLEAR_REG 0x0a /* W: DMA Interrupt Clear reg */
+#define TIMER_CLEAR_REG 0x0c /* W: Timer Interrupt Clear reg */
+#define CMD6_REG 0x0e /* W: Command 6 reg */
+#define CMD6_NRSE (1 << 0)
+#define CMD6_ADCUNI (1 << 1)
+#define CMD6_DACUNI(x) (1 << (2 + (x)))
+#define CMD6_HFINTEN (1 << 5)
+#define CMD6_DQINTEN (1 << 6)
+#define CMD6_SCANUP (1 << 7)
+#define CMD4_REG 0x0f /* W: Command 3 reg */
+#define CMD4_INTSCAN (1 << 0)
+#define CMD4_EOIRCV (1 << 1)
+#define CMD4_ECLKDRV (1 << 2)
+#define CMD4_SEDIFF (1 << 3)
+#define CMD4_ECLKRCV (1 << 4)
+#define DIO_BASE_REG 0x10 /* R/W: 8255 DIO base reg */
+#define COUNTER_A_BASE_REG 0x14 /* R/W: 8253 Counter A base reg */
+#define COUNTER_B_BASE_REG 0x18 /* R/W: 8253 Counter B base reg */
+#define CMD5_REG 0x1c /* W: Command 5 reg */
+#define CMD5_WRTPRT (1 << 2)
+#define CMD5_DITHEREN (1 << 3)
+#define CMD5_CALDACLD (1 << 4)
+#define CMD5_SCLK (1 << 5)
+#define CMD5_SDATA (1 << 6)
+#define CMD5_EEPROMCS (1 << 7)
+#define STAT2_REG 0x1d /* R: Status 2 reg */
+#define STAT2_PROMOUT (1 << 0)
+#define STAT2_OUTA1 (1 << 1)
+#define STAT2_FIFONHF (1 << 2)
+#define INTERVAL_COUNT_REG 0x1e /* W: Interval Counter Data reg */
+#define INTERVAL_STROBE_REG 0x1f /* W: Interval Counter Strobe reg */
+
+#define LABPC_SIZE 0x20 /* size of ISA io region */
+#define LABPC_TIMER_BASE 500 /* 2 MHz master clock */
+#define LABPC_ADC_TIMEOUT 1000
enum scan_mode {
MODE_SINGLE_CHAN,
@@ -215,187 +153,63 @@ enum scan_mode {
MODE_MULT_CHAN_DOWN,
};
-static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-static irqreturn_t labpc_interrupt(int irq, void *d);
-static int labpc_drain_fifo(struct comedi_device *dev);
-#ifdef CONFIG_ISA_DMA_API
-static void labpc_drain_dma(struct comedi_device *dev);
-static void handle_isa_dma(struct comedi_device *dev);
-#endif
-static void labpc_drain_dregs(struct comedi_device *dev);
-static int labpc_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int labpc_calib_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int labpc_calib_write_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int labpc_eeprom_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int labpc_eeprom_write_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
- enum scan_mode scan_mode);
-#ifdef CONFIG_ISA_DMA_API
-static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd);
-#endif
-static int labpc_dio_mem_callback(int dir, int port, int data,
- unsigned long arg);
-static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
- unsigned int num_bits);
-static unsigned int labpc_serial_in(struct comedi_device *dev);
-static unsigned int labpc_eeprom_read(struct comedi_device *dev,
- unsigned int address);
-static unsigned int labpc_eeprom_read_status(struct comedi_device *dev);
-static int labpc_eeprom_write(struct comedi_device *dev,
- unsigned int address,
- unsigned int value);
-static void write_caldac(struct comedi_device *dev, unsigned int channel,
- unsigned int value);
-
-/* analog input ranges */
-#define NUM_LABPC_PLUS_AI_RANGES 16
-/* indicates unipolar ranges */
-static const int labpc_plus_is_unipolar[NUM_LABPC_PLUS_AI_RANGES] = {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
-};
-
-/* map range index to gain bits */
-static const int labpc_plus_ai_gain_bits[NUM_LABPC_PLUS_AI_RANGES] = {
- 0x00,
- 0x10,
- 0x20,
- 0x30,
- 0x40,
- 0x50,
- 0x60,
- 0x70,
- 0x00,
- 0x10,
- 0x20,
- 0x30,
- 0x40,
- 0x50,
- 0x60,
- 0x70,
+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 = {
- NUM_LABPC_PLUS_AI_RANGES,
- {
- 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),
- }
+ 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)
+ }
};
-#define NUM_LABPC_1200_AI_RANGES 14
-/* indicates unipolar ranges */
-const int labpc_1200_is_unipolar[NUM_LABPC_1200_AI_RANGES] = {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
-};
-EXPORT_SYMBOL_GPL(labpc_1200_is_unipolar);
-
-/* map range index to gain bits */
-const int labpc_1200_ai_gain_bits[NUM_LABPC_1200_AI_RANGES] = {
- 0x00,
- 0x20,
- 0x30,
- 0x40,
- 0x50,
- 0x60,
- 0x70,
- 0x00,
- 0x20,
- 0x30,
- 0x40,
- 0x50,
- 0x60,
- 0x70,
+const int labpc_1200_ai_gain_bits[] = {
+ 0x00, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x00, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
};
EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
const struct comedi_lrange range_labpc_1200_ai = {
- NUM_LABPC_1200_AI_RANGES,
- {
- BIP_RANGE(5),
- 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(5),
- UNI_RANGE(2),
- UNI_RANGE(1),
- UNI_RANGE(0.5),
- UNI_RANGE(0.2),
- UNI_RANGE(0.1),
- }
+ 14, {
+ BIP_RANGE(5),
+ 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(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1)
+ }
};
EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
-/* analog output ranges */
-#define AO_RANGE_IS_UNIPOLAR 0x1
static const struct comedi_lrange range_labpc_ao = {
- 2,
- {
- BIP_RANGE(5),
- UNI_RANGE(10),
- }
+ 2, {
+ BIP_RANGE(5),
+ UNI_RANGE(10)
+ }
};
/* functions that do inb/outb and readb/writeb so we can use
@@ -420,413 +234,417 @@ static inline void labpc_writeb(unsigned int byte, unsigned long address)
writeb(byte, (void __iomem *)address);
}
-static const struct labpc_board_struct 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,
- .memory_mapped_io = 0,
- },
+#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISA)
+static const struct labpc_boardinfo labpc_boards[] = {
{
- .name = "lab-pc-1200ai",
- .ai_speed = 10000,
- .bustype = isa_bustype,
- .register_layout = labpc_1200_layout,
- .has_ao = 0,
- .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 = 0,
- },
- {
- .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,
- .ai_scan_up = 0,
- .memory_mapped_io = 0,
- },
-#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,
- },
-/* dummy entry so pci board works when comedi_config is passed driver name */
- {
- .name = DRV_NAME,
- .bustype = pci_bustype,
- },
-#endif
+ .name = "lab-pc-1200",
+ .ai_speed = 10000,
+ .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,
+ }, {
+ .name = "lab-pc-1200ai",
+ .ai_speed = 10000,
+ .register_layout = labpc_1200_layout,
+ .ai_range_table = &range_labpc_1200_ai,
+ .ai_range_code = labpc_1200_ai_gain_bits,
+ .ai_scan_up = 1,
+ }, {
+ .name = "lab-pc+",
+ .ai_speed = 12000,
+ .register_layout = labpc_plus_layout,
+ .has_ao = 1,
+ .ai_range_table = &range_labpc_plus_ai,
+ .ai_range_code = labpc_plus_ai_gain_bits,
+ },
};
-
-/*
- * Useful for shorthand access to the particular board structure
- */
-#define thisboard ((struct labpc_board_struct *)dev->board_ptr)
+#endif
/* size in bytes of dma buffer */
static const int dma_buffer_size = 0xff00;
/* 2 bytes per sample */
static const int sample_size = 2;
-static inline int labpc_counter_load(struct comedi_device *dev,
- unsigned long base_address,
- unsigned int counter_number,
- unsigned int count, unsigned int mode)
+static int labpc_counter_load(struct comedi_device *dev,
+ unsigned long base_address,
+ unsigned int counter_number,
+ unsigned int count, unsigned int mode)
{
- if (thisboard->memory_mapped_io)
+ const struct labpc_boardinfo *board = comedi_board(dev);
+
+ if (board->has_mmio)
return i8254_mm_load((void __iomem *)base_address, 0,
counter_number, count, mode);
else
return i8254_load(base_address, 0, counter_number, count, mode);
}
-int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
- unsigned int irq, unsigned int dma_chan)
+static int labpc_counter_set_mode(struct comedi_device *dev,
+ unsigned long base_address,
+ unsigned int counter_number,
+ unsigned int mode)
+{
+ const struct labpc_boardinfo *board = comedi_board(dev);
+
+ if (board->has_mmio)
+ return i8254_mm_set_mode((void __iomem *)base_address, 0,
+ counter_number, mode);
+ else
+ return i8254_set_mode(base_address, 0, counter_number, mode);
+}
+
+static bool labpc_range_is_unipolar(struct comedi_subdevice *s,
+ unsigned int range)
+{
+ return s->range_table->range[range].min >= 0;
+}
+
+static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
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;
+ unsigned long flags;
- 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;
+ spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
+ devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ spin_unlock_irqrestore(&dev->spinlock, flags);
- if (thisboard->memory_mapped_io) {
- devpriv->read_byte = labpc_readb;
- devpriv->write_byte = labpc_writeb;
- } else {
- devpriv->read_byte = labpc_inb;
- devpriv->write_byte = labpc_outb;
- }
- /* initialize board's command registers */
- devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
- devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
- devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
- devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
- if (thisboard->register_layout == labpc_1200_layout) {
- devpriv->write_byte(devpriv->command5_bits,
- dev->iobase + COMMAND5_REG);
- devpriv->write_byte(devpriv->command6_bits,
- dev->iobase + COMMAND6_REG);
- }
+ devpriv->cmd3 = 0;
+ devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_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;
+ return 0;
+}
-#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;
+static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
+ enum scan_mode mode,
+ unsigned int chan,
+ unsigned int range,
+ unsigned int aref)
+{
+ const struct labpc_boardinfo *board = comedi_board(dev);
+ struct labpc_private *devpriv = dev->private;
- 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);
- }
-#endif
+ /* munge channel bits for differential/scan disabled mode */
+ if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
+ aref == AREF_DIFF)
+ chan *= 2;
+ devpriv->cmd1 = CMD1_MA(chan);
+ devpriv->cmd1 |= board->ai_range_code[range];
- dev->board_name = thisboard->name;
+ devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
+}
- ret = comedi_alloc_subdevices(dev, 5);
- if (ret)
- return ret;
+static void labpc_setup_cmd6_reg(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ enum scan_mode mode,
+ enum transfer_type xfer,
+ unsigned int range,
+ unsigned int aref,
+ bool ena_intr)
+{
+ const struct labpc_boardinfo *board = comedi_board(dev);
+ struct labpc_private *devpriv = dev->private;
- /* analog input subdevice */
- s = &dev->subdevices[0];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags =
- SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
- s->n_chan = 8;
- s->len_chanlist = 8;
- s->maxdata = (1 << 12) - 1; /* 12 bit resolution */
- s->range_table = thisboard->ai_range_table;
- s->do_cmd = labpc_ai_cmd;
- s->do_cmdtest = labpc_ai_cmdtest;
- s->insn_read = labpc_ai_rinsn;
- s->cancel = labpc_cancel;
+ if (board->register_layout != labpc_1200_layout)
+ return;
- /* analog output */
- s = &dev->subdevices[1];
- if (thisboard->has_ao) {
- /*
- * Could provide command support, except it only has a
- * one sample hardware buffer for analog output and no
- * underrun flag.
- */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
- s->n_chan = NUM_AO_CHAN;
- s->maxdata = (1 << 12) - 1; /* 12 bit resolution */
- s->range_table = &range_labpc_ao;
- s->insn_read = labpc_ao_rinsn;
- s->insn_write = labpc_ao_winsn;
- /* initialize analog outputs to a known value */
- for (i = 0; i < s->n_chan; i++) {
- devpriv->ao_value[i] = s->maxdata / 2;
- lsb = devpriv->ao_value[i] & 0xff;
- msb = (devpriv->ao_value[i] >> 8) & 0xff;
- devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
- devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
- }
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
+ /* reference inputs to ground or common? */
+ if (aref != AREF_GROUND)
+ devpriv->cmd6 |= CMD6_NRSE;
+ else
+ devpriv->cmd6 &= ~CMD6_NRSE;
- /* 8255 dio */
- s = &dev->subdevices[2];
- /* if board uses io memory we have to give a custom callback
- * function to the 8255 driver */
- if (thisboard->memory_mapped_io)
- subdev_8255_init(dev, s, labpc_dio_mem_callback,
- (unsigned long)(dev->iobase + DIO_BASE_REG));
+ /* bipolar or unipolar range? */
+ if (labpc_range_is_unipolar(s, range))
+ devpriv->cmd6 |= CMD6_ADCUNI;
else
- subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
+ devpriv->cmd6 &= ~CMD6_ADCUNI;
- /* calibration subdevices for boards that have one */
- s = &dev->subdevices[3];
- if (thisboard->register_layout == labpc_1200_layout) {
- s->type = COMEDI_SUBD_CALIB;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 16;
- s->maxdata = 0xff;
- s->insn_read = labpc_calib_read_insn;
- s->insn_write = labpc_calib_write_insn;
+ /* interrupt on fifo half full? */
+ if (xfer == fifo_half_full_transfer)
+ devpriv->cmd6 |= CMD6_HFINTEN;
+ else
+ devpriv->cmd6 &= ~CMD6_HFINTEN;
- for (i = 0; i < s->n_chan; i++)
- write_caldac(dev, i, s->maxdata / 2);
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ /* enable interrupt on counter a1 terminal count? */
+ if (ena_intr)
+ devpriv->cmd6 |= CMD6_DQINTEN;
+ else
+ devpriv->cmd6 &= ~CMD6_DQINTEN;
- /* EEPROM */
- s = &dev->subdevices[4];
- if (thisboard->register_layout == labpc_1200_layout) {
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = EEPROM_SIZE;
- s->maxdata = 0xff;
- s->insn_read = labpc_eeprom_read_insn;
- s->insn_write = labpc_eeprom_write_insn;
-
- for (i = 0; i < EEPROM_SIZE; i++)
- devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
- } else
- s->type = COMEDI_SUBD_UNUSED;
+ /* are we scanning up or down through channels? */
+ if (mode == MODE_MULT_CHAN_UP)
+ devpriv->cmd6 |= CMD6_SCANUP;
+ else
+ devpriv->cmd6 &= ~CMD6_SCANUP;
- return 0;
+ devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
}
-EXPORT_SYMBOL_GPL(labpc_common_attach);
-static const struct labpc_board_struct *
-labpc_pci_find_boardinfo(struct pci_dev *pcidev)
+static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
+{
+ struct labpc_private *devpriv = dev->private;
+ unsigned int lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ unsigned int msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+
+ return (msb << 8) | lsb;
+}
+
+static void labpc_clear_adc_fifo(struct comedi_device *dev)
+{
+ struct labpc_private *devpriv = dev->private;
+
+ devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ labpc_read_adc_fifo(dev);
+}
+
+static int labpc_ai_wait_for_data(struct comedi_device *dev,
+ int timeout)
{
- unsigned int device_id = pcidev->device;
- unsigned int n;
-
- for (n = 0; n < ARRAY_SIZE(labpc_boards); n++) {
- const struct labpc_board_struct *board = &labpc_boards[n];
- if (board->bustype == pci_bustype &&
- board->device_id == device_id)
- return board;
+ struct labpc_private *devpriv = dev->private;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ if (devpriv->stat1 & STAT1_DAVAIL)
+ return 0;
+ udelay(1);
}
- return NULL;
+ return -ETIME;
}
-static int labpc_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+static int labpc_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct labpc_private *devpriv;
- unsigned long iobase;
- unsigned int irq;
+ struct labpc_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int aref = CR_AREF(insn->chanspec);
int ret;
+ int i;
- if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS))
- return -ENODEV;
+ /* disable timed conversions, interrupt generation and dma */
+ labpc_cancel(dev, s);
- devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
- if (!devpriv)
- return -ENOMEM;
- dev->private = devpriv;
+ labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref);
- 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)
+ labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer,
+ range, aref, false);
+
+ /* setup cmd4 register */
+ devpriv->cmd4 = 0;
+ devpriv->cmd4 |= CMD4_ECLKRCV;
+ /* single-ended/differential */
+ if (aref == AREF_DIFF)
+ devpriv->cmd4 |= CMD4_SEDIFF;
+ devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+
+ /* initialize pacer counter to prevent any problems */
+ ret = labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 0, I8254_MODE2);
+ if (ret)
return ret;
- iobase = (unsigned long)devpriv->mite->daq_io_addr;
- irq = mite_irq(devpriv->mite);
- return labpc_common_attach(dev, iobase, irq, 0);
+
+ labpc_clear_adc_fifo(dev);
+
+ for (i = 0; i < insn->n; i++) {
+ /* trigger conversion */
+ devpriv->write_byte(0x1, dev->iobase + ADC_START_CONVERT_REG);
+
+ ret = labpc_ai_wait_for_data(dev, LABPC_ADC_TIMEOUT);
+ if (ret)
+ return ret;
+
+ data[i] = labpc_read_adc_fifo(dev);
+ }
+
+ return insn->n;
}
-static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+#ifdef CONFIG_ISA_DMA_API
+/* utility function that suggests a dma transfer size in bytes */
+static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
{
- struct labpc_private *devpriv;
- unsigned long iobase = 0;
- unsigned int irq = 0;
- unsigned int dma_chan = 0;
+ unsigned int size;
+ unsigned int freq;
- devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
- if (!devpriv)
- return -ENOMEM;
- dev->private = devpriv;
+ if (cmd->convert_src == TRIG_TIMER)
+ freq = 1000000000 / cmd->convert_arg;
+ /* return some default value */
+ else
+ freq = 0xffffffff;
- /* 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;
+ /* make buffer fill in no more than 1/3 second */
+ 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;
+ else if (size < sample_size)
+ size = sample_size;
+
+ return size;
+}
#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 bool labpc_use_continuous_mode(const struct comedi_cmd *cmd,
+ enum scan_mode mode)
+{
+ if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW)
+ return true;
+
+ return false;
}
-void labpc_common_detach(struct comedi_device *dev)
+static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
+ enum scan_mode mode)
{
- struct labpc_private *devpriv = dev->private;
- struct comedi_subdevice *s;
+ if (cmd->convert_src != TRIG_TIMER)
+ return 0;
+
+ if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
+ return cmd->scan_begin_arg;
- if (!thisboard)
+ return cmd->convert_arg;
+}
+
+static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
+ enum scan_mode mode, unsigned int ns)
+{
+ if (cmd->convert_src != TRIG_TIMER)
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->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);
- }
-#endif
-};
-EXPORT_SYMBOL_GPL(labpc_common_detach);
-static void labpc_clear_adc_fifo(const struct comedi_device *dev)
+ if (mode == MODE_SINGLE_CHAN &&
+ cmd->scan_begin_src == TRIG_TIMER) {
+ cmd->scan_begin_arg = ns;
+ if (cmd->convert_arg > cmd->scan_begin_arg)
+ cmd->convert_arg = cmd->scan_begin_arg;
+ } else
+ cmd->convert_arg = ns;
+}
+
+static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
+ enum scan_mode mode)
{
- struct labpc_private *devpriv = dev->private;
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return 0;
- devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
- devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
- devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
+ return 0;
+
+ return cmd->scan_begin_arg;
}
-static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
+ enum scan_mode mode, unsigned int ns)
+{
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return;
+
+ if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
+ return;
+
+ cmd->scan_begin_arg = ns;
+}
+
+/* figures out what counter values to use based on command */
+static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
+ enum scan_mode mode)
{
struct labpc_private *devpriv = dev->private;
- unsigned long flags;
+ /* max value for 16 bit counter in mode 2 */
+ const int max_counter_value = 0x10000;
+ /* min value for 16 bit counter in mode 2 */
+ const int min_counter_value = 2;
+ unsigned int base_period;
+ unsigned int scan_period;
+ unsigned int convert_period;
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
- devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
+ /*
+ * if both convert and scan triggers are TRIG_TIMER, then they
+ * both rely on counter b0
+ */
+ convert_period = labpc_ai_convert_period(cmd, mode);
+ scan_period = labpc_ai_scan_period(cmd, mode);
+ if (convert_period && scan_period) {
+ /*
+ * pick the lowest b0 divisor value we can (for maximum input
+ * clock speed on convert and scan counters)
+ */
+ devpriv->divisor_b0 = (scan_period - 1) /
+ (LABPC_TIMER_BASE * max_counter_value) + 1;
+ if (devpriv->divisor_b0 < min_counter_value)
+ devpriv->divisor_b0 = min_counter_value;
+ if (devpriv->divisor_b0 > max_counter_value)
+ devpriv->divisor_b0 = max_counter_value;
- devpriv->command3_bits = 0;
- devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+ base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
- return 0;
+ /* set a0 for conversion frequency and b1 for scan frequency */
+ switch (cmd->flags & TRIG_ROUND_MASK) {
+ default:
+ case TRIG_ROUND_NEAREST:
+ devpriv->divisor_a0 =
+ (convert_period + (base_period / 2)) / base_period;
+ devpriv->divisor_b1 =
+ (scan_period + (base_period / 2)) / base_period;
+ break;
+ case TRIG_ROUND_UP:
+ devpriv->divisor_a0 =
+ (convert_period + (base_period - 1)) / base_period;
+ devpriv->divisor_b1 =
+ (scan_period + (base_period - 1)) / base_period;
+ break;
+ case TRIG_ROUND_DOWN:
+ devpriv->divisor_a0 = convert_period / base_period;
+ devpriv->divisor_b1 = scan_period / base_period;
+ break;
+ }
+ /* make sure a0 and b1 values are acceptable */
+ if (devpriv->divisor_a0 < min_counter_value)
+ devpriv->divisor_a0 = min_counter_value;
+ if (devpriv->divisor_a0 > max_counter_value)
+ devpriv->divisor_a0 = max_counter_value;
+ if (devpriv->divisor_b1 < min_counter_value)
+ devpriv->divisor_b1 = min_counter_value;
+ if (devpriv->divisor_b1 > max_counter_value)
+ devpriv->divisor_b1 = max_counter_value;
+ /* write corrected timings to command */
+ labpc_set_ai_convert_period(cmd, mode,
+ base_period * devpriv->divisor_a0);
+ labpc_set_ai_scan_period(cmd, mode,
+ base_period * devpriv->divisor_b1);
+ /*
+ * if only one TRIG_TIMER is used, we can employ the generic
+ * cascaded timing functions
+ */
+ } else if (scan_period) {
+ /*
+ * calculate cascaded counter values
+ * that give desired scan timing
+ */
+ i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+ &(devpriv->divisor_b1),
+ &(devpriv->divisor_b0),
+ &scan_period,
+ cmd->flags & TRIG_ROUND_MASK);
+ labpc_set_ai_scan_period(cmd, mode, scan_period);
+ } else if (convert_period) {
+ /*
+ * calculate cascaded counter values
+ * that give desired conversion timing
+ */
+ i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+ &(devpriv->divisor_a0),
+ &(devpriv->divisor_b0),
+ &convert_period,
+ cmd->flags & TRIG_ROUND_MASK);
+ labpc_set_ai_convert_period(cmd, mode, convert_period);
+ }
}
static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
@@ -923,72 +741,10 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
return 0;
}
-static int labpc_use_continuous_mode(const struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- if (mode == MODE_SINGLE_CHAN)
- return 1;
-
- if (cmd->scan_begin_src == TRIG_FOLLOW)
- return 1;
-
- return 0;
-}
-
-static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- if (cmd->convert_src != TRIG_TIMER)
- return 0;
-
- if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
- return cmd->scan_begin_arg;
-
- return cmd->convert_arg;
-}
-
-static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
- enum scan_mode mode, unsigned int ns)
-{
- if (cmd->convert_src != TRIG_TIMER)
- return;
-
- if (mode == MODE_SINGLE_CHAN &&
- cmd->scan_begin_src == TRIG_TIMER) {
- cmd->scan_begin_arg = ns;
- if (cmd->convert_arg > cmd->scan_begin_arg)
- cmd->convert_arg = cmd->scan_begin_arg;
- } else
- cmd->convert_arg = ns;
-}
-
-static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- if (cmd->scan_begin_src != TRIG_TIMER)
- return 0;
-
- if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
- return 0;
-
- return cmd->scan_begin_arg;
-}
-
-static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
- enum scan_mode mode, unsigned int ns)
-{
- if (cmd->scan_begin_src != TRIG_TIMER)
- return;
-
- if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
- return;
-
- cmd->scan_begin_arg = ns;
-}
-
static int labpc_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
+ const struct labpc_boardinfo *board = comedi_board(dev);
int err = 0;
int tmp, tmp2;
unsigned int stop_mask;
@@ -1003,7 +759,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
stop_mask = TRIG_COUNT | TRIG_NONE;
- if (thisboard->register_layout == labpc_1200_layout)
+ if (board->register_layout == labpc_1200_layout)
stop_mask |= TRIG_EXT;
err |= cfc_check_trigger_src(&cmd->stop_src, stop_mask);
@@ -1037,7 +793,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
if (cmd->convert_src == TRIG_TIMER)
err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
- thisboard->ai_speed);
+ board->ai_speed);
/* make sure scan timing is not too fast */
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -1045,7 +801,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
cmd->convert_arg * cmd->chanlist_len);
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
- thisboard->ai_speed * cmd->chanlist_len);
+ board->ai_speed * cmd->chanlist_len);
}
switch (cmd->stop_src) {
@@ -1086,34 +842,23 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct labpc_boardinfo *board = comedi_board(dev);
struct labpc_private *devpriv = dev->private;
- int channel, range, aref;
-#ifdef CONFIG_ISA_DMA_API
- unsigned long irq_flags;
-#endif
- int ret;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
+ enum scan_mode mode = labpc_ai_scan_mode(cmd);
+ unsigned int chanspec = (mode == MODE_MULT_CHAN_UP)
+ ? cmd->chanlist[cmd->chanlist_len - 1]
+ : cmd->chanlist[0];
+ unsigned int chan = CR_CHAN(chanspec);
+ unsigned int range = CR_RANGE(chanspec);
+ unsigned int aref = CR_AREF(chanspec);
enum transfer_type xfer;
- enum scan_mode mode;
unsigned long flags;
-
- if (!dev->irq) {
- comedi_error(dev, "no irq assigned, cannot perform command");
- return -1;
- }
-
- range = CR_RANGE(cmd->chanlist[0]);
- aref = CR_AREF(cmd->chanlist[0]);
+ int ret;
/* make sure board is disabled before setting up acquisition */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
- devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- devpriv->command3_bits = 0;
- devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+ labpc_cancel(dev, s);
/* initialize software conversion count */
if (cmd->stop_src == TRIG_COUNT)
@@ -1126,17 +871,17 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* (pc+ manual says this is minimum allowed) using mode 0
*/
ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
- 1, 3, 0);
- if (ret < 0) {
- comedi_error(dev, "error loading counter a1");
- return -1;
- }
- } else /*
- * otherwise, just put a1 in mode 0
- * with no count to set its output low
- */
- devpriv->write_byte(INIT_A1_BITS,
- dev->iobase + COUNTER_A_CONTROL_REG);
+ 1, 3, I8254_MODE0);
+ } else {
+ /* just put counter a1 in mode 0 to set its output low */
+ ret = labpc_counter_set_mode(dev,
+ dev->iobase + COUNTER_A_BASE_REG,
+ 1, I8254_MODE0);
+ }
+ if (ret) {
+ comedi_error(dev, "error loading counter a1");
+ return ret;
+ }
#ifdef CONFIG_ISA_DMA_API
/* figure out what method we will use to transfer data */
@@ -1145,14 +890,12 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* dma unsafe at RT priority,
* and too much setup time for TRIG_WAKE_EOS for
*/
- (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0 &&
- /* only available on the isa boards */
- thisboard->bustype == isa_bustype) {
+ (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0) {
xfer = isa_dma_transfer;
/* pc-plus has no fifo-half full interrupt */
} else
#endif
- if (thisboard->register_layout == labpc_1200_layout &&
+ if (board->register_layout == labpc_1200_layout &&
/* wake-end-of-scan should interrupt on fifo not empty */
(cmd->flags & TRIG_WAKE_EOS) == 0 &&
/* make sure we are taking more than just a few points */
@@ -1161,76 +904,34 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
} else
xfer = fifo_not_empty_transfer;
devpriv->current_transfer = xfer;
- mode = labpc_ai_scan_mode(cmd);
- /* setup command6 register for 1200 boards */
- if (thisboard->register_layout == labpc_1200_layout) {
- /* reference inputs to ground or common? */
- if (aref != AREF_GROUND)
- devpriv->command6_bits |= ADC_COMMON_BIT;
- else
- devpriv->command6_bits &= ~ADC_COMMON_BIT;
- /* bipolar or unipolar range? */
- if (thisboard->ai_range_is_unipolar[range])
- devpriv->command6_bits |= ADC_UNIP_BIT;
- else
- devpriv->command6_bits &= ~ADC_UNIP_BIT;
- /* interrupt on fifo half full? */
- if (xfer == fifo_half_full_transfer)
- devpriv->command6_bits |= ADC_FHF_INTR_EN_BIT;
- else
- devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
- /* enable interrupt on counter a1 terminal count? */
- if (cmd->stop_src == TRIG_EXT)
- devpriv->command6_bits |= A1_INTR_EN_BIT;
- else
- devpriv->command6_bits &= ~A1_INTR_EN_BIT;
- /* are we scanning up or down through channels? */
- if (mode == MODE_MULT_CHAN_UP)
- devpriv->command6_bits |= ADC_SCAN_UP_BIT;
- else
- devpriv->command6_bits &= ~ADC_SCAN_UP_BIT;
- /* write to register */
- devpriv->write_byte(devpriv->command6_bits,
- dev->iobase + COMMAND6_REG);
- }
+ labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);
+
+ labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
+ (cmd->stop_src == TRIG_EXT));
- /* setup channel list, etc (command1 register) */
- devpriv->command1_bits = 0;
- if (mode == MODE_MULT_CHAN_UP)
- channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
- else
- channel = CR_CHAN(cmd->chanlist[0]);
- /* munge channel bits for differential / scan disabled mode */
- if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
- aref == AREF_DIFF)
- channel *= 2;
- devpriv->command1_bits |= ADC_CHAN_BITS(channel);
- devpriv->command1_bits |= thisboard->ai_range_code[range];
- devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
/* manual says to set scan enable bit on second pass */
if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
- devpriv->command1_bits |= ADC_SCAN_EN_BIT;
+ devpriv->cmd1 |= CMD1_SCANEN;
/* need a brief delay before enabling scan, or scan
* list will get screwed when you switch
* between scan up to scan down mode - dunno why */
udelay(1);
- devpriv->write_byte(devpriv->command1_bits,
- dev->iobase + COMMAND1_REG);
+ devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
}
devpriv->write_byte(cmd->chanlist_len,
dev->iobase + INTERVAL_COUNT_REG);
/* load count */
- devpriv->write_byte(INTERVAL_LOAD_BITS,
- dev->iobase + INTERVAL_LOAD_REG);
+ devpriv->write_byte(0x1, dev->iobase + INTERVAL_STROBE_REG);
- if (cmd->convert_src == TRIG_TIMER || cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->convert_src == TRIG_TIMER ||
+ cmd->scan_begin_src == TRIG_TIMER) {
/* set up pacing */
labpc_adc_timing(dev, cmd, mode);
/* load counter b0 in mode 3 */
ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
- 0, devpriv->divisor_b0, 3);
+ 0, devpriv->divisor_b0, I8254_MODE3);
if (ret < 0) {
comedi_error(dev, "error loading counter b0");
return -1;
@@ -1240,20 +941,23 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (labpc_ai_convert_period(cmd, mode)) {
/* load counter a0 in mode 2 */
ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, devpriv->divisor_a0, 2);
- if (ret < 0) {
- comedi_error(dev, "error loading counter a0");
- return -1;
- }
- } else
- devpriv->write_byte(INIT_A0_BITS,
- dev->iobase + COUNTER_A_CONTROL_REG);
+ 0, devpriv->divisor_a0, I8254_MODE2);
+ } else {
+ /* initialize pacer counter to prevent any problems */
+ ret = labpc_counter_set_mode(dev,
+ dev->iobase + COUNTER_A_BASE_REG,
+ 0, I8254_MODE2);
+ }
+ if (ret) {
+ comedi_error(dev, "error loading counter a0");
+ return ret;
+ }
/* set up scan pacing */
if (labpc_ai_scan_period(cmd, mode)) {
/* load counter b1 in mode 2 */
ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
- 1, devpriv->divisor_b1, 2);
+ 1, devpriv->divisor_b1, I8254_MODE2);
if (ret < 0) {
comedi_error(dev, "error loading counter b1");
return -1;
@@ -1265,6 +969,8 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
#ifdef CONFIG_ISA_DMA_API
/* set up dma transfer */
if (xfer == isa_dma_transfer) {
+ unsigned long irq_flags;
+
irq_flags = claim_dma_lock();
disable_dma(devpriv->dma_chan);
/* clear flip-flop to make sure 2-byte registers for
@@ -1283,197 +989,54 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
enable_dma(devpriv->dma_chan);
release_dma_lock(irq_flags);
/* enable board's dma */
- devpriv->command3_bits |= DMA_EN_BIT | DMATC_INTR_EN_BIT;
+ devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN);
} else
- devpriv->command3_bits &= ~DMA_EN_BIT & ~DMATC_INTR_EN_BIT;
+ devpriv->cmd3 &= ~(CMD3_DMAEN | CMD3_DMATCINTEN);
#endif
/* enable error interrupts */
- devpriv->command3_bits |= ERR_INTR_EN_BIT;
+ devpriv->cmd3 |= CMD3_ERRINTEN;
/* enable fifo not empty interrupt? */
if (xfer == fifo_not_empty_transfer)
- devpriv->command3_bits |= ADC_FNE_INTR_EN_BIT;
+ devpriv->cmd3 |= CMD3_FIFOINTEN;
else
- devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT;
- devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+ devpriv->cmd3 &= ~CMD3_FIFOINTEN;
+ devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
- /* setup any external triggering/pacing (command4 register) */
- devpriv->command4_bits = 0;
+ /* setup any external triggering/pacing (cmd4 register) */
+ devpriv->cmd4 = 0;
if (cmd->convert_src != TRIG_EXT)
- devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+ devpriv->cmd4 |= CMD4_ECLKRCV;
/* XXX should discard first scan when using interval scanning
* since manual says it is not synced with scan clock */
- if (labpc_use_continuous_mode(cmd, mode) == 0) {
- devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
+ if (!labpc_use_continuous_mode(cmd, mode)) {
+ devpriv->cmd4 |= CMD4_INTSCAN;
if (cmd->scan_begin_src == TRIG_EXT)
- devpriv->command4_bits |= EXT_SCAN_EN_BIT;
+ devpriv->cmd4 |= CMD4_EOIRCV;
}
/* single-ended/differential */
if (aref == AREF_DIFF)
- devpriv->command4_bits |= ADC_DIFF_BIT;
- devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+ devpriv->cmd4 |= CMD4_SEDIFF;
+ devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
/* startup acquisition */
- /* command2 reg */
- /* use 2 cascaded counters for pacing */
spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->command2_bits |= CASCADE_BIT;
- switch (cmd->start_src) {
- case TRIG_EXT:
- devpriv->command2_bits |= HWTRIG_BIT;
- devpriv->command2_bits &= ~PRETRIG_BIT & ~SWTRIG_BIT;
- break;
- case TRIG_NOW:
- devpriv->command2_bits |= SWTRIG_BIT;
- devpriv->command2_bits &= ~PRETRIG_BIT & ~HWTRIG_BIT;
- break;
- default:
- comedi_error(dev, "bug with start_src");
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return -1;
- break;
- }
- switch (cmd->stop_src) {
- case TRIG_EXT:
- devpriv->command2_bits |= HWTRIG_BIT | PRETRIG_BIT;
- break;
- case TRIG_COUNT:
- case TRIG_NONE:
- break;
- default:
- comedi_error(dev, "bug with stop_src");
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return -1;
- }
- devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return 0;
-}
-
-/* interrupt service routine */
-static irqreturn_t labpc_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct labpc_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- struct comedi_async *async;
- struct comedi_cmd *cmd;
-
- if (dev->attached == 0) {
- comedi_error(dev, "premature interrupt");
- return IRQ_HANDLED;
- }
-
- async = s->async;
- cmd = &async->cmd;
- async->events = 0;
-
- /* read board status */
- devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
- if (thisboard->register_layout == labpc_1200_layout)
- devpriv->status2_bits =
- devpriv->read_byte(dev->iobase + STATUS2_REG);
-
- if ((devpriv->status1_bits & (DMATC_BIT | TIMER_BIT | OVERFLOW_BIT |
- OVERRUN_BIT | DATA_AVAIL_BIT)) == 0
- && (devpriv->status2_bits & A1_TC_BIT) == 0
- && (devpriv->status2_bits & FNHF_BIT)) {
- return IRQ_NONE;
- }
-
- if (devpriv->status1_bits & OVERRUN_BIT) {
- /* clear error interrupt */
- devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
- async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s);
- comedi_error(dev, "overrun");
- return IRQ_HANDLED;
- }
-
-#ifdef CONFIG_ISA_DMA_API
- if (devpriv->current_transfer == isa_dma_transfer) {
- /*
- * if a dma terminal count of external stop trigger
- * has occurred
- */
- if (devpriv->status1_bits & DMATC_BIT ||
- (thisboard->register_layout == labpc_1200_layout
- && devpriv->status2_bits & A1_TC_BIT)) {
- handle_isa_dma(dev);
- }
- } else
-#endif
- labpc_drain_fifo(dev);
-
- if (devpriv->status1_bits & TIMER_BIT) {
- comedi_error(dev, "handled timer interrupt?");
- /* clear it */
- devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
- }
-
- if (devpriv->status1_bits & OVERFLOW_BIT) {
- /* clear error interrupt */
- devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
- async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- comedi_event(dev, s);
- comedi_error(dev, "overflow");
- return IRQ_HANDLED;
- }
- /* handle external stop trigger */
- if (cmd->stop_src == TRIG_EXT) {
- if (devpriv->status2_bits & A1_TC_BIT) {
- labpc_drain_dregs(dev);
- labpc_cancel(dev, s);
- async->events |= COMEDI_CB_EOA;
- }
- }
-
- /* TRIG_COUNT end of acquisition */
- if (cmd->stop_src == TRIG_COUNT) {
- if (devpriv->count == 0) {
- labpc_cancel(dev, s);
- async->events |= COMEDI_CB_EOA;
- }
- }
- comedi_event(dev, s);
- return IRQ_HANDLED;
-}
+ /* use 2 cascaded counters for pacing */
+ devpriv->cmd2 |= CMD2_TBSEL;
-/* read all available samples from ai fifo */
-static int labpc_drain_fifo(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int lsb, msb;
- short data;
- struct comedi_async *async = dev->read_subdev->async;
- const int timeout = 10000;
- unsigned int i;
+ devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
+ if (cmd->start_src == TRIG_EXT)
+ devpriv->cmd2 |= CMD2_HWTRIG;
+ else
+ devpriv->cmd2 |= CMD2_SWTRIG;
+ if (cmd->stop_src == TRIG_EXT)
+ devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
- devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+ devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
- for (i = 0; (devpriv->status1_bits & DATA_AVAIL_BIT) && i < timeout;
- i++) {
- /* quit if we have all the data we want */
- if (async->cmd.stop_src == TRIG_COUNT) {
- if (devpriv->count == 0)
- break;
- devpriv->count--;
- }
- lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
- msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
- data = (msb << 8) | lsb;
- cfc_write_to_buffer(dev->read_subdev, data);
- devpriv->status1_bits =
- devpriv->read_byte(dev->iobase + STATUS1_REG);
- }
- if (i == timeout) {
- comedi_error(dev, "ai timeout, fifo never empties");
- async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- return -1;
- }
+ spin_unlock_irqrestore(&dev->spinlock, flags);
return 0;
}
@@ -1489,7 +1052,7 @@ static void labpc_drain_dma(struct comedi_device *dev)
unsigned int max_points, num_points, residue, leftover;
int i;
- status = devpriv->status1_bits;
+ status = devpriv->stat1;
flags = claim_dma_lock();
disable_dma(devpriv->dma_chan);
@@ -1546,6 +1109,38 @@ static void handle_isa_dma(struct comedi_device *dev)
}
#endif
+/* read all available samples from ai fifo */
+static int labpc_drain_fifo(struct comedi_device *dev)
+{
+ struct labpc_private *devpriv = dev->private;
+ short data;
+ struct comedi_async *async = dev->read_subdev->async;
+ const int timeout = 10000;
+ unsigned int i;
+
+ devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+
+ for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
+ i++) {
+ /* quit if we have all the data we want */
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (devpriv->count == 0)
+ break;
+ devpriv->count--;
+ }
+ data = labpc_read_adc_fifo(dev);
+ cfc_write_to_buffer(dev->read_subdev, data);
+ devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "ai timeout, fifo never empties");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ return -1;
+ }
+
+ return 0;
+}
+
/* makes sure all data acquired by board is transferred to comedi (used
* when acquisition is terminated by stop_src == TRIG_EXT). */
static void labpc_drain_dregs(struct comedi_device *dev)
@@ -1560,99 +1155,102 @@ static void labpc_drain_dregs(struct comedi_device *dev)
labpc_drain_fifo(dev);
}
-static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+/* interrupt service routine */
+static irqreturn_t labpc_interrupt(int irq, void *d)
{
+ struct comedi_device *dev = d;
+ const struct labpc_boardinfo *board = comedi_board(dev);
struct labpc_private *devpriv = dev->private;
- int i, n;
- int chan, range;
- int lsb, msb;
- int timeout = 1000;
- unsigned long flags;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
- /* disable timed conversions */
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
- devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
- spin_unlock_irqrestore(&dev->spinlock, flags);
+ if (!dev->attached) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
- /* disable interrupt generation and dma */
- devpriv->command3_bits = 0;
- devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+ async = s->async;
+ cmd = &async->cmd;
+ async->events = 0;
- /* set gain and channel */
- devpriv->command1_bits = 0;
- chan = CR_CHAN(insn->chanspec);
- range = CR_RANGE(insn->chanspec);
- devpriv->command1_bits |= thisboard->ai_range_code[range];
- /* munge channel bits for differential/scan disabled mode */
- if (CR_AREF(insn->chanspec) == AREF_DIFF)
- chan *= 2;
- devpriv->command1_bits |= ADC_CHAN_BITS(chan);
- devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
-
- /* setup command6 register for 1200 boards */
- if (thisboard->register_layout == labpc_1200_layout) {
- /* reference inputs to ground or common? */
- if (CR_AREF(insn->chanspec) != AREF_GROUND)
- devpriv->command6_bits |= ADC_COMMON_BIT;
- else
- devpriv->command6_bits &= ~ADC_COMMON_BIT;
- /* bipolar or unipolar range? */
- if (thisboard->ai_range_is_unipolar[range])
- devpriv->command6_bits |= ADC_UNIP_BIT;
- else
- devpriv->command6_bits &= ~ADC_UNIP_BIT;
- /* don't interrupt on fifo half full */
- devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
- /* don't enable interrupt on counter a1 terminal count? */
- devpriv->command6_bits &= ~A1_INTR_EN_BIT;
- /* write to register */
- devpriv->write_byte(devpriv->command6_bits,
- dev->iobase + COMMAND6_REG);
+ /* read board status */
+ devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ if (board->register_layout == labpc_1200_layout)
+ devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
+
+ if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
+ STAT1_OVERRUN | STAT1_DAVAIL)) == 0
+ && (devpriv->stat2 & STAT2_OUTA1) == 0
+ && (devpriv->stat2 & STAT2_FIFONHF)) {
+ return IRQ_NONE;
}
- /* setup command4 register */
- devpriv->command4_bits = 0;
- devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
- /* single-ended/differential */
- if (CR_AREF(insn->chanspec) == AREF_DIFF)
- devpriv->command4_bits |= ADC_DIFF_BIT;
- devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
- /*
- * initialize pacer counter output to make sure it doesn't
- * cause any problems
- */
- devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
+ if (devpriv->stat1 & STAT1_OVERRUN) {
+ /* clear error interrupt */
+ devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ comedi_error(dev, "overrun");
+ return IRQ_HANDLED;
+ }
- labpc_clear_adc_fifo(dev);
+#ifdef CONFIG_ISA_DMA_API
+ if (devpriv->current_transfer == isa_dma_transfer) {
+ /*
+ * if a dma terminal count of external stop trigger
+ * has occurred
+ */
+ if (devpriv->stat1 & STAT1_GATA0 ||
+ (board->register_layout == labpc_1200_layout
+ && devpriv->stat2 & STAT2_OUTA1)) {
+ handle_isa_dma(dev);
+ }
+ } else
+#endif
+ labpc_drain_fifo(dev);
- for (n = 0; n < insn->n; n++) {
- /* trigger conversion */
- devpriv->write_byte(0x1, dev->iobase + ADC_CONVERT_REG);
+ if (devpriv->stat1 & STAT1_CNTINT) {
+ comedi_error(dev, "handled timer interrupt?");
+ /* clear it */
+ devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
+ }
- for (i = 0; i < timeout; i++) {
- if (devpriv->read_byte(dev->iobase +
- STATUS1_REG) & DATA_AVAIL_BIT)
- break;
- udelay(1);
+ if (devpriv->stat1 & STAT1_OVERFLOW) {
+ /* clear error interrupt */
+ devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ comedi_error(dev, "overflow");
+ return IRQ_HANDLED;
+ }
+ /* handle external stop trigger */
+ if (cmd->stop_src == TRIG_EXT) {
+ if (devpriv->stat2 & STAT2_OUTA1) {
+ labpc_drain_dregs(dev);
+ labpc_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
}
- if (i == timeout) {
- comedi_error(dev, "timeout");
- return -ETIME;
+ }
+
+ /* TRIG_COUNT end of acquisition */
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (devpriv->count == 0) {
+ labpc_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
}
- lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
- msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
- data[n] = (msb << 8) | lsb;
}
- return n;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
}
-/* analog output insn */
-static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int labpc_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ const struct labpc_boardinfo *board = comedi_board(dev);
struct labpc_private *devpriv = dev->private;
int channel, range;
unsigned long flags;
@@ -1664,20 +1262,19 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
/* note: hardware bug in daqcard-1200 means pacing cannot
* be independently enabled/disabled for its the two channels */
spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->command2_bits &= ~DAC_PACED_BIT(channel);
- devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ devpriv->cmd2 &= ~CMD2_LDAC(channel);
+ devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
/* set range */
- if (thisboard->register_layout == labpc_1200_layout) {
+ if (board->register_layout == labpc_1200_layout) {
range = CR_RANGE(insn->chanspec);
- if (range & AO_RANGE_IS_UNIPOLAR)
- devpriv->command6_bits |= DAC_UNIP_BIT(channel);
+ if (labpc_range_is_unipolar(s, range))
+ devpriv->cmd6 |= CMD6_DACUNI(channel);
else
- devpriv->command6_bits &= ~DAC_UNIP_BIT(channel);
+ devpriv->cmd6 &= ~CMD6_DACUNI(channel);
/* write to register */
- devpriv->write_byte(devpriv->command6_bits,
- dev->iobase + COMMAND6_REG);
+ devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
}
/* send data */
lsb = data[0] & 0xff;
@@ -1691,9 +1288,10 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
return 1;
}
-/* analog output readback insn */
-static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int labpc_ao_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct labpc_private *devpriv = dev->private;
@@ -1702,183 +1300,7 @@ static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
return 1;
}
-static int labpc_calib_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct labpc_private *devpriv = dev->private;
-
- data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)];
-
- return 1;
-}
-
-static int labpc_calib_write_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int channel = CR_CHAN(insn->chanspec);
-
- write_caldac(dev, channel, data[0]);
- return 1;
-}
-
-static int labpc_eeprom_read_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct labpc_private *devpriv = dev->private;
-
- data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)];
-
- return 1;
-}
-
-static int labpc_eeprom_write_insn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int channel = CR_CHAN(insn->chanspec);
- int ret;
-
- /* only allow writes to user area of eeprom */
- if (channel < 16 || channel > 127) {
- dev_dbg(dev->class_dev,
- "eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)\n");
- return -EINVAL;
- }
-
- ret = labpc_eeprom_write(dev, channel, data[0]);
- if (ret < 0)
- return ret;
-
- return 1;
-}
-
-#ifdef CONFIG_ISA_DMA_API
-/* utility function that suggests a dma transfer size in bytes */
-static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
-{
- unsigned int size;
- unsigned int freq;
-
- if (cmd->convert_src == TRIG_TIMER)
- freq = 1000000000 / cmd->convert_arg;
- /* return some default value */
- else
- freq = 0xffffffff;
-
- /* make buffer fill in no more than 1/3 second */
- 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;
- else if (size < sample_size)
- size = sample_size;
-
- return size;
-}
-#endif
-
-/* figures out what counter values to use based on command */
-static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
- enum scan_mode mode)
-{
- struct labpc_private *devpriv = dev->private;
- /* max value for 16 bit counter in mode 2 */
- const int max_counter_value = 0x10000;
- /* min value for 16 bit counter in mode 2 */
- const int min_counter_value = 2;
- unsigned int base_period;
- unsigned int scan_period;
- unsigned int convert_period;
-
- /*
- * if both convert and scan triggers are TRIG_TIMER, then they
- * both rely on counter b0
- */
- convert_period = labpc_ai_convert_period(cmd, mode);
- scan_period = labpc_ai_scan_period(cmd, mode);
- if (convert_period && scan_period) {
- /*
- * pick the lowest b0 divisor value we can (for maximum input
- * clock speed on convert and scan counters)
- */
- devpriv->divisor_b0 = (scan_period - 1) /
- (LABPC_TIMER_BASE * max_counter_value) + 1;
- if (devpriv->divisor_b0 < min_counter_value)
- devpriv->divisor_b0 = min_counter_value;
- if (devpriv->divisor_b0 > max_counter_value)
- devpriv->divisor_b0 = max_counter_value;
-
- base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
-
- /* set a0 for conversion frequency and b1 for scan frequency */
- switch (cmd->flags & TRIG_ROUND_MASK) {
- default:
- case TRIG_ROUND_NEAREST:
- devpriv->divisor_a0 =
- (convert_period + (base_period / 2)) / base_period;
- devpriv->divisor_b1 =
- (scan_period + (base_period / 2)) / base_period;
- break;
- case TRIG_ROUND_UP:
- devpriv->divisor_a0 =
- (convert_period + (base_period - 1)) / base_period;
- devpriv->divisor_b1 =
- (scan_period + (base_period - 1)) / base_period;
- break;
- case TRIG_ROUND_DOWN:
- devpriv->divisor_a0 = convert_period / base_period;
- devpriv->divisor_b1 = scan_period / base_period;
- break;
- }
- /* make sure a0 and b1 values are acceptable */
- if (devpriv->divisor_a0 < min_counter_value)
- devpriv->divisor_a0 = min_counter_value;
- if (devpriv->divisor_a0 > max_counter_value)
- devpriv->divisor_a0 = max_counter_value;
- if (devpriv->divisor_b1 < min_counter_value)
- devpriv->divisor_b1 = min_counter_value;
- if (devpriv->divisor_b1 > max_counter_value)
- devpriv->divisor_b1 = max_counter_value;
- /* write corrected timings to command */
- labpc_set_ai_convert_period(cmd, mode,
- base_period * devpriv->divisor_a0);
- labpc_set_ai_scan_period(cmd, mode,
- base_period * devpriv->divisor_b1);
- /*
- * if only one TRIG_TIMER is used, we can employ the generic
- * cascaded timing functions
- */
- } else if (scan_period) {
- /*
- * calculate cascaded counter values
- * that give desired scan timing
- */
- i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
- &(devpriv->divisor_b1),
- &(devpriv->divisor_b0),
- &scan_period,
- cmd->flags & TRIG_ROUND_MASK);
- labpc_set_ai_scan_period(cmd, mode, scan_period);
- } else if (convert_period) {
- /*
- * calculate cascaded counter values
- * that give desired conversion timing
- */
- i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
- &(devpriv->divisor_a0),
- &(devpriv->divisor_b0),
- &convert_period,
- cmd->flags & TRIG_ROUND_MASK);
- labpc_set_ai_convert_period(cmd, mode, convert_period);
- }
-}
-
-static int labpc_dio_mem_callback(int dir, int port, int data,
- unsigned long iobase)
+static int labpc_8255_mmio(int dir, int port, int data, unsigned long iobase)
{
if (dir) {
writeb(data, (void __iomem *)(iobase + port));
@@ -1897,20 +1319,18 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
for (i = 1; i <= value_width; i++) {
/* clear serial clock */
- devpriv->command5_bits &= ~SCLOCK_BIT;
+ devpriv->cmd5 &= ~CMD5_SCLK;
/* send bits most significant bit first */
if (value & (1 << (value_width - i)))
- devpriv->command5_bits |= SDATA_BIT;
+ devpriv->cmd5 |= CMD5_SDATA;
else
- devpriv->command5_bits &= ~SDATA_BIT;
+ devpriv->cmd5 &= ~CMD5_SDATA;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits,
- dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* set clock to load bit */
- devpriv->command5_bits |= SCLOCK_BIT;
+ devpriv->cmd5 |= CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits,
- dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
}
}
@@ -1924,20 +1344,17 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
for (i = 1; i <= value_width; i++) {
/* set serial clock */
- devpriv->command5_bits |= SCLOCK_BIT;
+ devpriv->cmd5 |= CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits,
- dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* clear clock bit */
- devpriv->command5_bits &= ~SCLOCK_BIT;
+ devpriv->cmd5 &= ~CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits,
- dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* read bits most significant bit first */
udelay(1);
- devpriv->status2_bits =
- devpriv->read_byte(dev->iobase + STATUS2_REG);
- if (devpriv->status2_bits & EEPROM_OUT_BIT)
+ devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
+ if (devpriv->stat2 & STAT2_PROMOUT)
value |= 1 << (value_width - i);
}
@@ -1955,12 +1372,12 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
const int write_length = 8;
/* enable read/write to eeprom */
- devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
- devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* send read instruction */
labpc_serial_out(dev, read_instruction, write_length);
@@ -1970,9 +1387,37 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
value = labpc_serial_in(dev);
/* disable read/write to eeprom */
- devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
+ udelay(1);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+
+ return value;
+}
+
+static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
+{
+ struct labpc_private *devpriv = dev->private;
+ unsigned int value;
+ const int read_status_instruction = 0x5;
+ const int write_length = 8; /* 8 bit write lengths to eeprom */
+
+ /* enable read/write to eeprom */
+ devpriv->cmd5 &= ~CMD5_EEPROMCS;
+ udelay(1);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
+ udelay(1);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+
+ /* send read status instruction */
+ labpc_serial_out(dev, read_status_instruction, write_length);
+ /* read result */
+ value = labpc_serial_in(dev);
+
+ /* disable read/write to eeprom */
+ devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
return value;
}
@@ -2002,68 +1447,40 @@ static int labpc_eeprom_write(struct comedi_device *dev,
devpriv->eeprom_data[address] = value;
/* enable read/write to eeprom */
- devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
- devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* send write_enable instruction */
labpc_serial_out(dev, write_enable_instruction, write_length);
- devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* send write instruction */
- devpriv->command5_bits |= EEPROM_EN_BIT;
+ devpriv->cmd5 |= CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
labpc_serial_out(dev, write_instruction, write_length);
/* send 8 bit address to write to */
labpc_serial_out(dev, address, write_length);
/* write value */
labpc_serial_out(dev, value, write_length);
- devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* disable read/write to eeprom */
- devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
return 0;
}
-static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
-{
- struct labpc_private *devpriv = dev->private;
- unsigned int value;
- const int read_status_instruction = 0x5;
- const int write_length = 8; /* 8 bit write lengths to eeprom */
-
- /* enable read/write to eeprom */
- devpriv->command5_bits &= ~EEPROM_EN_BIT;
- udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
- devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
- udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
-
- /* send read status instruction */
- labpc_serial_out(dev, read_status_instruction, write_length);
- /* read result */
- value = labpc_serial_in(dev);
-
- /* disable read/write to eeprom */
- devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
- udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
-
- return value;
-}
-
/* writes to 8 bit calibration dacs */
static void write_caldac(struct comedi_device *dev, unsigned int channel,
unsigned int value)
@@ -2075,10 +1492,9 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
devpriv->caldac[channel] = value;
/* clear caldac load bit and make sure we don't write to eeprom */
- devpriv->command5_bits &=
- ~CALDAC_LOAD_BIT & ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
/* write 4 bit channel */
labpc_serial_out(dev, channel, 4);
@@ -2086,49 +1502,295 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
labpc_serial_out(dev, value, 8);
/* set and clear caldac bit to load caldac value */
- devpriv->command5_bits |= CALDAC_LOAD_BIT;
+ devpriv->cmd5 |= CMD5_CALDACLD;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
- devpriv->command5_bits &= ~CALDAC_LOAD_BIT;
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->cmd5 &= ~CMD5_CALDACLD;
udelay(1);
- devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
}
-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_board_struct),
-};
+static int labpc_calib_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
-#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);
+ /*
+ * Only write the last data value to the caldac. Preceding
+ * data would be overwritten anyway.
+ */
+ if (insn->n > 0)
+ write_caldac(dev, chan, data[insn->n - 1]);
+
+ return insn->n;
+}
-static int labpc_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+static int labpc_calib_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- return comedi_pci_auto_config(dev, &labpc_driver);
+ struct labpc_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->caldac[chan];
+
+ return insn->n;
}
-static struct pci_driver labpc_pci_driver = {
- .name = DRV_NAME,
- .id_table = labpc_pci_table,
- .probe = labpc_pci_probe,
- .remove = comedi_pci_auto_unconfig,
+static int labpc_eeprom_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int ret;
+
+ /* only allow writes to user area of eeprom */
+ if (chan < 16 || chan > 127)
+ return -EINVAL;
+
+ /*
+ * Only write the last data value to the eeprom. Preceding
+ * data would be overwritten anyway.
+ */
+ if (insn->n > 0) {
+ ret = labpc_eeprom_write(dev, chan, data[insn->n - 1]);
+ if (ret)
+ return ret;
+ }
+
+ return insn->n;
+}
+
+static int labpc_eeprom_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct labpc_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->eeprom_data[chan];
+
+ return insn->n;
+}
+
+int labpc_common_attach(struct comedi_device *dev,
+ unsigned int irq, unsigned long isr_flags)
+{
+ const struct labpc_boardinfo *board = comedi_board(dev);
+ struct labpc_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
+
+ if (board->has_mmio) {
+ devpriv->read_byte = labpc_readb;
+ devpriv->write_byte = labpc_writeb;
+ } else {
+ devpriv->read_byte = labpc_inb;
+ devpriv->write_byte = labpc_outb;
+ }
+
+ /* initialize board's command registers */
+ devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
+ devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
+ devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+ if (board->register_layout == labpc_1200_layout) {
+ devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ }
+
+ if (irq) {
+ ret = request_irq(irq, labpc_interrupt, isr_flags,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = irq;
+ }
+
+ ret = comedi_alloc_subdevices(dev, 5);
+ if (ret)
+ return ret;
+
+ /* analog input subdevice */
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->maxdata = 0x0fff;
+ s->range_table = board->ai_range_table;
+ s->insn_read = labpc_ai_insn_read;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmd = labpc_ai_cmd;
+ s->do_cmdtest = labpc_ai_cmdtest;
+ s->cancel = labpc_cancel;
+ }
+
+ /* analog output */
+ s = &dev->subdevices[1];
+ if (board->has_ao) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = NUM_AO_CHAN;
+ s->maxdata = 0x0fff;
+ s->range_table = &range_labpc_ao;
+ s->insn_read = labpc_ao_insn_read;
+ s->insn_write = labpc_ao_insn_write;
+
+ /* initialize analog outputs to a known value */
+ for (i = 0; i < s->n_chan; i++) {
+ short lsb, msb;
+
+ devpriv->ao_value[i] = s->maxdata / 2;
+ lsb = devpriv->ao_value[i] & 0xff;
+ msb = (devpriv->ao_value[i] >> 8) & 0xff;
+ devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
+ devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* 8255 dio */
+ s = &dev->subdevices[2];
+ ret = subdev_8255_init(dev, s,
+ (board->has_mmio) ? labpc_8255_mmio : NULL,
+ dev->iobase + DIO_BASE_REG);
+ if (ret)
+ return ret;
+
+ /* calibration subdevices for boards that have one */
+ s = &dev->subdevices[3];
+ if (board->register_layout == labpc_1200_layout) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 16;
+ s->maxdata = 0xff;
+ s->insn_read = labpc_calib_insn_read;
+ s->insn_write = labpc_calib_insn_write;
+
+ for (i = 0; i < s->n_chan; i++)
+ write_caldac(dev, i, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* EEPROM */
+ s = &dev->subdevices[4];
+ if (board->register_layout == labpc_1200_layout) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = EEPROM_SIZE;
+ s->maxdata = 0xff;
+ s->insn_read = labpc_eeprom_insn_read;
+ s->insn_write = labpc_eeprom_insn_write;
+
+ for (i = 0; i < s->n_chan; i++)
+ devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+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);
+
+#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISA)
+static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+ struct labpc_private *devpriv;
+ unsigned int irq = it->options[1];
+ unsigned int dma_chan = it->options[2];
+ int ret;
+
+ devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+ if (!devpriv)
+ return -ENOMEM;
+ dev->private = devpriv;
+
+ ret = comedi_request_region(dev, it->options[0], LABPC_SIZE);
+ if (ret)
+ return ret;
+
+ ret = labpc_common_attach(dev, irq, 0);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_ISA_DMA_API
+ if (dev->irq && (dma_chan == 1 || dma_chan == 3)) {
+ devpriv->dma_buffer = kmalloc(dma_buffer_size,
+ GFP_KERNEL | GFP_DMA);
+ if (devpriv->dma_buffer) {
+ ret = request_dma(dma_chan, dev->board_name);
+ if (ret == 0) {
+ unsigned long dma_flags;
+
+ 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);
+ } else {
+ kfree(devpriv->dma_buffer);
+ }
+ }
+ }
+#endif
+
+ 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);
+ }
+ comedi_legacy_detach(dev);
+}
+
+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_pci_driver(labpc_driver, labpc_pci_driver);
-#else
module_comedi_driver(labpc_driver);
-#endif
+#else
+static int __init labpc_common_init(void)
+{
+ return 0;
+}
+module_init(labpc_common_init);
+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");
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index e052ed3ba54..615f16f271c 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -27,48 +27,45 @@
#define EEPROM_SIZE 256 /* 256 byte eeprom */
#define NUM_AO_CHAN 2 /* boards have two analog output channels */
-enum labpc_bustype { isa_bustype, pci_bustype, pcmcia_bustype };
enum labpc_register_layout { labpc_plus_layout, labpc_1200_layout };
enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer,
isa_dma_transfer
};
-struct labpc_board_struct {
+struct labpc_boardinfo {
const char *name;
int device_id; /* device id for pci and pcmcia boards */
int ai_speed; /* maximum input speed in nanoseconds */
- enum labpc_bustype bustype; /* ISA/PCI/etc. */
/* 1200 has extra registers compared to pc+ */
enum labpc_register_layout register_layout;
int has_ao; /* has analog output true/false */
const struct comedi_lrange *ai_range_table;
const int *ai_range_code;
- const int *ai_range_is_unipolar;
/* board can auto scan up in ai channels, not just down */
unsigned ai_scan_up:1;
/* uses memory mapped io instead of ioports */
- unsigned memory_mapped_io:1;
+ unsigned has_mmio:1;
};
struct labpc_private {
struct mite_struct *mite; /* for mite chip on pci-1200 */
/* number of data points left to be taken */
- volatile unsigned long long count;
+ unsigned long long count;
/* software copy of analog output values */
unsigned int ao_value[NUM_AO_CHAN];
/* software copys of bits written to command registers */
- volatile unsigned int command1_bits;
- volatile unsigned int command2_bits;
- volatile unsigned int command3_bits;
- volatile unsigned int command4_bits;
- volatile unsigned int command5_bits;
- volatile unsigned int command6_bits;
+ unsigned int cmd1;
+ unsigned int cmd2;
+ unsigned int cmd3;
+ unsigned int cmd4;
+ unsigned int cmd5;
+ unsigned int cmd6;
/* store last read of board status registers */
- volatile unsigned int status1_bits;
- volatile unsigned int status2_bits;
+ unsigned int stat1;
+ unsigned int stat2;
/*
* value to load into board's counter a0 (conversion pacing) for timed
* conversions
@@ -101,11 +98,10 @@ 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 isr_flags);
void labpc_common_detach(struct comedi_device *dev);
-extern const int labpc_1200_is_unipolar[];
extern const int labpc_1200_ai_gain_bits[];
extern const struct comedi_lrange range_labpc_1200_ai;
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index be7d1413b2e..9e3737c6918 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -73,17 +73,15 @@ NI manuals:
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-static const struct labpc_board_struct labpc_cs_boards[] = {
+static const struct labpc_boardinfo labpc_cs_boards[] = {
{
.name = "daqcard-1200",
.device_id = 0x103,
.ai_speed = 10000,
- .bustype = pcmcia_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,
},
};
@@ -112,7 +110,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_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c
new file mode 100644
index 00000000000..8e916f86cce
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c
@@ -0,0 +1,142 @@
+/*
+ * comedi/drivers/ni_labpc_pci.c
+ * Driver for National Instruments Lab-PC PCI-1200
+ * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * 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@users.sourceforge.net>
+ * 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 <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",
+ .ai_speed = 10000,
+ .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), 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);
+ }
+ 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");
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index b7403597e90..a46d579016d 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -189,11 +189,6 @@ static const struct comedi_lrange range_ni_M_ai_628x = { 7, {
}
};
-static const struct comedi_lrange range_ni_S_ai_6143 = { 1, {
- RANGE(-5, +5),
- }
-};
-
static const struct comedi_lrange range_ni_E_ao_ext = { 4, {
RANGE(-10, 10),
RANGE(0, 10),
@@ -210,7 +205,7 @@ static const struct comedi_lrange *const ni_range_lkup[] = {
[ai_gain_611x] = &range_ni_E_ai_611x,
[ai_gain_622x] = &range_ni_M_ai_622x,
[ai_gain_628x] = &range_ni_M_ai_628x,
- [ai_gain_6143] = &range_ni_S_ai_6143
+ [ai_gain_6143] = &range_bipolar5
};
static int ni_dio_insn_config(struct comedi_device *dev,
@@ -696,9 +691,10 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev)
static void ni_e_series_enable_second_irq(struct comedi_device *dev,
unsigned gpct_index, short enable)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
return;
switch (gpct_index) {
case 0:
@@ -728,16 +724,17 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev,
static void ni_clear_ai_fifo(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
- if (boardtype.reg_type == ni_reg_6143) {
+ if (board->reg_type == ni_reg_6143) {
/* Flush the 6143 data FIFO */
ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */
ni_writel(0x00, AIFIFO_Control_6143); /* Flush fifo */
while (ni_readl(AIFIFO_Status_6143) & 0x10) ; /* Wait for complete */
} else {
devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
- if (boardtype.reg_type == ni_reg_625x) {
+ if (board->reg_type == ni_reg_625x) {
ni_writeb(0, M_Offset_Static_AI_Control(0));
ni_writeb(1, M_Offset_Static_AI_Control(0));
#if 0
@@ -845,7 +842,7 @@ static irqreturn_t ni_E_interrupt(int irq, void *d)
struct mite_struct *mite = devpriv->mite;
#endif
- if (dev->attached == 0)
+ if (!dev->attached)
return IRQ_NONE;
smp_mb(); /* make sure dev->attached is checked before handler does anything else. */
@@ -1292,6 +1289,7 @@ static void ni_mio_print_status_b(int status)
static void ni_ao_fifo_load(struct comedi_device *dev,
struct comedi_subdevice *s, int n)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
int chan;
@@ -1309,10 +1307,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
range = CR_RANGE(cmd->chanlist[chan]);
- if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ if (board->reg_type & ni_reg_6xxx_mask) {
packed_data = d & 0xffff;
/* 6711 only has 16 bit wide ao fifo */
- if (boardtype.reg_type != ni_reg_6711) {
+ if (board->reg_type != ni_reg_6711) {
err &= comedi_buf_get(async, &d);
if (err == 0)
break;
@@ -1352,6 +1350,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
static int ni_ao_fifo_half_empty(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
int n;
n = comedi_buf_read_n_available(s->async);
@@ -1361,8 +1360,8 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev,
}
n /= sizeof(short);
- if (n > boardtype.ao_fifo_depth / 2)
- n = boardtype.ao_fifo_depth / 2;
+ if (n > board->ao_fifo_depth / 2)
+ n = board->ao_fifo_depth / 2;
ni_ao_fifo_load(dev, s, n);
@@ -1374,12 +1373,13 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev,
static int ni_ao_prep_fifo(struct comedi_device *dev,
struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int n;
/* reset fifo */
devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
- if (boardtype.reg_type & ni_reg_6xxx_mask)
+ if (board->reg_type & ni_reg_6xxx_mask)
ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
/* load some data */
@@ -1388,8 +1388,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev,
return 0;
n /= sizeof(short);
- if (n > boardtype.ao_fifo_depth)
- n = boardtype.ao_fifo_depth;
+ if (n > board->ao_fifo_depth)
+ n = board->ao_fifo_depth;
ni_ao_fifo_load(dev, s, n);
@@ -1399,11 +1399,12 @@ static int ni_ao_prep_fifo(struct comedi_device *dev,
static void ni_ai_fifo_read(struct comedi_device *dev,
struct comedi_subdevice *s, int n)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_async *async = s->async;
int i;
- if (boardtype.reg_type == ni_reg_611x) {
+ if (board->reg_type == ni_reg_611x) {
short data[2];
u32 dl;
@@ -1420,7 +1421,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
data[0] = dl & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
- } else if (boardtype.reg_type == ni_reg_6143) {
+ } else if (board->reg_type == ni_reg_6143) {
short data[2];
u32 dl;
@@ -1458,10 +1459,11 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
static void ni_handle_fifo_half_full(struct comedi_device *dev)
{
- int n;
+ const struct ni_board_struct *board = comedi_board(dev);
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ int n;
- n = boardtype.ai_fifo_depth / 2;
+ n = board->ai_fifo_depth / 2;
ni_ai_fifo_read(dev, s, n);
}
@@ -1508,6 +1510,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev)
*/
static void ni_handle_fifo_dregs(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
short data[2];
@@ -1515,7 +1518,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
short fifo_empty;
int i;
- if (boardtype.reg_type == ni_reg_611x) {
+ if (board->reg_type == ni_reg_611x) {
while ((devpriv->stc_readw(dev,
AI_Status_1_Register) &
AI_FIFO_Empty_St) == 0) {
@@ -1526,7 +1529,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
data[1] = (dl & 0xffff);
cfc_write_array_to_buffer(s, data, sizeof(data));
}
- } else if (boardtype.reg_type == ni_reg_6143) {
+ } else if (board->reg_type == ni_reg_6143) {
i = 0;
while (ni_readl(AIFIFO_Status_6143) & 0x04) {
dl = ni_readl(AIFIFO_Data_6143);
@@ -1573,12 +1576,13 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
static void get_last_sample_611x(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv __maybe_unused = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
short data;
u32 dl;
- if (boardtype.reg_type != ni_reg_611x)
+ if (board->reg_type != ni_reg_611x)
return;
/* Check if there's a single sample stuck in the FIFO */
@@ -1591,12 +1595,13 @@ static void get_last_sample_611x(struct comedi_device *dev)
static void get_last_sample_6143(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv __maybe_unused = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
short data;
u32 dl;
- if (boardtype.reg_type != ni_reg_6143)
+ if (board->reg_type != ni_reg_6143)
return;
/* Check if there's a single sample stuck in the FIFO */
@@ -1641,6 +1646,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
int retval;
@@ -1660,7 +1666,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
return -EIO;
}
- switch (boardtype.reg_type) {
+ switch (board->reg_type) {
case ni_reg_611x:
case ni_reg_6143:
mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
@@ -1681,6 +1687,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
int retval;
@@ -1695,7 +1702,7 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
if (devpriv->ao_mite_chan) {
- if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) {
+ if (board->reg_type & (ni_reg_611x | ni_reg_6713)) {
mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
} else {
/* doing 32 instead of 16 bit wide transfers from memory
@@ -1720,6 +1727,7 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
ni_release_ai_mite_channel(dev);
@@ -1735,7 +1743,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
ni_clear_ai_fifo(dev);
- if (boardtype.reg_type != ni_reg_6143)
+ if (board->reg_type != ni_reg_6143)
ni_writeb(0, Misc_Command);
devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
@@ -1746,7 +1754,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
/* generate FIFO interrupts on non-empty */
devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
- if (boardtype.reg_type == ni_reg_611x) {
+ if (board->reg_type == ni_reg_611x) {
devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
AI_SOC_Polarity |
AI_LOCALMUX_CLK_Pulse_Width,
@@ -1759,7 +1767,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
AI_CONVERT_Output_Select
(AI_CONVERT_Output_Enable_High),
AI_Output_Control_Register);
- } else if (boardtype.reg_type == ni_reg_6143) {
+ } else if (board->reg_type == ni_reg_6143) {
devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
AI_SOC_Polarity |
AI_LOCALMUX_CLK_Pulse_Width,
@@ -1784,7 +1792,7 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
AI_EXTMUX_CLK_Output_Select(0) |
AI_LOCALMUX_CLK_Output_Select(2) |
AI_SC_TC_Output_Select(3);
- if (boardtype.reg_type == ni_reg_622x)
+ if (board->reg_type == ni_reg_622x)
ai_output_control_bits |=
AI_CONVERT_Output_Select
(AI_CONVERT_Output_Enable_High);
@@ -1832,9 +1840,10 @@ static int ni_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int i, n;
- const unsigned int mask = (1 << boardtype.adbits) - 1;
+ const unsigned int mask = (1 << board->adbits) - 1;
unsigned signbits;
unsigned short d;
unsigned long dl;
@@ -1844,7 +1853,7 @@ static int ni_ai_insn_read(struct comedi_device *dev,
ni_clear_ai_fifo(dev);
signbits = devpriv->ai_offset[0];
- if (boardtype.reg_type == ni_reg_611x) {
+ if (board->reg_type == ni_reg_611x) {
for (n = 0; n < num_adc_stages_611x; n++) {
devpriv->stc_writew(dev, AI_CONVERT_Pulse,
AI_Command_1_Register);
@@ -1877,7 +1886,7 @@ static int ni_ai_insn_read(struct comedi_device *dev,
d += signbits;
data[n] = d;
}
- } else if (boardtype.reg_type == ni_reg_6143) {
+ } else if (board->reg_type == ni_reg_6143) {
for (n = 0; n < insn->n; n++) {
devpriv->stc_writew(dev, AI_CONVERT_Pulse,
AI_Command_1_Register);
@@ -1913,7 +1922,7 @@ static int ni_ai_insn_read(struct comedi_device *dev,
("ni_mio_common: timeout in ni_ai_insn_read\n");
return -ETIME;
}
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
data[n] =
ni_readl(M_Offset_AI_FIFO_Data) & mask;
} else {
@@ -1948,6 +1957,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan,
unsigned int *list)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan, range, aref;
unsigned int i;
@@ -1957,12 +1967,12 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
-/* offset = 1 << (boardtype.adbits - 1); */
+/* offset = 1 << (board->adbits - 1); */
if ((list[0] & CR_ALT_SOURCE)) {
unsigned bypass_bits;
chan = CR_CHAN(list[0]);
range = CR_RANGE(list[0]);
- range_code = ni_gainlkup[boardtype.gainlkup][range];
+ range_code = ni_gainlkup[board->gainlkup][range];
dither = ((list[0] & CR_ALT_FILTER) != 0);
bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit;
bypass_bits |= chan;
@@ -1989,7 +1999,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
range = CR_RANGE(list[i]);
dither = ((list[i] & CR_ALT_FILTER) != 0);
- range_code = ni_gainlkup[boardtype.gainlkup][range];
+ range_code = ni_gainlkup[board->gainlkup][range];
devpriv->ai_offset[i] = offset;
switch (aref) {
case AREF_DIFF:
@@ -2009,7 +2019,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
}
config_bits |= MSeries_AI_Config_Channel_Bits(chan);
config_bits |=
- MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan);
+ MSeries_AI_Config_Bank_Bits(board->reg_type, chan);
config_bits |= MSeries_AI_Config_Gain_Bits(range_code);
if (i == n_chan - 1)
config_bits |= MSeries_AI_Config_Last_Channel_Bit;
@@ -2054,6 +2064,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
static void ni_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan, range, aref;
unsigned int i;
@@ -2061,12 +2072,12 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
unsigned offset;
unsigned int dither;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
ni_m_series_load_channelgain_list(dev, n_chan, list);
return;
}
- if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x)
- && (boardtype.reg_type != ni_reg_6143)) {
+ if (n_chan == 1 && (board->reg_type != ni_reg_611x)
+ && (board->reg_type != ni_reg_6143)) {
if (devpriv->changain_state
&& devpriv->changain_spec == list[0]) {
/* ready to go. */
@@ -2081,7 +2092,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
/* Set up Calibration mode if required */
- if (boardtype.reg_type == ni_reg_6143) {
+ if (board->reg_type == ni_reg_6143) {
if ((list[0] & CR_ALT_SOURCE)
&& !devpriv->ai_calib_source_enabled) {
/* Strobe Relay enable bit */
@@ -2105,9 +2116,9 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
}
}
- offset = 1 << (boardtype.adbits - 1);
+ offset = 1 << (board->adbits - 1);
for (i = 0; i < n_chan; i++) {
- if ((boardtype.reg_type != ni_reg_6143)
+ if ((board->reg_type != ni_reg_6143)
&& (list[i] & CR_ALT_SOURCE)) {
chan = devpriv->ai_calib_source;
} else {
@@ -2118,21 +2129,21 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
dither = ((list[i] & CR_ALT_FILTER) != 0);
/* fix the external/internal range differences */
- range = ni_gainlkup[boardtype.gainlkup][range];
- if (boardtype.reg_type == ni_reg_611x)
+ range = ni_gainlkup[board->gainlkup][range];
+ if (board->reg_type == ni_reg_611x)
devpriv->ai_offset[i] = offset;
else
devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
hi = 0;
if ((list[i] & CR_ALT_SOURCE)) {
- if (boardtype.reg_type == ni_reg_611x)
+ if (board->reg_type == ni_reg_611x)
ni_writew(CR_CHAN(list[i]) & 0x0003,
Calibration_Channel_Select_611x);
} else {
- if (boardtype.reg_type == ni_reg_611x)
+ if (board->reg_type == ni_reg_611x)
aref = AREF_DIFF;
- else if (boardtype.reg_type == ni_reg_6143)
+ else if (board->reg_type == ni_reg_6143)
aref = AREF_OTHER;
switch (aref) {
case AREF_DIFF:
@@ -2152,7 +2163,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
ni_writew(hi, Configuration_Memory_High);
- if (boardtype.reg_type != ni_reg_6143) {
+ if (board->reg_type != ni_reg_6143) {
lo = range;
if (i == n_chan - 1)
lo |= AI_LAST_CHANNEL;
@@ -2164,8 +2175,8 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
}
/* prime the channel/gain list */
- if ((boardtype.reg_type != ni_reg_611x)
- && (boardtype.reg_type != ni_reg_6143)) {
+ if ((board->reg_type != ni_reg_611x)
+ && (board->reg_type != ni_reg_6143)) {
ni_prime_channelgain_list(dev);
}
}
@@ -2201,22 +2212,25 @@ static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer)
static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
unsigned num_channels)
{
- switch (boardtype.reg_type) {
+ const struct ni_board_struct *board = comedi_board(dev);
+
+ switch (board->reg_type) {
case ni_reg_611x:
case ni_reg_6143:
/* simultaneously-sampled inputs */
- return boardtype.ai_speed;
+ return board->ai_speed;
break;
default:
/* multiplexed inputs */
break;
}
- return boardtype.ai_speed * num_channels;
+ return board->ai_speed * num_channels;
}
static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int err = 0;
int tmp;
@@ -2233,8 +2247,8 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
TRIG_TIMER | TRIG_EXT);
sources = TRIG_TIMER | TRIG_EXT;
- if (boardtype.reg_type == ni_reg_611x ||
- boardtype.reg_type == ni_reg_6143)
+ if (board->reg_type == ni_reg_611x ||
+ board->reg_type == ni_reg_6143)
sources |= TRIG_NOW;
err |= cfc_check_trigger_src(&cmd->convert_src, sources);
@@ -2289,12 +2303,12 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
}
if (cmd->convert_src == TRIG_TIMER) {
- if ((boardtype.reg_type == ni_reg_611x)
- || (boardtype.reg_type == ni_reg_6143)) {
+ if ((board->reg_type == ni_reg_611x)
+ || (board->reg_type == ni_reg_6143)) {
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
} else {
err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
- boardtype.ai_speed);
+ board->ai_speed);
err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
devpriv->clock_ns * 0xffff);
}
@@ -2315,7 +2329,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (cmd->stop_src == TRIG_COUNT) {
unsigned int max_count = 0x01000000;
- if (boardtype.reg_type == ni_reg_611x)
+ if (board->reg_type == ni_reg_611x)
max_count -= num_adc_stages_611x;
err |= cfc_check_trigger_arg_max(&cmd->stop_arg, max_count);
err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
@@ -2341,8 +2355,8 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
err++;
}
if (cmd->convert_src == TRIG_TIMER) {
- if ((boardtype.reg_type != ni_reg_611x)
- && (boardtype.reg_type != ni_reg_6143)) {
+ if ((board->reg_type != ni_reg_611x)
+ && (board->reg_type != ni_reg_6143)) {
tmp = cmd->convert_arg;
cmd->convert_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
@@ -2370,6 +2384,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
const struct comedi_cmd *cmd = &s->async->cmd;
int timer;
@@ -2426,8 +2441,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
mode2 &= ~AI_SC_Reload_Mode;
devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
- if (cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x)
- || (boardtype.reg_type == ni_reg_6143)) {
+ if (cmd->chanlist_len == 1 || (board->reg_type == ni_reg_611x)
+ || (board->reg_type == ni_reg_6143)) {
start_stop_select |= AI_STOP_Polarity;
start_stop_select |= AI_STOP_Select(31); /* logic low */
start_stop_select |= AI_STOP_Sync;
@@ -2442,7 +2457,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
case TRIG_COUNT:
stop_count = cmd->stop_arg - 1;
- if (boardtype.reg_type == ni_reg_611x) {
+ if (board->reg_type == ni_reg_611x) {
/* have to take 3 stage adc pipeline into account */
stop_count += num_adc_stages_611x;
}
@@ -2698,6 +2713,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
if (insn->n < 1)
@@ -2707,7 +2723,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
case INSN_CONFIG_ANALOG_TRIG:
return ni_ai_config_analog_trig(dev, s, insn, data);
case INSN_CONFIG_ALT_SOURCE:
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
MSeries_AI_Bypass_Mode_Mux_Mask |
@@ -2715,7 +2731,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
}
devpriv->ai_calib_source = data[1];
- } else if (boardtype.reg_type == ni_reg_6143) {
+ } else if (board->reg_type == ni_reg_6143) {
unsigned int calib_source;
calib_source = data[1] & 0xf;
@@ -2735,7 +2751,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
if (calib_source >= 8)
return -EINVAL;
devpriv->ai_calib_source = calib_source;
- if (boardtype.reg_type == ni_reg_611x) {
+ if (board->reg_type == ni_reg_611x) {
ni_writeb(calib_source_adjust,
Cal_Gain_Select_611x);
}
@@ -2753,6 +2769,7 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int a, b, modebits;
int err = 0;
@@ -2761,14 +2778,14 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev,
* data[2] is analog line
* data[3] is set level
* data[4] is reset level */
- if (!boardtype.has_analog_trig)
+ if (!board->has_analog_trig)
return -EINVAL;
if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) {
data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff);
err++;
}
- if (data[2] >= boardtype.n_adchan) {
- data[2] = boardtype.n_adchan - 1;
+ if (data[2] >= board->n_adchan) {
+ data[2] = board->n_adchan - 1;
err++;
}
if (data[3] > 255) { /* a */
@@ -2852,6 +2869,7 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
unsigned int chan_index)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct comedi_async *async = s->async;
unsigned int range;
unsigned int i;
@@ -2859,10 +2877,10 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int length = num_bytes / sizeof(short);
short *array = data;
- offset = 1 << (boardtype.aobits - 1);
+ offset = 1 << (board->aobits - 1);
for (i = 0; i < length; i++) {
range = CR_RANGE(async->cmd.chanlist[chan_index]);
- if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
+ if (board->ao_unipolar == 0 || (range & 1) == 0)
array[i] -= offset;
#ifdef PCIDMA
array[i] = cpu_to_le16(array[i]);
@@ -2877,6 +2895,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[],
unsigned int n_chans, int timed)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int range;
unsigned int chan;
@@ -2885,7 +2904,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
int invert = 0;
if (timed) {
- for (i = 0; i < boardtype.n_aochan; ++i) {
+ for (i = 0; i < board->n_aochan; ++i) {
devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
ni_writeb(devpriv->ao_conf[i],
M_Offset_AO_Config_Bank(i));
@@ -2949,6 +2968,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[],
unsigned int n_chans)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int range;
unsigned int chan;
@@ -2961,10 +2981,10 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
range = CR_RANGE(chanspec[i]);
conf = AO_Channel(chan);
- if (boardtype.ao_unipolar) {
+ if (board->ao_unipolar) {
if ((range & 1) == 0) {
conf |= AO_Bipolar;
- invert = (1 << (boardtype.aobits - 1));
+ invert = (1 << (board->aobits - 1));
} else {
invert = 0;
}
@@ -2972,7 +2992,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
conf |= AO_Ext_Ref;
} else {
conf |= AO_Bipolar;
- invert = (1 << (boardtype.aobits - 1));
+ invert = (1 << (board->aobits - 1));
}
/* not all boards can deglitch, but this shouldn't hurt */
@@ -2995,7 +3015,9 @@ static int ni_ao_config_chanlist(struct comedi_device *dev,
unsigned int chanspec[], unsigned int n_chans,
int timed)
{
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ const struct ni_board_struct *board = comedi_board(dev);
+
+ if (board->reg_type & ni_reg_m_series_mask)
return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
timed);
else
@@ -3017,6 +3039,7 @@ static int ni_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int invert;
@@ -3025,7 +3048,7 @@ static int ni_ao_insn_write(struct comedi_device *dev,
devpriv->ao[chan] = data[0];
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
} else
ni_writew(data[0] ^ invert,
@@ -3038,12 +3061,13 @@ static int ni_ao_insn_write_671x(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int invert;
ao_win_out(1 << chan, AO_Immediate_671x);
- invert = 1 << (boardtype.aobits - 1);
+ invert = 1 << (board->aobits - 1);
ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
@@ -3057,13 +3081,14 @@ static int ni_ao_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
switch (data[0]) {
case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
switch (data[1]) {
case COMEDI_OUTPUT:
- data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short);
+ data[2] = 1 + board->ao_fifo_depth * sizeof(short);
if (devpriv->mite)
data[2] += devpriv->mite->fifo_size;
break;
@@ -3085,6 +3110,7 @@ static int ni_ao_insn_config(struct comedi_device *dev,
static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
+ const struct ni_board_struct *board __maybe_unused = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int ret;
int interrupt_b_bits;
@@ -3104,7 +3130,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
interrupt_b_bits = AO_Error_Interrupt_Enable;
#ifdef PCIDMA
devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
- if (boardtype.reg_type & ni_reg_6xxx_mask)
+ if (board->reg_type & ni_reg_6xxx_mask)
ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
ret = ni_ao_setup_MITE_dma(dev);
if (ret)
@@ -3155,6 +3181,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
const struct comedi_cmd *cmd = &s->async->cmd;
int bits;
@@ -3170,7 +3197,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
- if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ if (board->reg_type & ni_reg_6xxx_mask) {
ao_win_out(CLEAR_WG, AO_Misc_611x);
bits = 0;
@@ -3233,7 +3260,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
/* this is how the NI example code does it for m-series boards, verified correct with 6259 */
devpriv->stc_writel(dev, cmd->stop_arg - 1,
AO_UC_Load_A_Register);
@@ -3301,8 +3328,8 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned bits;
devpriv->ao_mode1 &= ~AO_Multiple_Channels;
bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
- if (boardtype.
- reg_type & (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
+ if (board->reg_type &
+ (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
bits |= AO_Number_Of_Channels(0);
} else {
bits |=
@@ -3329,14 +3356,14 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
AO_TMRDACWR_Pulse_Width;
- if (boardtype.ao_fifo_depth)
+ if (board->ao_fifo_depth)
bits |= AO_FIFO_Enable;
else
bits |= AO_DMA_PIO_Control;
#if 0
/* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
verified with bus analyzer. */
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
bits |= AO_Number_Of_DAC_Packages;
#endif
devpriv->stc_writew(dev, bits, AO_Personal_Register);
@@ -3360,6 +3387,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int err = 0;
int tmp;
@@ -3407,7 +3435,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
if (cmd->scan_begin_src == TRIG_TIMER) {
err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
- boardtype.ao_speed);
+ board->ao_speed);
err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
devpriv->clock_ns * 0xffffff);
}
@@ -3448,6 +3476,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
/* devpriv->ao0p=0x0000; */
@@ -3475,7 +3504,7 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
devpriv->ao_mode2 = 0;
devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
devpriv->ao_mode3 = AO_Last_Gate_Disable;
else
devpriv->ao_mode3 = 0;
@@ -3483,7 +3512,7 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_trigger_select = 0;
devpriv->stc_writew(dev, devpriv->ao_trigger_select,
AO_Trigger_Select_Register);
- if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ if (board->reg_type & ni_reg_6xxx_mask) {
unsigned immediate_bits = 0;
unsigned i;
for (i = 0; i < s->n_chan; ++i) {
@@ -3784,6 +3813,7 @@ static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static void handle_cdio_interrupt(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv __maybe_unused = dev->private;
unsigned cdio_status;
struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV];
@@ -3791,7 +3821,7 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
unsigned long flags;
#endif
- if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ if ((board->reg_type & ni_reg_m_series_mask) == 0) {
return;
}
#ifdef PCIDMA
@@ -4039,17 +4069,13 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
static void mio_common_detach(struct comedi_device *dev)
{
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s;
if (devpriv) {
if (devpriv->counter_dev) {
ni_gpct_device_destroy(devpriv->counter_dev);
}
}
- if (dev->subdevices && boardtype.has_8255) {
- s = &dev->subdevices[NI_8255_DIO_SUBDEV];
- subdev_8255_cleanup(dev, s);
- }
+ comedi_spriv_free(dev, NI_8255_DIO_SUBDEV);
}
static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -4355,14 +4381,15 @@ static int ni_alloc_private(struct comedi_device *dev)
static int ni_E_init(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_subdevice *s;
unsigned j;
enum ni_gpct_variant counter_variant;
int ret;
- if (boardtype.n_aochan > MAX_N_AO_CHAN) {
- printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n");
+ if (board->n_aochan > MAX_N_AO_CHAN) {
+ printk("bug! n_aochan > MAX_N_AO_CHAN\n");
return -EINVAL;
}
@@ -4374,20 +4401,20 @@ static int ni_E_init(struct comedi_device *dev)
s = &dev->subdevices[NI_AI_SUBDEV];
dev->read_subdev = s;
- if (boardtype.n_adchan) {
+ if (board->n_adchan) {
s->type = COMEDI_SUBD_AI;
s->subdev_flags =
SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
- if (boardtype.reg_type != ni_reg_611x)
+ if (board->reg_type != ni_reg_611x)
s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
- if (boardtype.adbits > 16)
+ if (board->adbits > 16)
s->subdev_flags |= SDF_LSAMPL;
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = boardtype.n_adchan;
+ s->n_chan = board->n_adchan;
s->len_chanlist = 512;
- s->maxdata = (1 << boardtype.adbits) - 1;
- s->range_table = ni_range_lkup[boardtype.gainlkup];
+ s->maxdata = (1 << board->adbits) - 1;
+ s->range_table = ni_range_lkup[board->gainlkup];
s->insn_read = &ni_ai_insn_read;
s->insn_config = &ni_ai_insn_config;
s->do_cmdtest = &ni_ai_cmdtest;
@@ -4405,40 +4432,40 @@ static int ni_E_init(struct comedi_device *dev)
/* analog output subdevice */
s = &dev->subdevices[NI_AO_SUBDEV];
- if (boardtype.n_aochan) {
+ if (board->n_aochan) {
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = boardtype.n_aochan;
- s->maxdata = (1 << boardtype.aobits) - 1;
- s->range_table = boardtype.ao_range_table;
+ s->n_chan = board->n_aochan;
+ s->maxdata = (1 << board->aobits) - 1;
+ s->range_table = board->ao_range_table;
s->insn_read = &ni_ao_insn_read;
- if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ if (board->reg_type & ni_reg_6xxx_mask) {
s->insn_write = &ni_ao_insn_write_671x;
} else {
s->insn_write = &ni_ao_insn_write;
}
s->insn_config = &ni_ao_insn_config;
#ifdef PCIDMA
- if (boardtype.n_aochan) {
+ if (board->n_aochan) {
s->async_dma_dir = DMA_TO_DEVICE;
#else
- if (boardtype.ao_fifo_depth) {
+ if (board->ao_fifo_depth) {
#endif
dev->write_subdev = s;
s->subdev_flags |= SDF_CMD_WRITE;
s->do_cmd = &ni_ao_cmd;
s->do_cmdtest = &ni_ao_cmdtest;
- s->len_chanlist = boardtype.n_aochan;
- if ((boardtype.reg_type & ni_reg_m_series_mask) == 0)
+ s->len_chanlist = board->n_aochan;
+ if ((board->reg_type & ni_reg_m_series_mask) == 0)
s->munge = ni_ao_munge;
}
s->cancel = &ni_ao_reset;
} else {
s->type = COMEDI_SUBD_UNUSED;
}
- if ((boardtype.reg_type & ni_reg_67xx_mask))
+ if ((board->reg_type & ni_reg_67xx_mask))
init_ao_67xx(dev, s);
/* digital i/o subdevice */
@@ -4449,8 +4476,8 @@ static int ni_E_init(struct comedi_device *dev)
s->maxdata = 1;
s->io_bits = 0; /* all bits input */
s->range_table = &range_digital;
- s->n_chan = boardtype.num_p0_dio_channels;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->n_chan = board->num_p0_dio_channels;
+ if (board->reg_type & ni_reg_m_series_mask) {
s->subdev_flags |=
SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ;
s->insn_bits = &ni_m_series_dio_insn_bits;
@@ -4472,7 +4499,7 @@ static int ni_E_init(struct comedi_device *dev)
/* 8255 device */
s = &dev->subdevices[NI_8255_DIO_SUBDEV];
- if (boardtype.has_8255) {
+ if (board->has_8255) {
subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev);
} else {
s->type = COMEDI_SUBD_UNUSED;
@@ -4485,14 +4512,14 @@ static int ni_E_init(struct comedi_device *dev)
/* calibration subdevice -- ai and ao */
s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
s->type = COMEDI_SUBD_CALIB;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
/* internal PWM analog output used for AI nonlinearity calibration */
s->subdev_flags = SDF_INTERNAL;
s->insn_config = &ni_m_series_pwm_config;
s->n_chan = 1;
s->maxdata = 0;
ni_writel(0x0, M_Offset_Cal_PWM);
- } else if (boardtype.reg_type == ni_reg_6143) {
+ } else if (board->reg_type == ni_reg_6143) {
/* internal PWM analog output used for AI nonlinearity calibration */
s->subdev_flags = SDF_INTERNAL;
s->insn_config = &ni_6143_pwm_config;
@@ -4510,7 +4537,7 @@ static int ni_E_init(struct comedi_device *dev)
s->type = COMEDI_SUBD_MEMORY;
s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
s->maxdata = 0xff;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
s->n_chan = M_SERIES_EEPROM_SIZE;
s->insn_read = &ni_m_series_eeprom_insn_read;
} else {
@@ -4522,7 +4549,7 @@ static int ni_E_init(struct comedi_device *dev)
s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
s->type = COMEDI_SUBD_DIO;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
unsigned i;
s->n_chan = 16;
ni_writew(s->state, M_Offset_PFI_DO);
@@ -4534,7 +4561,7 @@ static int ni_E_init(struct comedi_device *dev)
s->n_chan = 10;
}
s->maxdata = 1;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
s->insn_bits = &ni_pfi_insn_bits;
}
s->insn_config = &ni_pfi_insn_config;
@@ -4542,11 +4569,11 @@ static int ni_E_init(struct comedi_device *dev)
/* cs5529 calibration adc */
s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
- if (boardtype.reg_type & ni_reg_67xx_mask) {
+ if (board->reg_type & ni_reg_67xx_mask) {
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
/* one channel for each analog output channel */
- s->n_chan = boardtype.n_aochan;
+ s->n_chan = board->n_aochan;
s->maxdata = (1 << 16) - 1;
s->range_table = &range_unknown; /* XXX */
s->insn_read = cs5529_ai_insn_read;
@@ -4576,7 +4603,7 @@ static int ni_E_init(struct comedi_device *dev)
s->insn_config = ni_rtsi_insn_config;
ni_rtsi_init(dev);
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
counter_variant = ni_gpct_variant_m_series;
} else {
counter_variant = ni_gpct_variant_e_series;
@@ -4594,7 +4621,7 @@ static int ni_E_init(struct comedi_device *dev)
SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
/* | SDF_CMD_WRITE */ ;
s->n_chan = 3;
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
s->maxdata = 0xffffffff;
else
s->maxdata = 0xffffff;
@@ -4626,7 +4653,7 @@ static int ni_E_init(struct comedi_device *dev)
/* ai configuration */
s = &dev->subdevices[NI_AI_SUBDEV];
ni_ai_reset(dev, s);
- if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) {
+ if ((board->reg_type & ni_reg_6xxx_mask) == 0) {
/* BEAM is this needed for PCI-6143 ?? */
devpriv->clock_and_fout =
Slow_Internal_Time_Divide_By_2 |
@@ -4663,11 +4690,11 @@ static int ni_E_init(struct comedi_device *dev)
ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
- if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ if (board->reg_type & ni_reg_6xxx_mask) {
ni_writeb(0, Magic_611x);
- } else if (boardtype.reg_type & ni_reg_m_series_mask) {
+ } else if (board->reg_type & ni_reg_m_series_mask) {
int channel;
- for (channel = 0; channel < boardtype.n_aochan; ++channel) {
+ for (channel = 0; channel < board->n_aochan; ++channel) {
ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
ni_writeb(0x0,
M_Offset_AO_Reference_Attenuation(channel));
@@ -4938,6 +4965,7 @@ static struct caldac_struct caldacs[] = {
static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
int i, j;
int n_dacs;
@@ -4947,12 +4975,12 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
int type;
int chan;
- type = boardtype.caldac[0];
+ type = board->caldac[0];
if (type == caldac_none)
return;
n_bits = caldacs[type].n_bits;
for (i = 0; i < 3; i++) {
- type = boardtype.caldac[i];
+ type = board->caldac[i];
if (type == caldac_none)
break;
if (caldacs[type].n_bits != n_bits)
@@ -4971,7 +4999,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
chan = 0;
for (i = 0; i < n_dacs; i++) {
- type = boardtype.caldac[i];
+ type = board->caldac[i];
for (j = 0; j < caldacs[type].n_chans; j++) {
maxdata_list[chan] =
(1 << caldacs[type].n_bits) - 1;
@@ -4982,7 +5010,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
for (chan = 0; chan < s->n_chan; chan++)
ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
} else {
- type = boardtype.caldac[0];
+ type = board->caldac[0];
s->maxdata = (1 << caldacs[type].n_bits) - 1;
for (chan = 0; chan < s->n_chan; chan++)
@@ -4992,6 +5020,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
int i;
@@ -5003,7 +5032,7 @@ static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
devpriv->caldacs[addr] = val;
for (i = 0; i < 3; i++) {
- type = boardtype.caldac[i];
+ type = board->caldac[i];
if (type == caldac_none)
break;
if (addr < caldacs[type].n_chans) {
@@ -5275,7 +5304,9 @@ static int ni_old_set_pfi_routing(struct comedi_device *dev, unsigned chan,
static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
unsigned source)
{
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ const struct ni_board_struct *board = comedi_board(dev);
+
+ if (board->reg_type & ni_reg_m_series_mask)
return ni_m_series_set_pfi_routing(dev, chan, source);
else
return ni_old_set_pfi_routing(dev, chan, source);
@@ -5336,7 +5367,9 @@ static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, unsigned chan)
static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
{
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ const struct ni_board_struct *board = comedi_board(dev);
+
+ if (board->reg_type & ni_reg_m_series_mask)
return ni_m_series_get_pfi_routing(dev, chan);
else
return ni_old_get_pfi_routing(dev, chan);
@@ -5345,10 +5378,11 @@ static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
enum ni_pfi_filter_select filter)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv __maybe_unused = dev->private;
unsigned bits;
- if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ if ((board->reg_type & ni_reg_m_series_mask) == 0) {
return -ENOTSUPP;
}
bits = ni_readl(M_Offset_PFI_Filter);
@@ -5362,9 +5396,10 @@ static int ni_pfi_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv __maybe_unused = dev->private;
- if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ if ((board->reg_type & ni_reg_m_series_mask) == 0) {
return -ENOTSUPP;
}
if (data[0]) {
@@ -5423,6 +5458,7 @@ static int ni_pfi_insn_config(struct comedi_device *dev,
*/
static void ni_rtsi_init(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
/* Initialises the RTSI bus signal switch to a default state */
@@ -5449,7 +5485,7 @@ static void ni_rtsi_init(struct comedi_device *dev)
RTSI_Trig_Output_Bits(5,
NI_RTSI_OUTPUT_G_SRC0) |
RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0);
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
devpriv->rtsi_trig_b_output_reg |=
RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
@@ -5517,7 +5553,9 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
{
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ const struct ni_board_struct *board = comedi_board(dev);
+
+ if (board->reg_type & ni_reg_m_series_mask)
return 8;
else
return 7;
@@ -5629,6 +5667,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
unsigned period_ns)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
if (source == NI_MIO_INTERNAL_CLOCK) {
@@ -5636,7 +5675,7 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
RTSI_Trig_Direction_Register);
devpriv->clock_ns = TIMEBASE_1_NS;
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
devpriv->clock_and_fout2 &=
~(MSeries_Timebase1_Select_Bit |
MSeries_Timebase3_Select_Bit);
@@ -5646,7 +5685,7 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
}
devpriv->clock_source = source;
} else {
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
return ni_mseries_set_pll_master_clock(dev, source,
period_ns);
} else {
@@ -5676,6 +5715,8 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
unsigned source)
{
+ const struct ni_board_struct *board = comedi_board(dev);
+
if (chan >= num_configurable_rtsi_channels(dev)) {
if (chan == old_RTSI_clock_channel) {
if (source == NI_RTSI_OUTPUT_RTSI_OSC)
@@ -5702,7 +5743,7 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
return 1;
break;
case NI_RTSI_OUTPUT_RTSI_OSC:
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
return 1;
else
return 0;
@@ -5758,6 +5799,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
@@ -5766,9 +5808,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
if (chan < num_configurable_rtsi_channels(dev)) {
devpriv->rtsi_trig_direction_reg |=
RTSI_Output_Bit(chan,
- (boardtype.
- reg_type & ni_reg_m_series_mask) !=
- 0);
+ (board->reg_type & ni_reg_m_series_mask) != 0);
} else if (chan == old_RTSI_clock_channel) {
devpriv->rtsi_trig_direction_reg |=
Drive_RTSI_Clock_Bit;
@@ -5780,9 +5820,7 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
if (chan < num_configurable_rtsi_channels(dev)) {
devpriv->rtsi_trig_direction_reg &=
~RTSI_Output_Bit(chan,
- (boardtype.
- reg_type & ni_reg_m_series_mask)
- != 0);
+ (board->reg_type & ni_reg_m_series_mask) != 0);
} else if (chan == old_RTSI_clock_channel) {
devpriv->rtsi_trig_direction_reg &=
~Drive_RTSI_Clock_Bit;
@@ -5795,10 +5833,9 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
data[1] =
(devpriv->rtsi_trig_direction_reg &
RTSI_Output_Bit(chan,
- (boardtype.reg_type &
- ni_reg_m_series_mask)
- != 0)) ? INSN_CONFIG_DIO_OUTPUT :
- INSN_CONFIG_DIO_INPUT;
+ (board->reg_type & ni_reg_m_series_mask) != 0))
+ ? INSN_CONFIG_DIO_OUTPUT
+ : INSN_CONFIG_DIO_INPUT;
} else if (chan == old_RTSI_clock_channel) {
data[1] =
(devpriv->rtsi_trig_direction_reg &
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 0a00260d11f..b5f340c186e 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -280,29 +280,30 @@ enum FPGA_Control_Bits {
static int ni_pcidio_cancel(struct comedi_device *dev,
struct comedi_subdevice *s);
+enum nidio_boardid {
+ BOARD_PCIDIO_32HS,
+ BOARD_PXI6533,
+ BOARD_PCI6534,
+};
+
struct nidio_board {
- int dev_id;
const char *name;
unsigned int uses_firmware:1;
};
static const struct nidio_board nidio_boards[] = {
- {
- .dev_id = 0x1150,
+ [BOARD_PCIDIO_32HS] = {
.name = "pci-dio-32hs",
- }, {
- .dev_id = 0x1320,
+ },
+ [BOARD_PXI6533] = {
.name = "pxi-6533",
- }, {
- .dev_id = 0x12b0,
+ },
+ [BOARD_PCI6534] = {
.name = "pci-6534",
.uses_firmware = 1,
},
};
-#define n_nidio_boards ARRAY_SIZE(nidio_boards)
-#define this_board ((const struct nidio_board *)dev->board_ptr)
-
struct nidio96_private {
struct mite_struct *mite;
int boardtype;
@@ -419,7 +420,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
unsigned int m_status = 0;
/* interrupcions parasites */
- if (dev->attached == 0) {
+ if (!dev->attached) {
/* assume it's from another card */
return IRQ_NONE;
}
@@ -1094,29 +1095,27 @@ static int pci_6534_upload_firmware(struct comedi_device *dev)
return ret;
}
-static const struct nidio_board *
-nidio_find_boardinfo(struct pci_dev *pcidev)
-{
- unsigned int dev_id = pcidev->device;
- unsigned int n;
-
- for (n = 0; n < ARRAY_SIZE(nidio_boards); n++) {
- const struct nidio_board *board = &nidio_boards[n];
- if (board->dev_id == dev_id)
- return board;
- }
- return NULL;
-}
-
static int nidio_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ const struct nidio_board *board = NULL;
struct nidio96_private *devpriv;
struct comedi_subdevice *s;
int ret;
unsigned int irq;
+ if (context < ARRAY_SIZE(nidio_boards))
+ board = &nidio_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;
@@ -1124,9 +1123,6 @@ static int nidio_auto_attach(struct comedi_device *dev,
spin_lock_init(&devpriv->mite_channel_lock);
- dev->board_ptr = nidio_find_boardinfo(pcidev);
- if (!dev->board_ptr)
- return -ENODEV;
devpriv->mite = mite_alloc(pcidev);
if (!devpriv->mite)
return -ENOMEM;
@@ -1141,9 +1137,8 @@ static int nidio_auto_attach(struct comedi_device *dev,
if (devpriv->di_mite_ring == NULL)
return -ENOMEM;
- dev->board_name = this_board->name;
irq = mite_irq(devpriv->mite);
- if (this_board->uses_firmware) {
+ if (board->uses_firmware) {
ret = pci_6534_upload_firmware(dev);
if (ret < 0)
return ret;
@@ -1211,6 +1206,7 @@ static void nidio_detach(struct comedi_device *dev)
mite_free(devpriv->mite);
}
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver ni_pcidio_driver = {
@@ -1221,15 +1217,15 @@ static struct comedi_driver ni_pcidio_driver = {
};
static int ni_pcidio_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_pcidio_driver);
+ return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0) },
+ { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS },
+ { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 },
+ { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 98b43f2fc65..634d02303aa 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -111,7 +111,6 @@ Bugs:
*/
#include <linux/delay.h>
-#include <linux/delay.h>
#include "../comedidev.h"
@@ -158,1036 +157,894 @@ static const struct comedi_lrange range_ni_M_625x_ao = { 3, {
}
};
-static const struct comedi_lrange range_ni_M_622x_ao = { 1, {
- RANGE(-10, 10),
- }
+enum ni_pcimio_boardid {
+ BOARD_PCIMIO_16XE_50,
+ BOARD_PCIMIO_16XE_10,
+ BOARD_PCI6014,
+ BOARD_PXI6030E,
+ BOARD_PCIMIO_16E_1,
+ BOARD_PCIMIO_16E_4,
+ BOARD_PXI6040E,
+ BOARD_PCI6031E,
+ BOARD_PCI6032E,
+ BOARD_PCI6033E,
+ BOARD_PCI6071E,
+ BOARD_PCI6023E,
+ BOARD_PCI6024E,
+ BOARD_PCI6025E,
+ BOARD_PXI6025E,
+ BOARD_PCI6034E,
+ BOARD_PCI6035E,
+ BOARD_PCI6052E,
+ BOARD_PCI6110,
+ BOARD_PCI6111,
+ /* BOARD_PCI6115, */
+ /* BOARD_PXI6115, */
+ BOARD_PCI6711,
+ BOARD_PXI6711,
+ BOARD_PCI6713,
+ BOARD_PXI6713,
+ BOARD_PCI6731,
+ /* BOARD_PXI6731, */
+ BOARD_PCI6733,
+ BOARD_PXI6733,
+ BOARD_PXI6071E,
+ BOARD_PXI6070E,
+ BOARD_PXI6052E,
+ BOARD_PXI6031E,
+ BOARD_PCI6036E,
+ BOARD_PCI6220,
+ BOARD_PCI6221,
+ BOARD_PCI6221_37PIN,
+ BOARD_PCI6224,
+ BOARD_PXI6224,
+ BOARD_PCI6225,
+ BOARD_PXI6225,
+ BOARD_PCI6229,
+ BOARD_PCI6250,
+ BOARD_PCI6251,
+ BOARD_PCIE6251,
+ BOARD_PXIE6251,
+ BOARD_PCI6254,
+ BOARD_PCI6259,
+ BOARD_PCIE6259,
+ BOARD_PCI6280,
+ BOARD_PCI6281,
+ BOARD_PXI6281,
+ BOARD_PCI6284,
+ BOARD_PCI6289,
+ BOARD_PCI6143,
+ BOARD_PXI6143,
};
static const struct ni_board_struct ni_boards[] = {
- {
- .device_id = 0x0162, /* NI also says 0x1620. typo? */
- .name = "pci-mio-16xe-50",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 2048,
- .alwaysdither = 1,
- .gainlkup = ai_gain_8,
- .ai_speed = 50000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 50000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043},
- .has_8255 = 0,
- },
- {
- .device_id = 0x1170,
- .name = "pci-mio-16xe-10", /* aka pci-6030E */
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {
- .device_id = 0x28c0,
- .name = "pci-6014",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 100000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x11d0,
- .name = "pxi-6030e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {
- .device_id = 0x1180,
- .name = "pci-mio-16e-1", /* aka pci-6070e */
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341},
- .has_8255 = 0,
- },
- {
- .device_id = 0x1190,
- .name = "pci-mio-16e-4", /* aka pci-6040e */
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- /* .Note = there have been reported problems with full speed
- * on this board */
- .ai_speed = 2000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 512,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug}, /* doc says mb88341 */
- .has_8255 = 0,
- },
- {
- .device_id = 0x11c0,
- .name = "pxi-6040e",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 512,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341},
- .has_8255 = 0,
- },
-
- {
- .device_id = 0x1330,
- .name = "pci-6031e",
- .n_adchan = 64,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {
- .device_id = 0x1270,
- .name = "pci-6032e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {
- .device_id = 0x1340,
- .name = "pci-6033e",
- .n_adchan = 64,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {
- .device_id = 0x1350,
- .name = "pci-6071e",
- .n_adchan = 64,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x2a60,
- .name = "pci-6023e",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug}, /* manual is wrong */
- .has_8255 = 0,
- },
- {
- .device_id = 0x2a70,
- .name = "pci-6024e",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 100000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug}, /* manual is wrong */
- .has_8255 = 0,
- },
- {
- .device_id = 0x2a80,
- .name = "pci-6025e",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 100000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug}, /* manual is wrong */
- .has_8255 = 1,
- },
- {
- .device_id = 0x2ab0,
- .name = "pxi-6025e",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 100000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug}, /* manual is wrong */
- .has_8255 = 1,
- },
-
- {
- .device_id = 0x2ca0,
- .name = "pci-6034e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x2c80,
- .name = "pci-6035e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 100000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x18b0,
- .name = "pci-6052e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 3000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_unipolar = 1,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 3000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug, ad8804_debug, ad8522}, /* manual is wrong */
- },
- {.device_id = 0x14e0,
- .name = "pci-6110",
- .n_adchan = 4,
- .adbits = 12,
- .ai_fifo_depth = 8192,
- .alwaysdither = 0,
- .gainlkup = ai_gain_611x,
- .ai_speed = 200,
- .n_aochan = 2,
- .aobits = 16,
- .reg_type = ni_reg_611x,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804, ad8804},
- },
- {
- .device_id = 0x14f0,
- .name = "pci-6111",
- .n_adchan = 2,
- .adbits = 12,
- .ai_fifo_depth = 8192,
- .alwaysdither = 0,
- .gainlkup = ai_gain_611x,
- .ai_speed = 200,
- .n_aochan = 2,
- .aobits = 16,
- .reg_type = ni_reg_611x,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804, ad8804},
- },
+ [BOARD_PCIMIO_16XE_50] = {
+ .name = "pci-mio-16xe-50",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 2048,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_8,
+ .ai_speed = 50000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 50000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043 },
+ },
+ [BOARD_PCIMIO_16XE_10] = {
+ .name = "pci-mio-16xe-10", /* aka pci-6030E */
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
+ [BOARD_PCI6014] = {
+ .name = "pci-6014",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PXI6030E] = {
+ .name = "pxi-6030e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
+ [BOARD_PCIMIO_16E_1] = {
+ .name = "pci-mio-16e-1", /* aka pci-6070e */
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = { mb88341 },
+ },
+ [BOARD_PCIMIO_16E_4] = {
+ .name = "pci-mio-16e-4", /* aka pci-6040e */
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ /*
+ * there have been reported problems with
+ * full speed on this board
+ */
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 512,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug }, /* doc says mb88341 */
+ },
+ [BOARD_PXI6040E] = {
+ .name = "pxi-6040e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 512,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = { mb88341 },
+ },
+ [BOARD_PCI6031E] = {
+ .name = "pci-6031e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
+ [BOARD_PCI6032E] = {
+ .name = "pci-6032e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
+ [BOARD_PCI6033E] = {
+ .name = "pci-6033e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
+ [BOARD_PCI6071E] = {
+ .name = "pci-6071e",
+ .n_adchan = 64,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PCI6023E] = {
+ .name = "pci-6023e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug }, /* manual is wrong */
+ },
+ [BOARD_PCI6024E] = {
+ .name = "pci-6024e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug }, /* manual is wrong */
+ },
+ [BOARD_PCI6025E] = {
+ .name = "pci-6025e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug }, /* manual is wrong */
+ .has_8255 = 1,
+ },
+ [BOARD_PXI6025E] = {
+ .name = "pxi-6025e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug }, /* manual is wrong */
+ .has_8255 = 1,
+ },
+ [BOARD_PCI6034E] = {
+ .name = "pci-6034e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PCI6035E] = {
+ .name = "pci-6035e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PCI6052E] = {
+ .name = "pci-6052e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 3000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_unipolar = 1,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 3000,
+ .num_p0_dio_channels = 8,
+ /* manual is wrong */
+ .caldac = { ad8804_debug, ad8804_debug, ad8522 },
+ },
+ [BOARD_PCI6110] = {
+ .name = "pci-6110",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 200,
+ .n_aochan = 2,
+ .aobits = 16,
+ .reg_type = ni_reg_611x,
+ .ao_range_table = &range_bipolar10,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804, ad8804 },
+ },
+ [BOARD_PCI6111] = {
+ .name = "pci-6111",
+ .n_adchan = 2,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 200,
+ .n_aochan = 2,
+ .aobits = 16,
+ .reg_type = ni_reg_611x,
+ .ao_range_table = &range_bipolar10,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804, ad8804 },
+ },
#if 0
/* The 6115 boards probably need their own driver */
- {
- .device_id = 0x2ed0,
- .name = "pci-6115",
- .n_adchan = 4,
- .adbits = 12,
- .ai_fifo_depth = 8192,
- .alwaysdither = 0,
- .gainlkup = ai_gain_611x,
- .ai_speed = 100,
- .n_aochan = 2,
- .aobits = 16,
- .ao_671x = 1,
- .ao_unipolar = 0,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .num_p0_dio_channels = 8,
- .reg_611x = 1,
- .caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */
- },
+ [BOARD_PCI6115] = { /* .device_id = 0x2ed0, */
+ .name = "pci-6115",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 100,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_671x = 1,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .reg_611x = 1,
+ /* XXX */
+ .caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
+ },
#endif
#if 0
- {
- .device_id = 0x0000,
- .name = "pxi-6115",
- .n_adchan = 4,
- .adbits = 12,
- .ai_fifo_depth = 8192,
- .alwaysdither = 0,
- .gainlkup = ai_gain_611x,
- .ai_speed = 100,
- .n_aochan = 2,
- .aobits = 16,
- .ao_671x = 1,
- .ao_unipolar = 0,
- .ao_fifo_depth = 2048,
- .ao_speed = 250,
- .reg_611x = 1,
- .num_p0_dio_channels = 8,
- caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */
- },
+ [BOARD_PXI6115] = { /* .device_id = ????, */
+ .name = "pxi-6115",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 100,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_671x = 1,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .reg_611x = 1,
+ .num_p0_dio_channels = 8,
+ /* XXX */
+ .caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
+ },
#endif
- {
- .device_id = 0x1880,
- .name = "pci-6711",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 4,
- .aobits = 12,
- .ao_unipolar = 0,
- .ao_fifo_depth = 16384,
- /* data sheet says 8192, but fifo really holds 16384 samples */
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6711,
- .caldac = {ad8804_debug},
- },
- {
- .device_id = 0x2b90,
- .name = "pxi-6711",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 4,
- .aobits = 12,
- .ao_unipolar = 0,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6711,
- .caldac = {ad8804_debug},
- },
- {
- .device_id = 0x1870,
- .name = "pci-6713",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 8,
- .aobits = 12,
- .ao_unipolar = 0,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6713,
- .caldac = {ad8804_debug, ad8804_debug},
- },
- {
- .device_id = 0x2b80,
- .name = "pxi-6713",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 8,
- .aobits = 12,
- .ao_unipolar = 0,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6713,
- .caldac = {ad8804_debug, ad8804_debug},
- },
- {
- .device_id = 0x2430,
- .name = "pci-6731",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 4,
- .aobits = 16,
- .ao_unipolar = 0,
- .ao_fifo_depth = 8192,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6711,
- .caldac = {ad8804_debug},
- },
-#if 0 /* need device ids */
- {
- .device_id = 0x0,
- .name = "pxi-6731",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 4,
- .aobits = 16,
- .ao_unipolar = 0,
- .ao_fifo_depth = 8192,
- .ao_range_table = &range_bipolar10,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6711,
- .caldac = {ad8804_debug},
- },
+ [BOARD_PCI6711] = {
+ .name = "pci-6711",
+ .n_aochan = 4,
+ .aobits = 12,
+ /* data sheet says 8192, but fifo really holds 16384 samples */
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PXI6711] = {
+ .name = "pxi-6711",
+ .n_aochan = 4,
+ .aobits = 12,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PCI6713] = {
+ .name = "pci-6713",
+ .n_aochan = 8,
+ .aobits = 12,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = { ad8804_debug, ad8804_debug },
+ },
+ [BOARD_PXI6713] = {
+ .name = "pxi-6713",
+ .n_aochan = 8,
+ .aobits = 12,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = { ad8804_debug, ad8804_debug },
+ },
+ [BOARD_PCI6731] = {
+ .name = "pci-6731",
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8192,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = { ad8804_debug },
+ },
+#if 0
+ [BOARD_PXI6731] = { /* .device_id = ????, */
+ .name = "pxi-6731",
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8192,
+ .ao_range_table = &range_bipolar10,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = { ad8804_debug },
+ },
#endif
- {
- .device_id = 0x2410,
- .name = "pci-6733",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 8,
- .aobits = 16,
- .ao_unipolar = 0,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6713,
- .caldac = {ad8804_debug, ad8804_debug},
- },
- {
- .device_id = 0x2420,
- .name = "pxi-6733",
- .n_adchan = 0, /* no analog input */
- .n_aochan = 8,
- .aobits = 16,
- .ao_unipolar = 0,
- .ao_fifo_depth = 16384,
- .ao_range_table = &range_bipolar10,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_6713,
- .caldac = {ad8804_debug, ad8804_debug},
- },
- {
- .device_id = 0x15b0,
- .name = "pxi-6071e",
- .n_adchan = 64,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x11b0,
- .name = "pxi-6070e",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x18c0,
- .name = "pxi-6052e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_16,
- .ai_speed = 3000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_unipolar = 1,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_speed = 3000,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341, mb88341, ad8522},
- },
- {
- .device_id = 0x1580,
- .name = "pxi-6031e",
- .n_adchan = 64,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_14,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- },
- {
- .device_id = 0x2890,
- .name = "pci-6036e",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1,
- .gainlkup = ai_gain_4,
- .ai_speed = 5000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_bipolar10,
- .ao_unipolar = 0,
- .ao_speed = 100000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70b0,
- .name = "pci-6220",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- /* .FIXME = guess */
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .num_p0_dio_channels = 8,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70af,
- .name = "pci-6221",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_622x_ao,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .ao_speed = 1200,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x71bc,
- .name = "pci-6221_37pin",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_622x_ao,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .ao_speed = 1200,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70f2,
- .name = "pci-6224",
- .n_adchan = 32,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70f3,
- .name = "pxi-6224",
- .n_adchan = 32,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x716c,
- .name = "pci-6225",
- .n_adchan = 80,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_622x_ao,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .ao_speed = 1200,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x716d,
- .name = "pxi-6225",
- .n_adchan = 80,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_622x_ao,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .ao_speed = 1200,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
+ [BOARD_PCI6733] = {
+ .name = "pci-6733",
+ .n_aochan = 8,
+ .aobits = 16,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = { ad8804_debug, ad8804_debug },
+ },
+ [BOARD_PXI6733] = {
+ .name = "pxi-6733",
+ .n_aochan = 8,
+ .aobits = 16,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = { ad8804_debug, ad8804_debug },
+ },
+ [BOARD_PXI6071E] = {
+ .name = "pxi-6071e",
+ .n_adchan = 64,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PXI6070E] = {
+ .name = "pxi-6070e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PXI6052E] = {
+ .name = "pxi-6052e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 3000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_unipolar = 1,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 3000,
+ .num_p0_dio_channels = 8,
+ .caldac = { mb88341, mb88341, ad8522 },
+ },
+ [BOARD_PXI6031E] = {
+ .name = "pxi-6031e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
+ [BOARD_PCI6036E] = {
+ .name = "pci-6036e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug },
+ },
+ [BOARD_PCI6220] = {
+ .name = "pci-6220",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512, /* FIXME: guess */
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_622x,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6221] = {
+ .name = "pci-6221",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6221_37PIN] = {
+ .name = "pci-6221_37pin",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6224] = {
+ .name = "pci-6224",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .reg_type = ni_reg_622x,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PXI6224] = {
+ .name = "pxi-6224",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .reg_type = ni_reg_622x,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6225] = {
+ .name = "pci-6225",
+ .n_adchan = 80,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PXI6225] = {
+ .name = "pxi-6225",
+ .n_adchan = 80,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6229] = {
+ .name = "pci-6229",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6250] = {
+ .name = "pci-6250",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .reg_type = ni_reg_625x,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6251] = {
+ .name = "pci-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCIE6251] = {
+ .name = "pcie-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PXIE6251] = {
+ .name = "pxie-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6254] = {
+ .name = "pci-6254",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .reg_type = ni_reg_625x,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6259] = {
+ .name = "pci-6259",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCIE6259] = {
+ .name = "pcie-6259",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6280] = {
+ .name = "pci-6280",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .ao_fifo_depth = 8191,
+ .reg_type = ni_reg_628x,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6281] = {
+ .name = "pci-6281",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PXI6281] = {
+ .name = "pxi-6281",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6284] = {
+ .name = "pci-6284",
+ .n_adchan = 32,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .reg_type = ni_reg_628x,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6289] = {
+ .name = "pci-6289",
+ .n_adchan = 32,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 350,
+ .num_p0_dio_channels = 32,
+ .caldac = { caldac_none },
+ },
+ [BOARD_PCI6143] = {
+ .name = "pci-6143",
+ .n_adchan = 8,
+ .adbits = 16,
+ .ai_fifo_depth = 1024,
+ .gainlkup = ai_gain_6143,
+ .ai_speed = 4000,
+ .reg_type = ni_reg_6143,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug, ad8804_debug },
+ },
+ [BOARD_PXI6143] = {
+ .name = "pxi-6143",
+ .n_adchan = 8,
+ .adbits = 16,
+ .ai_fifo_depth = 1024,
+ .gainlkup = ai_gain_6143,
+ .ai_speed = 4000,
+ .reg_type = ni_reg_6143,
+ .num_p0_dio_channels = 8,
+ .caldac = { ad8804_debug, ad8804_debug },
},
- {
- .device_id = 0x70aa,
- .name = "pci-6229",
- .n_adchan = 32,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_622x,
- .ai_speed = 4000,
- .n_aochan = 4,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_622x_ao,
- .reg_type = ni_reg_622x,
- .ao_unipolar = 0,
- .ao_speed = 1200,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70b4,
- .name = "pci-6250",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70b8,
- .name = "pci-6251",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .ao_speed = 350,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x717d,
- .name = "pcie-6251",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .ao_speed = 350,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x72e8,
- .name = "pxie-6251",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .ao_speed = 350,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70b7,
- .name = "pci-6254",
- .n_adchan = 32,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70ab,
- .name = "pci-6259",
- .n_adchan = 32,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 4,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .ao_speed = 350,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x717f,
- .name = "pcie-6259",
- .n_adchan = 32,
- .adbits = 16,
- .ai_fifo_depth = 4095,
- .gainlkup = ai_gain_628x,
- .ai_speed = 800,
- .n_aochan = 4,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_625x_ao,
- .reg_type = ni_reg_625x,
- .ao_unipolar = 0,
- .ao_speed = 350,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70b6,
- .name = "pci-6280",
- .n_adchan = 16,
- .adbits = 18,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 8191,
- .reg_type = ni_reg_628x,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70bd,
- .name = "pci-6281",
- .n_adchan = 16,
- .adbits = 18,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_unipolar = 1,
- .ao_speed = 350,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70bf,
- .name = "pxi-6281",
- .n_adchan = 16,
- .adbits = 18,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 2,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_unipolar = 1,
- .ao_speed = 350,
- .num_p0_dio_channels = 8,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70bc,
- .name = "pci-6284",
- .n_adchan = 32,
- .adbits = 18,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 0,
- .aobits = 0,
- .ao_fifo_depth = 0,
- .reg_type = ni_reg_628x,
- .ao_unipolar = 0,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70ac,
- .name = "pci-6289",
- .n_adchan = 32,
- .adbits = 18,
- .ai_fifo_depth = 2047,
- .gainlkup = ai_gain_628x,
- .ai_speed = 1600,
- .n_aochan = 4,
- .aobits = 16,
- .ao_fifo_depth = 8191,
- .ao_range_table = &range_ni_M_628x_ao,
- .reg_type = ni_reg_628x,
- .ao_unipolar = 1,
- .ao_speed = 350,
- .num_p0_dio_channels = 32,
- .caldac = {caldac_none},
- .has_8255 = 0,
- },
- {
- .device_id = 0x70C0,
- .name = "pci-6143",
- .n_adchan = 8,
- .adbits = 16,
- .ai_fifo_depth = 1024,
- .alwaysdither = 0,
- .gainlkup = ai_gain_6143,
- .ai_speed = 4000,
- .n_aochan = 0,
- .aobits = 0,
- .reg_type = ni_reg_6143,
- .ao_unipolar = 0,
- .ao_fifo_depth = 0,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug, ad8804_debug},
- },
- {
- .device_id = 0x710D,
- .name = "pxi-6143",
- .n_adchan = 8,
- .adbits = 16,
- .ai_fifo_depth = 1024,
- .alwaysdither = 0,
- .gainlkup = ai_gain_6143,
- .ai_speed = 4000,
- .n_aochan = 0,
- .aobits = 0,
- .reg_type = ni_reg_6143,
- .ao_unipolar = 0,
- .ao_fifo_depth = 0,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug, ad8804_debug},
- },
};
struct ni_private {
@@ -1569,6 +1426,7 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev)
static void init_6143(struct comedi_device *dev)
{
+ const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
/* Disable interrupts */
@@ -1579,7 +1437,8 @@ static void init_6143(struct comedi_device *dev)
ni_writeb(0x80, PipelineDelay_6143); /* Set EOCMode, ADCMode and pipelinedelay */
ni_writeb(0x00, EOC_Set_6143); /* Set EOC Delay */
- ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143); /* Set the FIFO half full level */
+ /* Set the FIFO half full level */
+ ni_writel(board->ai_fifo_depth / 2, AIFIFO_Flag_6143);
/* Strobe Relay disable bit */
devpriv->ai_calib_source_enabled = 0;
@@ -1606,48 +1465,38 @@ static void pcimio_detach(struct comedi_device *dev)
mite_free(devpriv->mite);
}
}
-}
-
-static const struct ni_board_struct *
-pcimio_find_boardinfo(struct pci_dev *pcidev)
-{
- unsigned int device_id = pcidev->device;
- unsigned int n;
-
- for (n = 0; n < ARRAY_SIZE(ni_boards); n++) {
- const struct ni_board_struct *board = &ni_boards[n];
- if (board->device_id == device_id)
- return board;
- }
- return NULL;
+ comedi_pci_disable(dev);
}
static int pcimio_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_board_struct *board = NULL;
struct ni_private *devpriv;
int ret;
- dev_info(dev->class_dev, "ni_pcimio: attach %s\n", pci_name(pcidev));
+ if (context < ARRAY_SIZE(ni_boards))
+ board = &ni_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_alloc_private(dev);
if (ret)
return ret;
devpriv = dev->private;
- dev->board_ptr = pcimio_find_boardinfo(pcidev);
- if (!dev->board_ptr)
- return -ENODEV;
-
devpriv->mite = mite_alloc(pcidev);
if (!devpriv->mite)
return -ENOMEM;
- dev_dbg(dev->class_dev, "%s\n", boardtype.name);
- dev->board_name = boardtype.name;
-
- if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (board->reg_type & ni_reg_m_series_mask) {
devpriv->stc_writew = &m_series_stc_writew;
devpriv->stc_readw = &m_series_stc_readw;
devpriv->stc_writel = &m_series_stc_writel;
@@ -1681,9 +1530,9 @@ static int pcimio_auto_attach(struct comedi_device *dev,
if (devpriv->gpct_mite_ring[1] == NULL)
return -ENOMEM;
- if (boardtype.reg_type & ni_reg_m_series_mask)
+ if (board->reg_type & ni_reg_m_series_mask)
m_series_init_eeprom_buffer(dev);
- if (boardtype.reg_type == ni_reg_6143)
+ if (board->reg_type == ni_reg_6143)
init_6143(dev);
dev->irq = mite_irq(devpriv->mite);
@@ -1788,65 +1637,66 @@ static struct comedi_driver ni_pcimio_driver = {
};
static int ni_pcimio_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_pcimio_driver);
+ return comedi_pci_auto_config(dev, &ni_pcimio_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(ni_pcimio_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0162) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1170) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1180) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1190) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11b0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11c0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11d0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1270) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1330) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1340) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1350) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14e0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14f0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1580) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x15b0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1880) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1870) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18b0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18c0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2410) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2420) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2430) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2890) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x28c0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a60) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a70) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a80) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ab0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b80) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b90) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c80) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ca0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70aa) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ab) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ac) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70af) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b4) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b6) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b7) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b8) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bc) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bd) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bf) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c0) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70f2) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x710d) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716c) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716d) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d) },
- { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x72e8) },
+ { PCI_VDEVICE(NI, 0x0162), BOARD_PCIMIO_16XE_50 }, /* 0x1620? */
+ { PCI_VDEVICE(NI, 0x1170), BOARD_PCIMIO_16XE_10 },
+ { PCI_VDEVICE(NI, 0x1180), BOARD_PCIMIO_16E_1 },
+ { PCI_VDEVICE(NI, 0x1190), BOARD_PCIMIO_16E_4 },
+ { PCI_VDEVICE(NI, 0x11b0), BOARD_PXI6070E },
+ { PCI_VDEVICE(NI, 0x11c0), BOARD_PXI6040E },
+ { PCI_VDEVICE(NI, 0x11d0), BOARD_PXI6030E },
+ { PCI_VDEVICE(NI, 0x1270), BOARD_PCI6032E },
+ { PCI_VDEVICE(NI, 0x1330), BOARD_PCI6031E },
+ { PCI_VDEVICE(NI, 0x1340), BOARD_PCI6033E },
+ { PCI_VDEVICE(NI, 0x1350), BOARD_PCI6071E },
+ { PCI_VDEVICE(NI, 0x14e0), BOARD_PCI6110 },
+ { PCI_VDEVICE(NI, 0x14f0), BOARD_PCI6111 },
+ { PCI_VDEVICE(NI, 0x1580), BOARD_PXI6031E },
+ { PCI_VDEVICE(NI, 0x15b0), BOARD_PXI6071E },
+ { PCI_VDEVICE(NI, 0x1880), BOARD_PCI6711 },
+ { PCI_VDEVICE(NI, 0x1870), BOARD_PCI6713 },
+ { PCI_VDEVICE(NI, 0x18b0), BOARD_PCI6052E },
+ { PCI_VDEVICE(NI, 0x18c0), BOARD_PXI6052E },
+ { PCI_VDEVICE(NI, 0x2410), BOARD_PCI6733 },
+ { PCI_VDEVICE(NI, 0x2420), BOARD_PXI6733 },
+ { PCI_VDEVICE(NI, 0x2430), BOARD_PCI6731 },
+ { PCI_VDEVICE(NI, 0x2890), BOARD_PCI6036E },
+ { PCI_VDEVICE(NI, 0x28c0), BOARD_PCI6014 },
+ { PCI_VDEVICE(NI, 0x2a60), BOARD_PCI6023E },
+ { PCI_VDEVICE(NI, 0x2a70), BOARD_PCI6024E },
+ { PCI_VDEVICE(NI, 0x2a80), BOARD_PCI6025E },
+ { PCI_VDEVICE(NI, 0x2ab0), BOARD_PXI6025E },
+ { PCI_VDEVICE(NI, 0x2b80), BOARD_PXI6713 },
+ { PCI_VDEVICE(NI, 0x2b90), BOARD_PXI6711 },
+ { PCI_VDEVICE(NI, 0x2c80), BOARD_PCI6035E },
+ { PCI_VDEVICE(NI, 0x2ca0), BOARD_PCI6034E },
+ { PCI_VDEVICE(NI, 0x70aa), BOARD_PCI6229 },
+ { PCI_VDEVICE(NI, 0x70ab), BOARD_PCI6259 },
+ { PCI_VDEVICE(NI, 0x70ac), BOARD_PCI6289 },
+ { PCI_VDEVICE(NI, 0x70af), BOARD_PCI6221 },
+ { PCI_VDEVICE(NI, 0x70b0), BOARD_PCI6220 },
+ { PCI_VDEVICE(NI, 0x70b4), BOARD_PCI6250 },
+ { PCI_VDEVICE(NI, 0x70b6), BOARD_PCI6280 },
+ { PCI_VDEVICE(NI, 0x70b7), BOARD_PCI6254 },
+ { PCI_VDEVICE(NI, 0x70b8), BOARD_PCI6251 },
+ { PCI_VDEVICE(NI, 0x70bc), BOARD_PCI6284 },
+ { PCI_VDEVICE(NI, 0x70bd), BOARD_PCI6281 },
+ { PCI_VDEVICE(NI, 0x70bf), BOARD_PXI6281 },
+ { PCI_VDEVICE(NI, 0x70c0), BOARD_PCI6143 },
+ { PCI_VDEVICE(NI, 0x70f2), BOARD_PCI6224 },
+ { PCI_VDEVICE(NI, 0x70f3), BOARD_PXI6224 },
+ { PCI_VDEVICE(NI, 0x710d), BOARD_PXI6143 },
+ { PCI_VDEVICE(NI, 0x716c), BOARD_PCI6225 },
+ { PCI_VDEVICE(NI, 0x716d), BOARD_PXI6225 },
+ { PCI_VDEVICE(NI, 0x717f), BOARD_PCIE6259 },
+ { PCI_VDEVICE(NI, 0x71bc), BOARD_PCI6221_37PIN },
+ { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 },
+ { PCI_VDEVICE(NI, 0x72e8), BOARD_PXIE6251 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
index 504ea715533..0a613c07760 100644
--- a/drivers/staging/comedi/drivers/ni_stc.h
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -1421,10 +1421,6 @@ struct ni_board_struct {
enum caldac_enum caldac[3];
};
-#define n_ni_boards (sizeof(ni_boards)/sizeof(struct ni_board_struct))
-
-#define boardtype (*(struct ni_board_struct *)dev->board_ptr)
-
#define MAX_N_AO_CHAN 8
#define NUM_GPCT 2
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 6ee5da24a96..8be2a4c503c 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -451,23 +451,12 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct pcl711_board *board = comedi_board(dev);
struct pcl711_private *devpriv;
int ret;
- unsigned long iobase;
unsigned int irq;
struct comedi_subdevice *s;
- /* claim our I/O space */
-
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: pcl711: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, PCL711_SIZE, "pcl711")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- /* there should be a sanity check here */
-
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0], PCL711_SIZE);
+ if (ret)
+ return ret;
/* grab our IRQ */
irq = it->options[1];
@@ -476,7 +465,8 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -EINVAL;
}
if (irq) {
- if (request_irq(irq, pcl711_interrupt, 0, "pcl711", dev)) {
+ if (request_irq(irq, pcl711_interrupt, 0, dev->board_name,
+ dev)) {
printk(KERN_ERR "unable to allocate irq %u\n", irq);
return -EINVAL;
} else {
@@ -560,14 +550,6 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void pcl711_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, PCL711_SIZE);
-}
-
static const struct pcl711_board boardtypes[] = {
{ "pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5 },
{ "pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai },
@@ -579,7 +561,7 @@ static struct comedi_driver pcl711_driver = {
.driver_name = "pcl711",
.module = THIS_MODULE,
.attach = pcl711_attach,
- .detach = pcl711_detach,
+ .detach = comedi_legacy_detach,
.board_name = &boardtypes[0].name,
.num_names = ARRAY_SIZE(boardtypes),
.offset = sizeof(struct pcl711_board),
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index 7b3c4293c01..4f033d88eec 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -100,28 +100,19 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl724_board *board = comedi_board(dev);
struct comedi_subdevice *s;
- unsigned long iobase;
unsigned int iorange;
int ret, i, n_subdevices;
#ifdef PCL724_IRQ
unsigned int irq;
#endif
- iobase = it->options[0];
iorange = board->io_range;
- if ((board->can_have96) && ((it->options[1] == 1)
- || (it->options[1] == 96)))
+ if ((board->can_have96) &&
+ ((it->options[1] == 1) || (it->options[1] == 96)))
iorange = PCL722_96_SIZE; /* PCL-724 in 96 DIO configuration */
- printk(KERN_INFO "comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
- board->name, iobase);
- if (!request_region(iobase, iorange, "pcl724")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
-
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0], iorange);
+ if (ret)
+ return ret;
#ifdef PCL724_IRQ
irq = 0;
@@ -134,8 +125,8 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
"DISABLING IT", irq);
irq = 0; /* Bad IRQ */
} else {
- if (request_irq
- (irq, interrupt_pcl724, 0, "pcl724", dev)) {
+ if (request_irq(irq, interrupt_pcl724, 0,
+ dev->board_name, dev)) {
printk(KERN_WARNING
", unable to allocate IRQ %u, "
"DISABLING IT", irq);
@@ -178,19 +169,11 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void pcl724_detach(struct comedi_device *dev)
{
- const struct pcl724_board *board = comedi_board(dev);
- struct comedi_subdevice *s;
int i;
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- subdev_8255_cleanup(dev, s);
- }
-#ifdef PCL724_IRQ
- if (dev->irq)
- free_irq(dev->irq, dev);
-#endif
- release_region(dev->iobase, board->io_range);
+ for (i = 0; i < dev->n_subdevices; i++)
+ comedi_spriv_free(dev, i);
+ comedi_legacy_detach(dev);
}
static const struct pcl724_board boardtypes[] = {
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
index 21fbc1ae1e7..6b02f0631b4 100644
--- a/drivers/staging/comedi/drivers/pcl725.c
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -45,18 +45,11 @@ static int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s,
static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct comedi_subdevice *s;
- unsigned long iobase;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->board_name = "pcl725";
- dev->iobase = iobase;
- dev->irq = 0;
+ ret = comedi_request_region(dev, it->options[0], PCL725_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
@@ -85,17 +78,11 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void pcl725_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, PCL725_SIZE);
-}
-
static struct comedi_driver pcl725_driver = {
.driver_name = "pcl725",
.module = THIS_MODULE,
.attach = pcl725_attach,
- .detach = pcl725_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(pcl725_driver);
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
index 50e01968f19..4aa994393fa 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -90,9 +90,6 @@ Interrupts are not supported.
#define PCL727_DI_HI 0
#define PCL727_DI_LO 1
-static const struct comedi_lrange range_4_20mA = { 1, {RANGE_mA(4, 20)} };
-static const struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
-
static const struct comedi_lrange *const rangelist_726[] = {
&range_unipolar5, &range_unipolar10,
&range_bipolar5, &range_bipolar10,
@@ -228,25 +225,14 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct pcl726_board *board = comedi_board(dev);
struct pcl726_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
- unsigned int iorange;
int ret, i;
#ifdef ACL6126_IRQ
unsigned int irq;
#endif
- iobase = it->options[0];
- iorange = board->io_range;
- printk(KERN_WARNING "comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
- board->name, iobase);
- if (!request_region(iobase, iorange, "pcl726")) {
- printk(KERN_WARNING "I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
-
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0], board->io_range);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -271,7 +257,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
irq = 0; /* Bad IRQ */
} else {
if (request_irq(irq, interrupt_pcl818, 0,
- "pcl726", dev)) {
+ dev->board_name, dev)) {
printk(KERN_WARNING
", unable to allocate IRQ %d,"
" DISABLING IT", irq);
@@ -349,23 +335,11 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void pcl726_detach(struct comedi_device *dev)
-{
- const struct pcl726_board *board = comedi_board(dev);
-
-#ifdef ACL6126_IRQ
- if (dev->irq)
- free_irq(dev->irq, dev);
-#endif
- if (dev->iobase)
- release_region(dev->iobase, board->io_range);
-}
-
static struct comedi_driver pcl726_driver = {
.driver_name = "pcl726",
.module = THIS_MODULE,
.attach = pcl726_attach,
- .detach = pcl726_detach,
+ .detach = comedi_legacy_detach,
.board_name = &boardtypes[0].name,
.num_names = ARRAY_SIZE(boardtypes),
.offset = sizeof(struct pcl726_board),
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index e3de4993745..2879db75da3 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -64,21 +64,11 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl730_board *board = comedi_board(dev);
struct comedi_subdevice *s;
- unsigned long iobase;
- unsigned int iorange;
int ret;
- iobase = it->options[0];
- iorange = board->io_range;
- printk(KERN_INFO "comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
- board->name, iobase);
- if (!request_region(iobase, iorange, "pcl730")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->board_name = board->name;
- dev->iobase = iobase;
- dev->irq = 0;
+ ret = comedi_request_region(dev, it->options[0], board->io_range);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@@ -129,14 +119,6 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void pcl730_detach(struct comedi_device *dev)
-{
- const struct pcl730_board *board = comedi_board(dev);
-
- if (dev->iobase)
- release_region(dev->iobase, board->io_range);
-}
-
static const struct pcl730_board boardtypes[] = {
{ "pcl730", PCL730_SIZE, },
{ "iso730", PCL730_SIZE, },
@@ -147,7 +129,7 @@ static struct comedi_driver pcl730_driver = {
.driver_name = "pcl730",
.module = THIS_MODULE,
.attach = pcl730_attach,
- .detach = pcl730_detach,
+ .detach = comedi_legacy_detach,
.board_name = &boardtypes[0].name,
.num_names = ARRAY_SIZE(boardtypes),
.offset = sizeof(struct pcl730_board),
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 560930e6a8e..cd02786702c 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -1041,28 +1041,6 @@ static void start_pacer(struct comedi_device *dev, int mode,
/*
==============================================================================
*/
-static void free_resources(struct comedi_device *dev)
-{
- const struct pcl812_board *board = comedi_board(dev);
- struct pcl812_private *devpriv = dev->private;
-
- if (devpriv) {
- if (devpriv->dmabuf[0])
- free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
- if (devpriv->dmabuf[1])
- free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
- if (devpriv->dma)
- free_dma(devpriv->dma);
- }
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, board->io_range);
-}
-
-/*
-==============================================================================
-*/
static int pcl812_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
@@ -1122,32 +1100,21 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct pcl812_board *board = comedi_board(dev);
struct pcl812_private *devpriv;
int ret, subdev;
- unsigned long iobase;
unsigned int irq;
unsigned int dma;
unsigned long pages;
struct comedi_subdevice *s;
int n_subdevices;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: pcl812: board=%s, ioport=0x%03lx",
- dev->minor, board->name, iobase);
-
- if (!request_region(iobase, board->io_range, "pcl812")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], board->io_range);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
- if (!devpriv) {
- free_resources(dev);
+ if (!devpriv)
return -ENOMEM;
- }
dev->private = devpriv;
- dev->board_name = board->name;
-
irq = 0;
if (board->IRQbits != 0) { /* board support IRQ */
irq = it->options[1];
@@ -1158,8 +1125,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
"DISABLING IT", irq);
irq = 0; /* Bad IRQ */
} else {
- if (request_irq
- (irq, interrupt_pcl812, 0, "pcl812", dev)) {
+ if (request_irq(irq, interrupt_pcl812, 0,
+ dev->board_name, dev)) {
printk
(", unable to allocate IRQ %u, "
"DISABLING IT", irq);
@@ -1183,7 +1150,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
printk(", DMA is out of allowed range, FAIL!\n");
return -EINVAL; /* Bad DMA */
}
- ret = request_dma(dma, "pcl812");
+ ret = request_dma(dma, dev->board_name);
if (ret) {
printk(KERN_ERR ", unable to allocate DMA %u, FAIL!\n",
dma);
@@ -1199,7 +1166,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
* maybe experiment with try_to_free_pages()
* will help ....
*/
- free_resources(dev);
return -EBUSY; /* no buffer :-( */
}
devpriv->dmapages[0] = pages;
@@ -1208,7 +1174,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
if (!devpriv->dmabuf[1]) {
printk(KERN_ERR ", unable to allocate DMA buffer, FAIL!\n");
- free_resources(dev);
return -EBUSY;
}
devpriv->dmapages[1] = pages;
@@ -1228,10 +1193,8 @@ no_dma:
n_subdevices++;
ret = comedi_alloc_subdevices(dev, n_subdevices);
- if (ret) {
- free_resources(dev);
+ if (ret)
return ret;
- }
subdev = 0;
@@ -1465,7 +1428,17 @@ no_dma:
static void pcl812_detach(struct comedi_device *dev)
{
- free_resources(dev);
+ struct pcl812_private *devpriv = dev->private;
+
+ if (devpriv) {
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ }
+ comedi_legacy_detach(dev);
}
static const struct pcl812_board boardtypes[] = {
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index f625fdab335..91bd2071f57 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -35,10 +35,10 @@ Configuration Options:
#include "../comedidev.h"
#include <linux/ioport.h>
-#include <linux/mc146818rtc.h>
#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
#include <asm/dma.h>
#include "comedi_fc.h"
@@ -82,14 +82,6 @@ Configuration Options:
#define INT_TYPE_AI1_DMA 2
#define INT_TYPE_AI3_INT 4
#define INT_TYPE_AI3_DMA 5
-#ifdef unused
-#define INT_TYPE_AI1_DMA_RTC 9
-#define INT_TYPE_AI3_DMA_RTC 10
-
-/* RTC stuff... */
-#define RTC_IRQ 8
-#define RTC_IO_EXTENT 0x10
-#endif
#define MAGIC_DMA_WORD 0x5a5a
@@ -126,26 +118,14 @@ struct pcl816_board {
int i8254_osc_base; /* 1/frequency of on board oscilator in ns */
};
-#ifdef unused
-static int RTC_lock; /* RTC lock */
-static int RTC_timer_lock; /* RTC int lock */
-#endif
-
struct pcl816_private {
unsigned int dma; /* used DMA, 0=don't use DMA */
- int dma_rtc; /* 1=RTC used with DMA, 0=no RTC alloc */
-#ifdef unused
- unsigned long rtc_iobase; /* RTC port region */
- unsigned int rtc_iosize;
- unsigned int rtc_irq;
-#endif
unsigned long dmabuf[2]; /* pointers to begin of DMA buffers */
unsigned int dmapages[2]; /* len of DMA buffers in PAGE_SIZEs */
unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */
unsigned int hwdmasize[2]; /* len of DMA buffers in Bytes */
unsigned int dmasamplsize; /* size in samples hwdmasize[0]/2 */
- unsigned int last_top_dma; /* DMA pointer in last RTC int */
int next_dma_buf; /* which DMA buffer will be used next round */
long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */
unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */
@@ -154,9 +134,6 @@ struct pcl816_private {
unsigned char ai_neverending; /* if=1, then we do neverending record (you must use cancel()) */
int irq_free; /* 1=have allocated IRQ */
int irq_blocked; /* 1=IRQ now uses any subdev */
-#ifdef unused
- int rtc_irq_blocked; /* 1=we now do AI with DMA&RTC */
-#endif
int irq_was_now_closed; /* when IRQ finish, there's stored int816_mode for last interrupt */
int int816_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */
struct comedi_subdevice *last_int_sub; /* ptr to subdevice which now finish */
@@ -167,10 +144,6 @@ struct pcl816_private {
unsigned int ai_n_chan; /* how many channels per scan */
unsigned int ai_poll_ptr; /* how many sampes transfer poll */
struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */
-#ifdef unused
- struct timer_list rtc_irq_timer; /* timer for RTC sanity check */
- unsigned long rtc_freq; /* RTC int freq */
-#endif
};
/*
@@ -186,9 +159,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s);
static void start_pacer(struct comedi_device *dev, int mode,
unsigned int divisor1, unsigned int divisor2);
-#ifdef unused
-static int set_rtc_irq_bit(unsigned char bit);
-#endif
static int pcl816_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -718,12 +688,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
if (devpriv->irq_blocked > 0) {
switch (devpriv->int816_mode) {
-#ifdef unused
- case INT_TYPE_AI1_DMA_RTC:
- case INT_TYPE_AI3_DMA_RTC:
- set_rtc_irq_bit(0); /* stop RTC */
- del_timer(&devpriv->rtc_irq_timer);
-#endif
case INT_TYPE_AI1_DMA:
case INT_TYPE_AI3_DMA:
disable_dma(devpriv->dma);
@@ -837,7 +801,7 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
/*
==============================================================================
- Check if channel list from user is builded correctly
+ Check if channel list from user is built correctly
If it's ok, then return non-zero length of repeated segment of channel list
*/
static int
@@ -939,67 +903,21 @@ setup_channel_list(struct comedi_device *dev,
dev->iobase + PCL816_MUX);
}
-#ifdef unused
-/*
-==============================================================================
- Enable(1)/disable(0) periodic interrupts from RTC
-*/
-static int set_rtc_irq_bit(unsigned char bit)
-{
- unsigned char val;
- unsigned long flags;
-
- if (bit == 1) {
- RTC_timer_lock++;
- if (RTC_timer_lock > 1)
- return 0;
- } else {
- RTC_timer_lock--;
- if (RTC_timer_lock < 0)
- RTC_timer_lock = 0;
- if (RTC_timer_lock > 0)
- return 0;
- }
-
- save_flags(flags);
- cli();
- val = CMOS_READ(RTC_CONTROL);
- if (bit)
- val |= RTC_PIE;
- else
- val &= ~RTC_PIE;
-
- CMOS_WRITE(val, RTC_CONTROL);
- CMOS_READ(RTC_INTR_FLAGS);
- restore_flags(flags);
- return 0;
-}
-#endif
-
static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl816_board *board = comedi_board(dev);
struct pcl816_private *devpriv;
int ret;
- unsigned long iobase;
unsigned int irq, dma;
unsigned long pages;
/* int i; */
struct comedi_subdevice *s;
- /* claim our I/O space */
- iobase = it->options[0];
- printk("comedi%d: pcl816: board=%s, ioport=0x%03lx", dev->minor,
- board->name, iobase);
-
- if (!request_region(iobase, board->io_range, "pcl816")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], board->io_range);
+ if (ret)
+ return ret;
- if (pcl816_check(iobase)) {
+ if (pcl816_check(dev->iobase)) {
printk(KERN_ERR ", I cann't detect board. FAIL!\n");
return -EIO;
}
@@ -1009,8 +927,6 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -ENOMEM;
dev->private = devpriv;
- dev->board_name = board->name;
-
/* grab our IRQ */
irq = 0;
if (board->IRQbits != 0) { /* board support IRQ */
@@ -1022,8 +938,8 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
"DISABLING IT", irq);
irq = 0; /* Bad IRQ */
} else {
- if (request_irq
- (irq, interrupt_pcl816, 0, "pcl816", dev)) {
+ if (request_irq(irq, interrupt_pcl816, 0,
+ dev->board_name, dev)) {
printk
(", unable to allocate IRQ %u, "
"DISABLING IT", irq);
@@ -1044,46 +960,10 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */
devpriv->int816_mode = 0; /* mode of irq */
-#ifdef unused
- /* grab RTC for DMA operations */
- devpriv->dma_rtc = 0;
- if (it->options[2] > 0) { /* we want to use DMA */
- if (RTC_lock == 0) {
- if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
- "pcl816 (RTC)"))
- goto no_rtc;
- }
- devpriv->rtc_iobase = RTC_PORT(0);
- devpriv->rtc_iosize = RTC_IO_EXTENT;
- RTC_lock++;
-#ifdef UNTESTED_CODE
- if (!request_irq(RTC_IRQ, interrupt_pcl816_ai_mode13_dma_rtc, 0,
- "pcl816 DMA (RTC)", dev)) {
- devpriv->dma_rtc = 1;
- devpriv->rtc_irq = RTC_IRQ;
- printk(", dma_irq=%u", devpriv->rtc_irq);
- } else {
- RTC_lock--;
- if (RTC_lock == 0) {
- if (devpriv->rtc_iobase)
- release_region(devpriv->rtc_iobase,
- devpriv->rtc_iosize);
- }
- devpriv->rtc_iobase = 0;
- devpriv->rtc_iosize = 0;
- }
-#else
- printk("pcl816: RTC code missing");
-#endif
-
- }
-
-no_rtc:
-#endif
/* grab our DMA */
dma = 0;
devpriv->dma = dma;
- if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+ if (!devpriv->irq_free)
goto no_dma; /* if we haven't IRQ, we can't use DMA */
if (board->DMAbits != 0) { /* board support DMA */
@@ -1095,7 +975,7 @@ no_rtc:
printk(", DMA is out of allowed range, FAIL!\n");
return -EINVAL; /* Bad DMA */
}
- ret = request_dma(dma, "pcl816");
+ ret = request_dma(dma, dev->board_name);
if (ret) {
printk(KERN_ERR
", unable to allocate DMA %u, FAIL!\n", dma);
@@ -1120,19 +1000,16 @@ no_rtc:
devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
/* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */
- if (devpriv->dma_rtc == 0) { /* we must do duble buff :-( */
- devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
- if (!devpriv->dmabuf[1]) {
- printk(KERN_ERR
- ", unable to allocate DMA buffer, "
- "FAIL!\n");
- return -EBUSY;
- }
- devpriv->dmapages[1] = pages;
- devpriv->hwdmaptr[1] =
- virt_to_bus((void *)devpriv->dmabuf[1]);
- devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ printk(KERN_ERR
+ ", unable to allocate DMA buffer, "
+ "FAIL!\n");
+ return -EBUSY;
}
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
}
no_dma:
@@ -1205,7 +1082,6 @@ case COMEDI_SUBD_DO:
static void pcl816_detach(struct comedi_device *dev)
{
- const struct pcl816_board *board = comedi_board(dev);
struct pcl816_private *devpriv = dev->private;
if (dev->private) {
@@ -1217,24 +1093,8 @@ static void pcl816_detach(struct comedi_device *dev)
free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
if (devpriv->dmabuf[1])
free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
-#ifdef unused
- if (devpriv->rtc_irq)
- free_irq(devpriv->rtc_irq, dev);
- if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
- if (devpriv->rtc_iobase)
- release_region(devpriv->rtc_iobase,
- devpriv->rtc_iosize);
- }
-#endif
}
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, board->io_range);
-#ifdef unused
- if (devpriv->dma_rtc)
- RTC_lock--;
-#endif
+ comedi_legacy_detach(dev);
}
static const struct pcl816_board boardtypes[] = {
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index b5af22eb7c3..91cb1bd6717 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -98,15 +98,15 @@ A word or two about DMA. Driver support DMA operations at two ways:
*/
-#include "../comedidev.h"
-
#include <linux/ioport.h>
-#include <linux/mc146818rtc.h>
#include <linux/gfp.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/interrupt.h>
#include <asm/dma.h>
+#include "../comedidev.h"
+
#include "comedi_fc.h"
#include "8253.h"
@@ -186,15 +186,6 @@ A word or two about DMA. Driver support DMA operations at two ways:
#define INT_TYPE_AO3_INT 8
#endif
-#ifdef unused
-/* RTC stuff... */
-#define INT_TYPE_AI1_DMA_RTC 9
-#define INT_TYPE_AI3_DMA_RTC 10
-
-#define RTC_IRQ 8
-#define RTC_IO_EXTENT 0x10
-#endif
-
#define MAGIC_DMA_WORD 0x5a5a
static const struct comedi_lrange range_pcl818h_ai = { 9, {
@@ -248,11 +239,6 @@ static const struct comedi_lrange range718_bipolar0_5 = {
static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} };
static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} };
-#ifdef unused
-static int RTC_lock; /* RTC lock */
-static int RTC_timer_lock; /* RTC int lock */
-#endif
-
struct pcl818_board {
const char *name; /* driver name */
@@ -277,22 +263,11 @@ struct pcl818_board {
struct pcl818_private {
unsigned int dma; /* used DMA, 0=don't use DMA */
- int dma_rtc; /* 1=RTC used with DMA, 0=no RTC alloc */
unsigned int io_range;
-#ifdef unused
- unsigned long rtc_iobase; /* RTC port region */
- unsigned int rtc_iosize;
- unsigned int rtc_irq;
- struct timer_list rtc_irq_timer; /* timer for RTC sanity check */
- unsigned long rtc_freq; /* RTC int freq */
- int rtc_irq_blocked; /* 1=we now do AI with DMA&RTC */
-#endif
unsigned long dmabuf[2]; /* pointers to begin of DMA buffers */
unsigned int dmapages[2]; /* len of DMA buffers in PAGE_SIZEs */
unsigned int hwdmaptr[2]; /* hardware address of DMA buffers */
unsigned int hwdmasize[2]; /* len of DMA buffers in Bytes */
- unsigned int dmasamplsize; /* size in samples hwdmasize[0]/2 */
- unsigned int last_top_dma; /* DMA pointer in last RTC int */
int next_dma_buf; /* which DMA buffer will be used next round */
long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */
unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */
@@ -342,12 +317,6 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
static void start_pacer(struct comedi_device *dev, int mode,
unsigned int divisor1, unsigned int divisor2);
-#ifdef unused
-static int set_rtc_irq_bit(unsigned char bit);
-static void rtc_dropped_irq(unsigned long data);
-static int rtc_setfreq_irq(int freq);
-#endif
-
/*
==============================================================================
ANALOG INPUT MODE0, 818 cards, slow version
@@ -610,113 +579,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
return IRQ_HANDLED;
}
-#ifdef unused
-/*
-==============================================================================
- analog input dma mode 1 & 3 over RTC, 818 cards
-*/
-static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct pcl818_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[0];
- unsigned long tmp;
- unsigned int top1, top2, i, bufptr;
- long ofs_dats;
- short *dmabuf = (short *)devpriv->dmabuf[0];
-
- /* outb(2,0x378); */
- switch (devpriv->ai_mode) {
- case INT_TYPE_AI1_DMA_RTC:
- case INT_TYPE_AI3_DMA_RTC:
- tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
- mod_timer(&devpriv->rtc_irq_timer,
- jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
-
- for (i = 0; i < 10; i++) {
- top1 = get_dma_residue(devpriv->dma);
- top2 = get_dma_residue(devpriv->dma);
- if (top1 == top2)
- break;
- }
-
- if (top1 != top2)
- return IRQ_HANDLED;
- top1 = devpriv->hwdmasize[0] - top1; /* where is now DMA in buffer */
- top1 >>= 1;
- ofs_dats = top1 - devpriv->last_top_dma; /* new samples from last call */
- if (ofs_dats < 0)
- ofs_dats = (devpriv->dmasamplsize) + ofs_dats;
- if (!ofs_dats)
- return IRQ_HANDLED; /* exit=no new samples from last call */
- /* obsluz data */
- i = devpriv->last_top_dma - 1;
- i &= (devpriv->dmasamplsize - 1);
-
- if (dmabuf[i] != MAGIC_DMA_WORD) { /* DMA overflow! */
- comedi_error(dev, "A/D mode1/3 DMA buffer overflow!");
- /* printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize); */
- pcl818_ai_cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
- return IRQ_HANDLED;
- }
- /* printk("r %ld ",ofs_dats); */
-
- bufptr = devpriv->last_top_dma;
-
- for (i = 0; i < ofs_dats; i++) {
- if ((dmabuf[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */
- printk
- ("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",
- (dmabuf[bufptr] & 0xf),
- devpriv->
- act_chanlist[devpriv->act_chanlist_pos]);
- pcl818_ai_cancel(dev, s);
- s->async->events |=
- COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
- return IRQ_HANDLED;
- }
-
- comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */
- bufptr &= (devpriv->dmasamplsize - 1);
-
- devpriv->act_chanlist_pos++;
- if (devpriv->act_chanlist_pos >=
- devpriv->act_chanlist_len) {
- devpriv->act_chanlist_pos = 0;
- }
- s->async->cur_chan++;
- if (s->async->cur_chan >= devpriv->ai_n_chan) {
- s->async->cur_chan = 0;
- devpriv->ai_act_scan--;
- }
-
- if (!devpriv->neverending_ai)
- if (devpriv->ai_act_scan == 0) { /* all data sampled */
- pcl818_ai_cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA;
- comedi_event(dev, s);
- /* printk("done int ai13 dma\n"); */
- return IRQ_HANDLED;
- }
- }
-
- devpriv->last_top_dma = bufptr;
- bufptr--;
- bufptr &= (devpriv->dmasamplsize - 1);
- dmabuf[bufptr] = MAGIC_DMA_WORD;
- comedi_event(dev, s);
- /* outb(0,0x378); */
- return IRQ_HANDLED;
- }
-
- /* outb(0,0x378); */
- return IRQ_HANDLED;
-}
-#endif
-
/*
==============================================================================
analog input interrupt mode 1 & 3, 818HD/HG cards
@@ -900,49 +762,6 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev,
};
}
-#ifdef unused
-/*
-==============================================================================
- ANALOG INPUT MODE 1 or 3 DMA rtc, 818 cards
-*/
-static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- struct pcl818_private *devpriv = dev->private;
- unsigned int flags;
- short *pole;
-
- set_dma_mode(devpriv->dma, DMA_MODE_READ | DMA_AUTOINIT);
- flags = claim_dma_lock();
- clear_dma_ff(devpriv->dma);
- set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
- set_dma_count(devpriv->dma, devpriv->hwdmasize[0]);
- release_dma_lock(flags);
- enable_dma(devpriv->dma);
- devpriv->last_top_dma = 0; /* devpriv->hwdmasize[0]; */
- pole = (short *)devpriv->dmabuf[0];
- devpriv->dmasamplsize = devpriv->hwdmasize[0] / 2;
- pole[devpriv->dmasamplsize - 1] = MAGIC_DMA_WORD;
-#ifdef unused
- devpriv->rtc_freq = rtc_setfreq_irq(2048);
- devpriv->rtc_irq_timer.expires =
- jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100;
- devpriv->rtc_irq_timer.data = (unsigned long)dev;
- devpriv->rtc_irq_timer.function = rtc_dropped_irq;
-
- add_timer(&devpriv->rtc_irq_timer);
-#endif
-
- if (mode == 1) {
- devpriv->int818_mode = INT_TYPE_AI1_DMA_RTC;
- outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+DMA */
- } else {
- devpriv->int818_mode = INT_TYPE_AI3_DMA_RTC;
- outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+DMA */
- };
-}
-#endif
-
/*
==============================================================================
ANALOG INPUT MODE 1 or 3, 818 cards
@@ -956,7 +775,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
unsigned int seglen;
dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode()\n");
- if ((!dev->irq) && (!devpriv->dma_rtc)) {
+ if (!dev->irq) {
comedi_error(dev, "IRQ not defined!");
return -EINVAL;
}
@@ -1005,15 +824,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
switch (devpriv->dma) {
case 1: /* DMA */
case 3:
- if (devpriv->dma_rtc == 0)
- pcl818_ai_mode13dma_int(mode, dev, s);
-#ifdef unused
- else
- pcl818_ai_mode13dma_rtc(mode, dev, s);
-#else
- else
- return -EINVAL;
-#endif
+ pcl818_ai_mode13dma_int(mode, dev, s);
break;
case 0:
if (!devpriv->usefifo) {
@@ -1047,97 +858,10 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
start_pacer(dev, mode, divisor1, divisor2);
-#ifdef unused
- switch (devpriv->ai_mode) {
- case INT_TYPE_AI1_DMA_RTC:
- case INT_TYPE_AI3_DMA_RTC:
- set_rtc_irq_bit(1); /* start RTC */
- break;
- }
-#endif
dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode() end\n");
return 0;
}
-#ifdef unused
-/*
-==============================================================================
- ANALOG OUTPUT MODE 1 or 3, 818 cards
-*/
-#ifdef PCL818_MODE13_AO
-static int pcl818_ao_mode13(int mode, struct comedi_device *dev,
- struct comedi_subdevice *s, comedi_trig *it)
-{
- struct pcl818_private *devpriv = dev->private;
- int divisor1 = 0, divisor2 = 0;
-
- if (!dev->irq) {
- comedi_error(dev, "IRQ not defined!");
- return -EINVAL;
- }
-
- if (devpriv->irq_blocked)
- return -EBUSY;
-
- start_pacer(dev, -1, 0, 0); /* stop pacer */
-
- devpriv->int13_act_scan = it->n;
- devpriv->int13_act_chan = 0;
- devpriv->irq_blocked = 1;
- devpriv->irq_was_now_closed = 0;
- devpriv->neverending_ai = 0;
- devpriv->act_chanlist_pos = 0;
-
- if (mode == 1) {
- i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
- &divisor2, &it->trigvar,
- TRIG_ROUND_NEAREST);
- if (divisor1 == 1) { /* PCL818 crash if any divisor is set to 1 */
- divisor1 = 2;
- divisor2 /= 2;
- }
- if (divisor2 == 1) {
- divisor2 = 2;
- divisor1 /= 2;
- }
- }
-
- outb(0, dev->iobase + PCL818_CNTENABLE); /* enable pacer */
- if (mode == 1) {
- devpriv->int818_mode = INT_TYPE_AO1_INT;
- outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
- } else {
- devpriv->int818_mode = INT_TYPE_AO3_INT;
- outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
- };
-
- start_pacer(dev, mode, divisor1, divisor2);
-
- return 0;
-}
-
-/*
-==============================================================================
- ANALOG OUTPUT MODE 1, 818 cards
-*/
-static int pcl818_ao_mode1(struct comedi_device *dev,
- struct comedi_subdevice *s, comedi_trig *it)
-{
- return pcl818_ao_mode13(1, dev, s, it);
-}
-
-/*
-==============================================================================
- ANALOG OUTPUT MODE 3, 818 cards
-*/
-static int pcl818_ao_mode3(struct comedi_device *dev,
- struct comedi_subdevice *s, comedi_trig *it)
-{
- return pcl818_ao_mode13(3, dev, s, it);
-}
-#endif
-#endif
-
/*
==============================================================================
Start/stop pacer onboard pacer
@@ -1391,12 +1115,6 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
devpriv->irq_was_now_closed = 1;
switch (devpriv->ai_mode) {
-#ifdef unused
- case INT_TYPE_AI1_DMA_RTC:
- case INT_TYPE_AI3_DMA_RTC:
- set_rtc_irq_bit(0); /* stop RTC */
- del_timer(&devpriv->rtc_irq_timer);
-#endif
case INT_TYPE_AI1_DMA:
case INT_TYPE_AI3_DMA:
if (devpriv->neverending_ai ||
@@ -1499,102 +1217,11 @@ static void pcl818_reset(struct comedi_device *dev)
}
}
-#ifdef unused
-/*
-==============================================================================
- Enable(1)/disable(0) periodic interrupts from RTC
-*/
-static int set_rtc_irq_bit(unsigned char bit)
-{
- unsigned char val;
- unsigned long flags;
-
- if (bit == 1) {
- RTC_timer_lock++;
- if (RTC_timer_lock > 1)
- return 0;
- } else {
- RTC_timer_lock--;
- if (RTC_timer_lock < 0)
- RTC_timer_lock = 0;
- if (RTC_timer_lock > 0)
- return 0;
- }
-
- save_flags(flags);
- cli();
- val = CMOS_READ(RTC_CONTROL);
- if (bit)
- val |= RTC_PIE;
- else
- val &= ~RTC_PIE;
-
- CMOS_WRITE(val, RTC_CONTROL);
- CMOS_READ(RTC_INTR_FLAGS);
- restore_flags(flags);
- return 0;
-}
-
-/*
-==============================================================================
- Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)
-*/
-static void rtc_dropped_irq(unsigned long data)
-{
- struct comedi_device *dev = (void *)data;
- struct pcl818_private *devpriv = dev->private;
- unsigned long flags, tmp;
-
- switch (devpriv->int818_mode) {
- case INT_TYPE_AI1_DMA_RTC:
- case INT_TYPE_AI3_DMA_RTC:
- mod_timer(&devpriv->rtc_irq_timer,
- jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
- save_flags(flags);
- cli();
- tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
- restore_flags(flags);
- break;
- }
-}
-
-/*
-==============================================================================
- Set frequency of interrupts from RTC
-*/
-static int rtc_setfreq_irq(int freq)
-{
- int tmp = 0;
- int rtc_freq;
- unsigned char val;
- unsigned long flags;
-
- if (freq < 2)
- freq = 2;
- if (freq > 8192)
- freq = 8192;
-
- while (freq > (1 << tmp))
- tmp++;
-
- rtc_freq = 1 << tmp;
-
- save_flags(flags);
- cli();
- val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
- val |= (16 - tmp);
- CMOS_WRITE(val, RTC_FREQ_SELECT);
- restore_flags(flags);
- return rtc_freq;
-}
-#endif
-
static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcl818_board *board = comedi_board(dev);
struct pcl818_private *devpriv;
int ret;
- unsigned long iobase;
unsigned int irq;
int dma;
unsigned long pages;
@@ -1605,31 +1232,21 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -ENOMEM;
dev->private = devpriv;
- /* claim our I/O space */
- iobase = it->options[0];
- printk
- ("comedi%d: pcl818: board=%s, ioport=0x%03lx",
- dev->minor, board->name, iobase);
devpriv->io_range = board->io_range;
if ((board->fifo) && (it->options[2] == -1)) {
/* we've board with FIFO and we want to use FIFO */
devpriv->io_range = PCLx1xFIFO_RANGE;
devpriv->usefifo = 1;
}
- if (!request_region(iobase, devpriv->io_range, "pcl818")) {
- comedi_error(dev, "I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], devpriv->io_range);
+ if (ret)
+ return ret;
- if (pcl818_check(iobase)) {
+ if (pcl818_check(dev->iobase)) {
comedi_error(dev, "I can't detect board. FAIL!\n");
return -EIO;
}
- dev->board_name = board->name;
-
/* grab our IRQ */
irq = 0;
if (board->IRQbits != 0) { /* board support IRQ */
@@ -1641,8 +1258,8 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
irq);
irq = 0; /* Bad IRQ */
} else {
- if (request_irq
- (irq, interrupt_pcl818, 0, "pcl818", dev)) {
+ if (request_irq(irq, interrupt_pcl818, 0,
+ dev->board_name, dev)) {
printk
(", unable to allocate IRQ %u, DISABLING IT",
irq);
@@ -1663,41 +1280,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */
devpriv->ai_mode = 0; /* mode of irq */
-#ifdef unused
- /* grab RTC for DMA operations */
- devpriv->dma_rtc = 0;
- if (it->options[2] > 0) { /* we want to use DMA */
- if (RTC_lock == 0) {
- if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
- "pcl818 (RTC)"))
- goto no_rtc;
- }
- devpriv->rtc_iobase = RTC_PORT(0);
- devpriv->rtc_iosize = RTC_IO_EXTENT;
- RTC_lock++;
- if (!request_irq(RTC_IRQ, interrupt_pcl818_ai_mode13_dma_rtc, 0,
- "pcl818 DMA (RTC)", dev)) {
- devpriv->dma_rtc = 1;
- devpriv->rtc_irq = RTC_IRQ;
- printk(KERN_DEBUG "dma_irq=%u", devpriv->rtc_irq);
- } else {
- RTC_lock--;
- if (RTC_lock == 0) {
- if (devpriv->rtc_iobase)
- release_region(devpriv->rtc_iobase,
- devpriv->rtc_iosize);
- }
- devpriv->rtc_iobase = 0;
- devpriv->rtc_iosize = 0;
- }
- }
-
-no_rtc:
-#endif
/* grab our DMA */
dma = 0;
devpriv->dma = dma;
- if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+ if (!devpriv->irq_free)
goto no_dma; /* if we haven't IRQ, we can't use DMA */
if (board->DMAbits != 0) { /* board support DMA */
dma = it->options[2];
@@ -1707,7 +1293,7 @@ no_rtc:
printk(KERN_ERR "DMA is out of allowed range, FAIL!\n");
return -EINVAL; /* Bad DMA */
}
- ret = request_dma(dma, "pcl818");
+ ret = request_dma(dma, dev->board_name);
if (ret)
return -EBUSY; /* DMA isn't free */
devpriv->dma = dma;
@@ -1720,15 +1306,12 @@ no_rtc:
devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
/* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */
- if (devpriv->dma_rtc == 0) { /* we must do duble buff :-( */
- devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
- if (!devpriv->dmabuf[1])
- return -EBUSY;
- devpriv->dmapages[1] = pages;
- devpriv->hwdmaptr[1] =
- virt_to_bus((void *)devpriv->dmabuf[1]);
- devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
- }
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1])
+ return -EBUSY;
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
}
no_dma:
@@ -1758,7 +1341,7 @@ no_dma:
s->range_table = board->ai_range_type;
s->cancel = pcl818_ai_cancel;
s->insn_read = pcl818_ai_insn_read;
- if ((irq) || (devpriv->dma_rtc)) {
+ if (irq) {
dev->read_subdev = s;
s->subdev_flags |= SDF_CMD_READ;
s->do_cmdtest = ai_cmdtest;
@@ -1815,14 +1398,6 @@ no_dma:
s->range_table = board->ao_range_type;
s->insn_read = pcl818_ao_insn_read;
s->insn_write = pcl818_ao_insn_write;
-#ifdef unused
-#ifdef PCL818_MODE13_AO
- if (irq) {
- s->trig[1] = pcl818_ao_mode1;
- s->trig[3] = pcl818_ao_mode3;
- }
-#endif
-#endif
if (board->is_818) {
if ((it->options[4] == 1) || (it->options[4] == 10))
s->range_table = &range_unipolar10;
@@ -1896,22 +1471,8 @@ static void pcl818_detach(struct comedi_device *dev)
free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
if (devpriv->dmabuf[1])
free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
-#ifdef unused
- if (devpriv->rtc_irq)
- free_irq(devpriv->rtc_irq, dev);
- if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
- if (devpriv->rtc_iobase)
- release_region(devpriv->rtc_iobase,
- devpriv->rtc_iosize);
- }
- if (devpriv->dma_rtc)
- RTC_lock--;
-#endif
}
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, devpriv->io_range);
+ comedi_legacy_detach(dev);
}
static const struct pcl818_board boardtypes[] = {
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index 5f062df1ead..4ef0df30b07 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -226,29 +226,16 @@ static int pcm3724_attach(struct comedi_device *dev,
{
struct priv_pcm3724 *priv;
struct comedi_subdevice *s;
- unsigned long iobase;
- unsigned int iorange;
int ret, i;
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
- iorange = PCM3724_SIZE;
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
dev->private = priv;
- printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
- dev->board_name, iobase);
- if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
-
- dev->iobase = iobase;
- printk(KERN_INFO "\n");
+ ret = comedi_request_region(dev, it->options[0], PCM3724_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
@@ -265,17 +252,11 @@ static int pcm3724_attach(struct comedi_device *dev,
static void pcm3724_detach(struct comedi_device *dev)
{
- struct comedi_subdevice *s;
int i;
- if (dev->subdevices) {
- for (i = 0; i < dev->n_subdevices; i++) {
- s = &dev->subdevices[i];
- subdev_8255_cleanup(dev, s);
- }
- }
- if (dev->iobase)
- release_region(dev->iobase, PCM3724_SIZE);
+ for (i = 0; i < dev->n_subdevices; i++)
+ comedi_spriv_free(dev, i);
+ comedi_legacy_detach(dev);
}
static struct comedi_driver pcm3724_driver = {
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
index 067f14d2261..3a3ce2c769a 100644
--- a/drivers/staging/comedi/drivers/pcm3730.c
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -54,19 +54,11 @@ static int pcm3730_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
struct comedi_subdevice *s;
- unsigned long iobase;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
- dev->board_name = "pcm3730";
- dev->iobase = dev->iobase;
- dev->irq = 0;
+ ret = comedi_request_region(dev, it->options[0], PCM3730_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 6);
if (ret)
@@ -131,17 +123,11 @@ static int pcm3730_attach(struct comedi_device *dev,
return 0;
}
-static void pcm3730_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, PCM3730_SIZE);
-}
-
static struct comedi_driver pcm3730_driver = {
.driver_name = "pcm3730",
.module = THIS_MODULE,
.attach = pcm3730_attach,
- .detach = pcm3730_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(pcm3730_driver);
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index 13e84215fac..b7c932e152e 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -105,18 +105,12 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct pcmad_board_struct *board = comedi_board(dev);
struct pcmad_priv_struct *devpriv;
- int ret;
struct comedi_subdevice *s;
- unsigned long iobase;
+ int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
- printk(KERN_CONT "I/O port conflict\n");
- return -EIO;
- }
- printk(KERN_CONT "\n");
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], PCMAD_SIZE);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
@@ -127,8 +121,6 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return -ENOMEM;
dev->private = devpriv;
- dev->board_name = board->name;
-
s = &dev->subdevices[0];
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | AREF_GROUND;
@@ -141,14 +133,6 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void pcmad_detach(struct comedi_device *dev)
-{
- if (dev->irq)
- free_irq(dev->irq, dev);
- if (dev->iobase)
- release_region(dev->iobase, PCMAD_SIZE);
-}
-
static const struct pcmad_board_struct pcmad_boards[] = {
{
.name = "pcmad12",
@@ -162,7 +146,7 @@ static struct comedi_driver pcmad_driver = {
.driver_name = "pcmad",
.module = THIS_MODULE,
.attach = pcmad_attach,
- .detach = pcmad_detach,
+ .detach = comedi_legacy_detach,
.board_name = &pcmad_boards[0].name,
.num_names = ARRAY_SIZE(pcmad_boards),
.offset = sizeof(pcmad_boards[0]),
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
index 13f79f49748..61e7fd14a1e 100644
--- a/drivers/staging/comedi/drivers/pcmda12.c
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -154,21 +154,11 @@ static int pcmda12_attach(struct comedi_device *dev,
{
struct pcmda12_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO
- "comedi%d: %s: io: %lx %s ", dev->minor, dev->driver->driver_name,
- iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
-
- if (!request_region(iobase, IOSIZE, dev->driver->driver_name)) {
- printk("I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- dev->board_name = dev->driver->driver_name;
+ ret = comedi_request_region(dev, it->options[0], IOSIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -193,22 +183,14 @@ static int pcmda12_attach(struct comedi_device *dev,
zero_chans(dev); /* clear out all the registers, basically */
- printk(KERN_INFO "attached\n");
-
return 1;
}
-static void pcmda12_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, IOSIZE);
-}
-
static struct comedi_driver pcmda12_driver = {
.driver_name = "pcmda12",
.module = THIS_MODULE,
.attach = pcmda12_attach,
- .detach = pcmda12_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(pcmda12_driver);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index 5fa1fe08eb9..5a236cd5b33 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -1034,24 +1034,14 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic,
thisasic_chanct = 0;
- unsigned long iobase;
unsigned int irq[MAX_ASICS];
int ret;
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
irq[0] = it->options[1];
- printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor,
- dev->board_name, iobase);
-
- dev->iobase = iobase;
-
- if (!iobase || !request_region(iobase, 32, dev->board_name)) {
- printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor);
- return -EIO;
- }
+ ret = comedi_request_region(dev, it->options[0], 32);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -1203,13 +1193,6 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
devpriv->asics[asic].irq = irq[asic];
}
- dev->irq = irq[0]; /*
- * grr.. wish comedi dev struct supported
- * multiple irqs..
- */
-
- printk(KERN_INFO "comedi%d: attached\n", dev->minor);
-
return 1;
}
@@ -1218,14 +1201,13 @@ static void pcmmio_detach(struct comedi_device *dev)
struct pcmmio_private *devpriv = dev->private;
int i;
- if (dev->iobase)
- release_region(dev->iobase, 32);
for (i = 0; i < MAX_ASICS; ++i) {
if (devpriv && devpriv->asics[i].irq)
free_irq(devpriv->asics[i].irq, dev);
}
if (devpriv && devpriv->sprivs)
kfree(devpriv->sprivs);
+ comedi_legacy_detach(dev);
}
static struct comedi_driver pcmmio_driver = {
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 433270ceda4..0c98e26bbba 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -800,27 +800,16 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct pcmuio_private *devpriv;
struct comedi_subdevice *s;
int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0;
- unsigned long iobase;
unsigned int irq[MAX_ASICS];
int ret;
- iobase = it->options[0];
irq[0] = it->options[1];
irq[1] = it->options[2];
- dev_dbg(dev->class_dev, "%s: io: %lx attach\n",
- dev->driver->driver_name, iobase);
-
- dev->iobase = iobase;
-
- if (!iobase || !request_region(iobase,
- board->num_asics * ASIC_IOSIZE,
- dev->driver->driver_name)) {
- dev_err(dev->class_dev, "I/O port conflict\n");
- return -EIO;
- }
-
- dev->board_name = board->name;
+ ret = comedi_request_region(dev, it->options[0],
+ board->num_asics * ASIC_IOSIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -928,9 +917,6 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
devpriv->asics[asic].irq = irq[asic];
}
- dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
- irqs.. */
-
if (irq[0]) {
dev_dbg(dev->class_dev, "irq: %u\n", irq[0]);
if (irq[1] && board->num_asics == 2)
@@ -946,18 +932,16 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
static void pcmuio_detach(struct comedi_device *dev)
{
- const struct pcmuio_board *board = comedi_board(dev);
struct pcmuio_private *devpriv = dev->private;
int i;
- if (dev->iobase)
- release_region(dev->iobase, ASIC_IOSIZE * board->num_asics);
for (i = 0; i < MAX_ASICS; ++i) {
if (devpriv->asics[i].irq)
free_irq(devpriv->asics[i].irq, dev);
}
if (devpriv && devpriv->sprivs)
kfree(devpriv->sprivs);
+ comedi_legacy_detach(dev);
}
static const struct pcmuio_board pcmuio_boards[] = {
diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h
index 5894739ff42..ff76fbb4b3e 100644
--- a/drivers/staging/comedi/drivers/plx9052.h
+++ b/drivers/staging/comedi/drivers/plx9052.h
@@ -27,60 +27,58 @@
#define _PLX9052_H_
/*
- * PLX PCI9052 INTCSR register.
+ * INTCSR - Interrupt Control/Status register
*/
-#define PLX9052_INTCSR 0x4C /* Offset in Local Configuration Registers */
-/* Local Interrupt 1 Enable */
-#define PLX9052_INTCSR_LI1ENAB_MASK 0x0001
-#define PLX9052_INTCSR_LI1ENAB_DISABLED 0x0000
-#define PLX9052_INTCSR_LI1ENAB_ENABLED 0x0001
-/* Local Interrupt 1 Polarity */
-#define PLX9052_INTCSR_LI1POL_MASK 0x0002
-#define PLX9052_INTCSR_LI1POL_LOW 0x0000
-#define PLX9052_INTCSR_LI1POL_HIGH 0x0002
-/* Local Interrupt 1 Status (read-only) */
-#define PLX9052_INTCSR_LI1STAT_MASK 0x0004
-#define PLX9052_INTCSR_LI1STAT_INACTIVE 0x0000
-#define PLX9052_INTCSR_LI1STAT_ACTIVE 0x0004
-/* Local Interrupt 2 Enable */
-#define PLX9052_INTCSR_LI2ENAB_MASK 0x0008
-#define PLX9052_INTCSR_LI2ENAB_DISABLED 0x0000
-#define PLX9052_INTCSR_LI2ENAB_ENABLED 0x0008
-/* Local Interrupt 2 Polarity */
-#define PLX9052_INTCSR_LI2POL_MASK 0x0010
-#define PLX9052_INTCSR_LI2POL_LOW 0x0000
-#define PLX9052_INTCSR_LI2POL_HIGH 0x0010
-/* Local Interrupt 2 Status (read-only) */
-#define PLX9052_INTCSR_LI2STAT_MASK 0x0020
-#define PLX9052_INTCSR_LI2STAT_INACTIVE 0x0000
-#define PLX9052_INTCSR_LI2STAT_ACTIVE 0x0020
-/* PCI Interrupt Enable */
-#define PLX9052_INTCSR_PCIENAB_MASK 0x0040
-#define PLX9052_INTCSR_PCIENAB_DISABLED 0x0000
-#define PLX9052_INTCSR_PCIENAB_ENABLED 0x0040
-/* Software Interrupt */
-#define PLX9052_INTCSR_SOFTINT_MASK 0x0080
-#define PLX9052_INTCSR_SOFTINT_UNASSERTED 0x0000
-#define PLX9052_INTCSR_SOFTINT_ASSERTED 0x0080
-/* Local Interrupt 1 Select Enable */
-#define PLX9052_INTCSR_LI1SEL_MASK 0x0100
-#define PLX9052_INTCSR_LI1SEL_LEVEL 0x0000
-#define PLX9052_INTCSR_LI1SEL_EDGE 0x0100
-/* Local Interrupt 2 Select Enable */
-#define PLX9052_INTCSR_LI2SEL_MASK 0x0200
-#define PLX9052_INTCSR_LI2SEL_LEVEL 0x0000
-#define PLX9052_INTCSR_LI2SEL_EDGE 0x0200
-/* Local Edge Triggerable Interrupt 1 Clear Bit */
-#define PLX9052_INTCSR_LI1CLRINT_MASK 0x0400
-#define PLX9052_INTCSR_LI1CLRINT_UNASSERTED 0x0000
-#define PLX9052_INTCSR_LI1CLRINT_ASSERTED 0x0400
-/* Local Edge Triggerable Interrupt 2 Clear Bit */
-#define PLX9052_INTCSR_LI2CLRINT_MASK 0x0800
-#define PLX9052_INTCSR_LI2CLRINT_UNASSERTED 0x0000
-#define PLX9052_INTCSR_LI2CLRINT_ASSERTED 0x0800
-/* ISA Interface Mode Enable (read-only over PCI bus) */
-#define PLX9052_INTCSR_ISAMODE_MASK 0x1000
-#define PLX9052_INTCSR_ISAMODE_DISABLED 0x0000
-#define PLX9052_INTCSR_ISAMODE_ENABLED 0x1000
+#define PLX9052_INTCSR 0x4c
+#define PLX9052_INTCSR_LI1ENAB (1 << 0) /* LI1 enabled */
+#define PLX9052_INTCSR_LI1POL (1 << 1) /* LI1 active high */
+#define PLX9052_INTCSR_LI1STAT (1 << 2) /* LI1 active */
+#define PLX9052_INTCSR_LI2ENAB (1 << 3) /* LI2 enabled */
+#define PLX9052_INTCSR_LI2POL (1 << 4) /* LI2 active high */
+#define PLX9052_INTCSR_LI2STAT (1 << 5) /* LI2 active */
+#define PLX9052_INTCSR_PCIENAB (1 << 6) /* PCIINT enabled */
+#define PLX9052_INTCSR_SOFTINT (1 << 7) /* generate soft int */
+#define PLX9052_INTCSR_LI1SEL (1 << 8) /* LI1 edge */
+#define PLX9052_INTCSR_LI2SEL (1 << 9) /* LI2 edge */
+#define PLX9052_INTCSR_LI1CLRINT (1 << 10) /* LI1 clear int */
+#define PLX9052_INTCSR_LI2CLRINT (1 << 11) /* LI2 clear int */
+#define PLX9052_INTCSR_ISAMODE (1 << 12) /* ISA interface mode */
+
+/*
+ * CNTRL - User I/O, Direct Slave Response, Serial EEPROM, and
+ * Initialization Control register
+ */
+#define PLX9052_CNTRL 0x50
+#define PLX9052_CNTRL_WAITO (1 << 0) /* UIO0 or WAITO# select */
+#define PLX9052_CNTRL_UIO0_DIR (1 << 1) /* UIO0 direction */
+#define PLX9052_CNTRL_UIO0_DATA (1 << 2) /* UIO0 data */
+#define PLX9052_CNTRL_LLOCKO (1 << 3) /* UIO1 or LLOCKo# select */
+#define PLX9052_CNTRL_UIO1_DIR (1 << 4) /* UIO1 direction */
+#define PLX9052_CNTRL_UIO1_DATA (1 << 5) /* UIO1 data */
+#define PLX9052_CNTRL_CS2 (1 << 6) /* UIO2 or CS2# select */
+#define PLX9052_CNTRL_UIO2_DIR (1 << 7) /* UIO2 direction */
+#define PLX9052_CNTRL_UIO2_DATA (1 << 8) /* UIO2 data */
+#define PLX9052_CNTRL_CS3 (1 << 9) /* UIO3 or CS3# select */
+#define PLX9052_CNTRL_UIO3_DIR (1 << 10) /* UIO3 direction */
+#define PLX9052_CNTRL_UIO3_DATA (1 << 11) /* UIO3 data */
+#define PLX9052_CNTRL_PCIBAR01 (0 << 12) /* bar 0 (mem) and 1 (I/O) */
+#define PLX9052_CNTRL_PCIBAR0 (1 << 12) /* bar 0 (mem) only */
+#define PLX9052_CNTRL_PCIBAR1 (2 << 12) /* bar 1 (I/O) only */
+#define PLX9052_CNTRL_PCI2_1_FEATURES (1 << 14) /* PCI r2.1 features enabled */
+#define PLX9052_CNTRL_PCI_R_W_FLUSH (1 << 15) /* read w/write flush mode */
+#define PLX9052_CNTRL_PCI_R_NO_FLUSH (1 << 16) /* read no flush mode */
+#define PLX9052_CNTRL_PCI_R_NO_WRITE (1 << 17) /* read no write mode */
+#define PLX9052_CNTRL_PCI_W_RELEASE (1 << 18) /* write release bus mode */
+#define PLX9052_CNTRL_RETRY_CLKS(x) (((x) & 0xf) << 19) /* slave retry clks */
+#define PLX9052_CNTRL_LOCK_ENAB (1 << 23) /* slave LOCK# enable */
+#define PLX9052_CNTRL_EEPROM_MASK (0x1f << 24) /* EEPROM bits */
+#define PLX9052_CNTRL_EEPROM_CLK (1 << 24) /* EEPROM clock */
+#define PLX9052_CNTRL_EEPROM_CS (1 << 25) /* EEPROM chip select */
+#define PLX9052_CNTRL_EEPROM_DOUT (1 << 26) /* EEPROM write bit */
+#define PLX9052_CNTRL_EEPROM_DIN (1 << 27) /* EEPROM read bit */
+#define PLX9052_CNTRL_EEPROM_PRESENT (1 << 28) /* EEPROM present */
+#define PLX9052_CNTRL_RELOAD_CFG (1 << 29) /* reload configuration */
+#define PLX9052_CNTRL_PCI_RESET (1 << 30) /* PCI adapter reset */
+#define PLX9052_CNTRL_MASK_REV (1 << 31) /* mask revision */
#endif /* _PLX9052_H_ */
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
index d7842c95d98..b55a16baeb1 100644
--- a/drivers/staging/comedi/drivers/poc.c
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -139,29 +139,11 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct boarddef_struct *board = comedi_board(dev);
struct poc_private *devpriv;
struct comedi_subdevice *s;
- unsigned long iobase;
- unsigned int iosize;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
- board->name, iobase);
-
- dev->board_name = board->name;
-
- if (iobase == 0) {
- printk(KERN_ERR "io base address required\n");
- return -EINVAL;
- }
-
- iosize = board->iosize;
- /* check if io addresses are available */
- if (!request_region(iobase, iosize, "dac02")) {
- printk(KERN_ERR "I/O port conflict: failed to allocate ports "
- "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], board->iosize);
+ if (ret)
+ return ret;
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
@@ -187,14 +169,6 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void poc_detach(struct comedi_device *dev)
-{
- const struct boarddef_struct *board = comedi_board(dev);
-
- if (dev->iobase)
- release_region(dev->iobase, board->iosize);
-}
-
static const struct boarddef_struct boards[] = {
{
.name = "dac02",
@@ -229,7 +203,7 @@ static struct comedi_driver poc_driver = {
.driver_name = "poc",
.module = THIS_MODULE,
.attach = poc_attach,
- .detach = poc_detach,
+ .detach = comedi_legacy_detach,
.board_name = &boards[0].name,
.num_names = ARRAY_SIZE(boards),
.offset = sizeof(boards[0]),
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 911eb6b3229..e092ce87722 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -715,8 +715,6 @@ static int daqp_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 6a5c914fa50..30a17284fac 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -1,105 +1,103 @@
/*
- comedi/drivers/rtd520.c
- Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2001 David A. Schleef <ds@schleef.org>
-
- 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.
+ * comedi/drivers/rtd520.c
+ * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
- 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: rtd520
-Description: Real Time Devices PCI4520/DM7520
-Author: Dan Christian
-Devices: [Real Time Devices] DM7520HR-1 (rtd520), DM7520HR-8,
- PCI4520, PCI4520-8
-Status: Works. Only tested on DM7520-8. Not SMP safe.
-
-Configuration options:
- [0] - PCI bus of device (optional)
- If bus / slot is not specified, the first available PCI
- device will be used.
- [1] - PCI slot of device (optional)
-*/
/*
- Created by Dan Christian, NASA Ames Research Center.
-
- The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
- Both have:
- 8/16 12 bit ADC with FIFO and channel gain table
- 8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
- 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
- 2 12 bit DACs with FIFOs
- 2 bits output
- 2 bits input
- bus mastering DMA
- timers: ADC sample, pacer, burst, about, delay, DA1, DA2
- sample counter
- 3 user timer/counters (8254)
- external interrupt
-
- The DM7520 has slightly fewer features (fewer gain steps).
-
- These boards can support external multiplexors and multi-board
- synchronization, but this driver doesn't support that.
-
- Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
- Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
- Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
- Call them and ask for the register level manual.
- PCI chip: http://www.plxtech.com/products/io/pci9080
-
- Notes:
- This board is memory mapped. There is some IO stuff, but it isn't needed.
-
- I use a pretty loose naming style within the driver (rtd_blah).
- All externally visible names should be rtd520_blah.
- I use camelCase for structures (and inside them).
- I may also use upper CamelCase for function names (old habit).
-
- This board is somewhat related to the RTD PCI4400 board.
-
- I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
- das1800, since they have the best documented code. Driver
- cb_pcidas64.c uses the same DMA controller.
-
- As far as I can tell, the About interrupt doesn't work if Sample is
- also enabled. It turns out that About really isn't needed, since
- we always count down samples read.
-
- There was some timer/counter code, but it didn't follow the right API.
-
-*/
+ * Driver: rtd520
+ * Description: Real Time Devices PCI4520/DM7520
+ * Devices: (Real Time Devices) DM7520HR-1 [DM7520]
+ * (Real Time Devices) DM7520HR-8 [DM7520]
+ * (Real Time Devices) PCI4520 [PCI4520]
+ * (Real Time Devices) PCI4520-8 [PCI4520]
+ * Author: Dan Christian
+ * Status: Works. Only tested on DM7520-8. Not SMP safe.
+ *
+ * Configuration options: not applicable, uses PCI auto config
+ */
/*
- driver status:
-
- Analog-In supports instruction and command mode.
-
- With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
- (single channel, 64K read buffer). I get random system lockups when
- using DMA with ALI-15xx based systems. I haven't been able to test
- any other chipsets. The lockups happen soon after the start of an
- acquistion, not in the middle of a long run.
-
- Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
- (with a 256K read buffer).
-
- Digital-IO and Analog-Out only support instruction mode.
+ * Created by Dan Christian, NASA Ames Research Center.
+ *
+ * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
+ * Both have:
+ * 8/16 12 bit ADC with FIFO and channel gain table
+ * 8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
+ * 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
+ * 2 12 bit DACs with FIFOs
+ * 2 bits output
+ * 2 bits input
+ * bus mastering DMA
+ * timers: ADC sample, pacer, burst, about, delay, DA1, DA2
+ * sample counter
+ * 3 user timer/counters (8254)
+ * external interrupt
+ *
+ * The DM7520 has slightly fewer features (fewer gain steps).
+ *
+ * These boards can support external multiplexors and multi-board
+ * synchronization, but this driver doesn't support that.
+ *
+ * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
+ * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
+ * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
+ * Call them and ask for the register level manual.
+ * PCI chip: http://www.plxtech.com/products/io/pci9080
+ *
+ * Notes:
+ * This board is memory mapped. There is some IO stuff, but it isn't needed.
+ *
+ * I use a pretty loose naming style within the driver (rtd_blah).
+ * All externally visible names should be rtd520_blah.
+ * I use camelCase for structures (and inside them).
+ * I may also use upper CamelCase for function names (old habit).
+ *
+ * This board is somewhat related to the RTD PCI4400 board.
+ *
+ * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
+ * das1800, since they have the best documented code. Driver cb_pcidas64.c
+ * uses the same DMA controller.
+ *
+ * As far as I can tell, the About interrupt doesn't work if Sample is
+ * also enabled. It turns out that About really isn't needed, since
+ * we always count down samples read.
+ *
+ * There was some timer/counter code, but it didn't follow the right API.
+ */
-*/
+/*
+ * driver status:
+ *
+ * Analog-In supports instruction and command mode.
+ *
+ * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
+ * (single channel, 64K read buffer). I get random system lockups when
+ * using DMA with ALI-15xx based systems. I haven't been able to test
+ * any other chipsets. The lockups happen soon after the start of an
+ * acquistion, not in the middle of a long run.
+ *
+ * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
+ * (with a 256K read buffer).
+ *
+ * Digital-IO and Analog-Out only support instruction mode.
+ */
#include <linux/pci.h>
#include <linux/delay.h>
@@ -108,9 +106,123 @@ Configuration options:
#include "../comedidev.h"
#include "comedi_fc.h"
-#include "rtd520.h"
#include "plx9080.h"
+/*
+ * Local Address Space 0 Offsets
+ */
+#define LAS0_USER_IO 0x0008 /* User I/O */
+#define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
+#define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */
+#define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */
+#define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */
+#define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */
+#define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */
+#define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */
+#define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */
+#define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */
+#define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */
+#define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */
+#define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */
+#define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */
+#define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */
+#define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */
+#define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
+#define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
+#define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
+#define LAS0_IT 0x0030 /* Interrupt Status/Enable */
+#define IRQM_ADC_FIFO_WRITE (1 << 0) /* ADC FIFO Write */
+#define IRQM_CGT_RESET (1 << 1) /* Reset CGT */
+#define IRQM_CGT_PAUSE (1 << 3) /* Pause CGT */
+#define IRQM_ADC_ABOUT_CNT (1 << 4) /* About Counter out */
+#define IRQM_ADC_DELAY_CNT (1 << 5) /* Delay Counter out */
+#define IRQM_ADC_SAMPLE_CNT (1 << 6) /* ADC Sample Counter */
+#define IRQM_DAC1_UCNT (1 << 7) /* DAC1 Update Counter */
+#define IRQM_DAC2_UCNT (1 << 8) /* DAC2 Update Counter */
+#define IRQM_UTC1 (1 << 9) /* User TC1 out */
+#define IRQM_UTC1_INV (1 << 10) /* User TC1 out, inverted */
+#define IRQM_UTC2 (1 << 11) /* User TC2 out */
+#define IRQM_DIGITAL_IT (1 << 12) /* Digital Interrupt */
+#define IRQM_EXTERNAL_IT (1 << 13) /* External Interrupt */
+#define IRQM_ETRIG_RISING (1 << 14) /* Ext Trigger rising-edge */
+#define IRQM_ETRIG_FALLING (1 << 15) /* Ext Trigger falling-edge */
+#define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
+#define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
+#define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
+#define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
+#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
+#define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
+#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
+#define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
+#define LAS0_ACNT 0x0058 /* About counter (16 bit) */
+#define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
+#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
+#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
+#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
+#define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
+#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
+#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
+#define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
+#define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
+#define LAS0_BOARD_RESET 0x0100 /* Board reset */
+#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
+#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
+#define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
+#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
+#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
+#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
+#define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
+#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
+#define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
+#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
+#define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
+#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
+#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
+#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
+#define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
+#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
+#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
+#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
+#define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
+#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
+#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
+#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
+#define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */
+#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
+#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
+#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
+#define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */
+#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
+#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
+#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
+#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
+#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
+#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
+#define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
+#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
+#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
+#define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
+#define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
+#define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
+#define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
+#define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
+#define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
+#define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
+#define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
+#define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
+#define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
+#define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
+#define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
+#define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
+
+/*
+ * Local Address Space 1 Offsets
+ */
+#define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
+#define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
+#define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */
+#define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */
+
/*======================================================================
Driver specific stuff (tunable)
======================================================================*/
@@ -249,61 +361,48 @@ static const struct comedi_lrange rtd_ao_range = {
}
};
-struct rtdBoard {
+enum rtd_boardid {
+ BOARD_DM7520,
+ BOARD_PCI4520,
+};
+
+struct rtd_boardinfo {
const char *name;
- int device_id;
- int range10Start; /* start of +-10V range */
- int rangeUniStart; /* start of +10V range */
+ int range_bip10; /* start of +-10V range */
+ int range_uni10; /* start of +10V range */
const struct comedi_lrange *ai_range;
};
-static const struct rtdBoard rtd520Boards[] = {
- {
+static const struct rtd_boardinfo rtd520Boards[] = {
+ [BOARD_DM7520] = {
.name = "DM7520",
- .device_id = 0x7520,
- .range10Start = 6,
- .rangeUniStart = 12,
+ .range_bip10 = 6,
+ .range_uni10 = 12,
.ai_range = &rtd_ai_7520_range,
- }, {
+ },
+ [BOARD_PCI4520] = {
.name = "PCI4520",
- .device_id = 0x4520,
- .range10Start = 8,
- .rangeUniStart = 16,
+ .range_bip10 = 8,
+ .range_uni10 = 16,
.ai_range = &rtd_ai_4520_range,
},
};
-/*
- This structure is for data unique to this hardware driver.
- This is also unique for each board in the system.
-*/
-struct rtdPrivate {
+struct rtd_private {
/* memory mapped board structures */
void __iomem *las0;
void __iomem *las1;
void __iomem *lcfg;
- long aiCount; /* total transfer size (samples) */
- int transCount; /* # to transfer data. 0->1/2FIFO */
+ long ai_count; /* total transfer size (samples) */
+ int xfer_count; /* # to transfer data. 0->1/2FIFO */
int flags; /* flag event modes */
- /* channel list info */
- /* chanBipolar tracks whether a channel is bipolar (and needs +2048) */
- unsigned char chanBipolar[RTD_MAX_CHANLIST / 8]; /* bit array */
+ unsigned char chan_is_bipolar[RTD_MAX_CHANLIST / 8]; /* bit array */
- /* read back data */
- unsigned int aoValue[2]; /* Used for AO read back */
+ unsigned int ao_readback[2];
- /* timer gate (when enabled) */
- u8 utcGate[4]; /* 1 extra allows simple range check */
-
- /* shadow registers affect other registers, but can't be read back */
- /* The macros below update these on writes */
- u16 intMask; /* interrupt mask */
- u16 intClearMask; /* interrupt clear mask */
- u8 utcCtrl[4]; /* crtl mode for 3 utc + read back */
- u8 dioStatus; /* could be read back (dio0Ctrl) */
- unsigned fifoLen;
+ unsigned fifosz;
};
/* bit defines for "flags" */
@@ -365,36 +464,34 @@ static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
/*
Convert a single comedi channel-gain entry to a RTD520 table entry
*/
-static unsigned short rtdConvertChanGain(struct comedi_device *dev,
- unsigned int comediChan, int chanIndex)
-{ /* index in channel list */
- const struct rtdBoard *thisboard = comedi_board(dev);
- struct rtdPrivate *devpriv = dev->private;
- unsigned int chan, range, aref;
+static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
+ unsigned int chanspec, int index)
+{
+ const struct rtd_boardinfo *board = comedi_board(dev);
+ struct rtd_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(chanspec);
+ unsigned int range = CR_RANGE(chanspec);
+ unsigned int aref = CR_AREF(chanspec);
unsigned short r = 0;
- chan = CR_CHAN(comediChan);
- range = CR_RANGE(comediChan);
- aref = CR_AREF(comediChan);
-
r |= chan & 0xf;
/* Note: we also setup the channel list bipolar flag array */
- if (range < thisboard->range10Start) {
+ if (range < board->range_bip10) {
/* +-5 range */
r |= 0x000;
r |= (range & 0x7) << 4;
- CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
- } else if (range < thisboard->rangeUniStart) {
+ CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
+ } else if (range < board->range_uni10) {
/* +-10 range */
r |= 0x100;
- r |= ((range - thisboard->range10Start) & 0x7) << 4;
- CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
+ r |= ((range - board->range_bip10) & 0x7) << 4;
+ CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
} else {
/* +10 range */
r |= 0x200;
- r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;
- CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
+ r |= ((range - board->range_uni10) & 0x7) << 4;
+ CHAN_ARRAY_CLEAR(devpriv->chan_is_bipolar, index);
}
switch (aref) {
@@ -423,7 +520,7 @@ static unsigned short rtdConvertChanGain(struct comedi_device *dev,
static void rtd_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
if (n_chan > 1) { /* setup channel gain table */
int ii;
@@ -431,12 +528,12 @@ static void rtd_load_channelgain_list(struct comedi_device *dev,
writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
for (ii = 0; ii < n_chan; ii++) {
- writel(rtdConvertChanGain(dev, list[ii], ii),
+ writel(rtd_convert_chan_gain(dev, list[ii], ii),
devpriv->las0 + LAS0_CGT_WRITE);
}
} else { /* just use the channel gain latch */
writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
- writel(rtdConvertChanGain(dev, list[0], 0),
+ writel(rtd_convert_chan_gain(dev, list[0], 0),
devpriv->las0 + LAS0_CGL_WRITE);
}
}
@@ -445,7 +542,7 @@ static void rtd_load_channelgain_list(struct comedi_device *dev,
empty status flag clears */
static int rtd520_probe_fifo_depth(struct comedi_device *dev)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
unsigned i;
static const unsigned limit = 0x2000;
@@ -493,7 +590,7 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
int n, ii;
int stat;
@@ -525,7 +622,7 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
d = readw(devpriv->las1 + LAS1_ADC_FIFO);
/*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
d = d >> 3; /* low 3 bits are marker lines */
- if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0))
+ if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar, 0))
/* convert to comedi unsigned data */
data[n] = d + 2048;
else
@@ -545,21 +642,22 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
int count)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
int ii;
for (ii = 0; ii < count; ii++) {
short sample;
s16 d;
- if (0 == devpriv->aiCount) { /* done */
+ if (0 == devpriv->ai_count) { /* done */
d = readw(devpriv->las1 + LAS1_ADC_FIFO);
continue;
}
d = readw(devpriv->las1 + LAS1_ADC_FIFO);
d = d >> 3; /* low 3 bits are marker lines */
- if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
+ if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
+ s->async->cur_chan)) {
/* convert to comedi unsigned data */
sample = d + 2048;
} else
@@ -568,8 +666,8 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
if (!comedi_buf_put(s->async, sample))
return -1;
- if (devpriv->aiCount > 0) /* < 0, means read forever */
- devpriv->aiCount--;
+ if (devpriv->ai_count > 0) /* < 0, means read forever */
+ devpriv->ai_count--;
}
return 0;
}
@@ -579,18 +677,19 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
*/
static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
short sample;
s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
- if (0 == devpriv->aiCount) { /* done */
+ if (0 == devpriv->ai_count) { /* done */
continue; /* read rest */
}
d = d >> 3; /* low 3 bits are marker lines */
- if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
+ if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
+ s->async->cur_chan)) {
/* convert to comedi unsigned data */
sample = d + 2048;
} else
@@ -599,8 +698,8 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
if (!comedi_buf_put(s->async, sample))
return -1;
- if (devpriv->aiCount > 0) /* < 0, means read forever */
- devpriv->aiCount--;
+ if (devpriv->ai_count > 0) /* < 0, means read forever */
+ devpriv->ai_count--;
}
return 0;
}
@@ -611,23 +710,22 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
This is a "slow handler"; other interrupts may be active.
The data conversion may someday happen in a "bottom half".
*/
-static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
- void *d)
-{ /* our data *//* cpu context (ignored) */
+static irqreturn_t rtd_interrupt(int irq, void *d)
+{
struct comedi_device *dev = d;
struct comedi_subdevice *s = &dev->subdevices[0];
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
u32 overrun;
u16 status;
- u16 fifoStatus;
+ u16 fifo_status;
if (!dev->attached)
return IRQ_NONE;
- fifoStatus = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(devpriv->las0 + LAS0_ADC);
/* check for FIFO full, this automatically halts the ADC! */
- if (!(fifoStatus & FS_ADC_NOT_FULL)) /* 0 -> full */
- goto abortTransfer;
+ if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */
+ goto xfer_abort;
status = readw(devpriv->las0 + LAS0_IT);
/* if interrupt was not caused by our board, or handled above */
@@ -641,23 +739,23 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
* finished, we must handle the possibility that there is
* no data here
*/
- if (!(fifoStatus & FS_ADC_HEMPTY)) {
+ if (!(fifo_status & FS_ADC_HEMPTY)) {
/* FIFO half full */
- if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0)
- goto abortTransfer;
+ if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
+ goto xfer_abort;
- if (0 == devpriv->aiCount)
- goto transferDone;
+ if (0 == devpriv->ai_count)
+ goto xfer_done;
comedi_event(dev, s);
- } else if (devpriv->transCount > 0) {
- if (fifoStatus & FS_ADC_NOT_EMPTY) {
+ } else if (devpriv->xfer_count > 0) {
+ if (fifo_status & FS_ADC_NOT_EMPTY) {
/* FIFO not empty */
- if (ai_read_n(dev, s, devpriv->transCount) < 0)
- goto abortTransfer;
+ if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
+ goto xfer_abort;
- if (0 == devpriv->aiCount)
- goto transferDone;
+ if (0 == devpriv->ai_count)
+ goto xfer_done;
comedi_event(dev, s);
}
@@ -666,30 +764,28 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
if (overrun)
- goto abortTransfer;
+ goto xfer_abort;
/* clear the interrupt */
- devpriv->intClearMask = status;
- writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
+ writew(status, devpriv->las0 + LAS0_CLEAR);
readw(devpriv->las0 + LAS0_CLEAR);
return IRQ_HANDLED;
-abortTransfer:
+xfer_abort:
writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
s->async->events |= COMEDI_CB_ERROR;
- devpriv->aiCount = 0; /* stop and don't transfer any more */
- /* fall into transferDone */
+ devpriv->ai_count = 0; /* stop and don't transfer any more */
+ /* fall into xfer_done */
-transferDone:
+xfer_done:
/* pacer stop source: SOFTWARE */
writel(0, devpriv->las0 + LAS0_PACER_STOP);
writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
- devpriv->intMask = 0;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
+ writew(0, devpriv->las0 + LAS0_IT);
- if (devpriv->aiCount > 0) { /* there shouldn't be anything left */
- fifoStatus = readl(devpriv->las0 + LAS0_ADC);
+ if (devpriv->ai_count > 0) { /* there shouldn't be anything left */
+ fifo_status = readl(devpriv->las0 + LAS0_ADC);
ai_read_dregs(dev, s); /* read anything left in FIFO */
}
@@ -698,11 +794,10 @@ transferDone:
/* clear the interrupt */
status = readw(devpriv->las0 + LAS0_IT);
- devpriv->intClearMask = status;
- writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
+ writew(status, devpriv->las0 + LAS0_CLEAR);
readw(devpriv->las0 + LAS0_CLEAR);
- fifoStatus = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(devpriv->las0 + LAS0_ADC);
overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
return IRQ_HANDLED;
@@ -875,7 +970,7 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
*/
static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int timer;
@@ -884,8 +979,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
writel(0, devpriv->las0 + LAS0_PACER_STOP);
writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
- devpriv->intMask = 0;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
+ writew(0, devpriv->las0 + LAS0_IT);
writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
writel(0, devpriv->las0 + LAS0_OVERRUN);
@@ -907,7 +1001,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* ADC conversion trigger source: PACER */
writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
}
- writel((devpriv->fifoLen / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
+ writel((devpriv->fifosz / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
if (TRIG_TIMER == cmd->scan_begin_src) {
/* scan_begin_arg is in nanoseconds */
@@ -918,37 +1012,36 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* the application is responsible for doing the
* right thing
*/
- devpriv->transCount = cmd->chanlist_len;
+ devpriv->xfer_count = cmd->chanlist_len;
devpriv->flags |= SEND_EOS;
} else {
/* arrange to transfer data periodically */
- devpriv->transCount
- =
+ devpriv->xfer_count =
(TRANS_TARGET_PERIOD * cmd->chanlist_len) /
cmd->scan_begin_arg;
- if (devpriv->transCount < cmd->chanlist_len) {
+ if (devpriv->xfer_count < cmd->chanlist_len) {
/* transfer after each scan (and avoid 0) */
- devpriv->transCount = cmd->chanlist_len;
+ devpriv->xfer_count = cmd->chanlist_len;
} else { /* make a multiple of scan length */
- devpriv->transCount =
- (devpriv->transCount +
+ devpriv->xfer_count =
+ (devpriv->xfer_count +
cmd->chanlist_len - 1)
/ cmd->chanlist_len;
- devpriv->transCount *= cmd->chanlist_len;
+ devpriv->xfer_count *= cmd->chanlist_len;
}
devpriv->flags |= SEND_EOS;
}
- if (devpriv->transCount >= (devpriv->fifoLen / 2)) {
+ if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
/* out of counter range, use 1/2 fifo instead */
- devpriv->transCount = 0;
+ devpriv->xfer_count = 0;
devpriv->flags &= ~SEND_EOS;
} else {
/* interrupt for each transfer */
- writel((devpriv->transCount - 1) & 0xffff,
+ writel((devpriv->xfer_count - 1) & 0xffff,
devpriv->las0 + LAS0_ACNT);
}
} else { /* unknown timing, just use 1/2 FIFO */
- devpriv->transCount = 0;
+ devpriv->xfer_count = 0;
devpriv->flags &= ~SEND_EOS;
}
/* pacer clock source: INTERNAL 8MHz */
@@ -961,15 +1054,15 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* First, setup when to stop */
switch (cmd->stop_src) {
case TRIG_COUNT: /* stop after N scans */
- devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len;
- if ((devpriv->transCount > 0)
- && (devpriv->transCount > devpriv->aiCount)) {
- devpriv->transCount = devpriv->aiCount;
+ devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
+ if ((devpriv->xfer_count > 0)
+ && (devpriv->xfer_count > devpriv->ai_count)) {
+ devpriv->xfer_count = devpriv->ai_count;
}
break;
case TRIG_NONE: /* stop when cancel is called */
- devpriv->aiCount = -1; /* read forever */
+ devpriv->ai_count = -1; /* read forever */
break;
}
@@ -1011,17 +1104,14 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* This doesn't seem to work. There is no way to clear an interrupt
that the priority controller has queued! */
- devpriv->intClearMask = ~0;
- writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
+ writew(~0, devpriv->las0 + LAS0_CLEAR);
readw(devpriv->las0 + LAS0_CLEAR);
/* TODO: allow multiple interrupt sources */
- if (devpriv->transCount > 0) { /* transfer every N samples */
- devpriv->intMask = IRQM_ADC_ABOUT_CNT;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
+ if (devpriv->xfer_count > 0) { /* transfer every N samples */
+ writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
} else { /* 1/2 FIFO transfers */
- devpriv->intMask = IRQM_ADC_ABOUT_CNT;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
+ writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
}
/* BUG: start_src is ASSUMED to be TRIG_NOW */
@@ -1035,7 +1125,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
*/
static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
u32 overrun;
u16 status;
@@ -1043,9 +1133,8 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
writel(0, devpriv->las0 + LAS0_PACER_STOP);
writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
- devpriv->intMask = 0;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
- devpriv->aiCount = 0; /* stop and don't transfer any more */
+ writew(0, devpriv->las0 + LAS0_IT);
+ devpriv->ai_count = 0; /* stop and don't transfer any more */
status = readw(devpriv->las0 + LAS0_IT);
overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
return 0;
@@ -1058,7 +1147,7 @@ static int rtd_ao_winsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
int range = CR_RANGE(insn->chanspec);
@@ -1090,7 +1179,7 @@ static int rtd_ao_winsn(struct comedi_device *dev,
writew(0, devpriv->las0 +
((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
- devpriv->aoValue[chan] = data[i]; /* save for read back */
+ devpriv->ao_readback[chan] = data[i];
for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
stat = readl(devpriv->las0 + LAS0_ADC);
@@ -1114,73 +1203,56 @@ static int rtd_ao_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
for (i = 0; i < insn->n; i++)
- data[i] = devpriv->aoValue[chan];
+ data[i] = devpriv->ao_readback[chan];
return i;
}
-/*
- Write a masked set of bits and the read back the port.
- We track what the bits should be (i.e. we don't read the port first).
-
- DIO devices are slightly special. Although it is possible to
- * implement the insn_read/insn_write interface, it is much more
- * useful to applications if you implement the insn_bits interface.
- * This allows packed reading/writing of the DIO channels. The
- * comedi core can convert between insn_bits and insn_read/write
- */
static int rtd_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
- /* The insn data is a mask in data[0] and the new data
- * in data[1], each channel cooresponding to a bit. */
- if (data[0]) {
- s->state &= ~data[0];
- s->state |= data[0] & data[1];
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
- /* Write out the new digital output lines */
writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
}
- /* on return, data[1] contains the value of the digital
- * input lines. */
+
data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
return insn->n;
}
-/*
- Configure one bit on a IO port as Input or Output (hence the name :-).
-*/
static int rtd_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct rtdPrivate *devpriv = dev->private;
- int chan = CR_CHAN(insn->chanspec);
+ struct rtd_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int mask = 1 << chan;
- /* The input or output configuration of each digital line is
- * configured by a special insn_config instruction. chanspec
- * contains the channel to be changed, and data[0] contains the
- * value COMEDI_INPUT or COMEDI_OUTPUT. */
switch (data[0]) {
case INSN_CONFIG_DIO_OUTPUT:
- s->io_bits |= 1 << chan; /* 1 means Out */
+ s->io_bits |= mask;
break;
case INSN_CONFIG_DIO_INPUT:
- s->io_bits &= ~(1 << chan);
+ s->io_bits &= ~mask;
break;
case INSN_CONFIG_DIO_QUERY:
- data[1] =
- (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
default:
@@ -1188,30 +1260,30 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
}
/* TODO support digital match interrupts and strobes */
- devpriv->dioStatus = 0x01; /* set direction */
- writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
+
+ /* set direction */
+ writew(0x01, devpriv->las0 + LAS0_DIO_STATUS);
writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
- devpriv->dioStatus = 0x00; /* clear interrupts */
- writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
+
+ /* clear interrupts */
+ writew(0x00, devpriv->las0 + LAS0_DIO_STATUS);
/* port1 can only be all input or all output */
/* there are also 2 user input lines and 2 user output lines */
- return 1;
+ return insn->n;
}
static void rtd_reset(struct comedi_device *dev)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
writel(0, devpriv->las0 + LAS0_BOARD_RESET);
udelay(100); /* needed? */
- writel(0, devpriv->lcfg + LCFG_ITCSR);
- devpriv->intMask = 0;
- writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
- devpriv->intClearMask = ~0;
- writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
+ writel(0, devpriv->lcfg + PLX_INTRCS_REG);
+ writew(0, devpriv->las0 + LAS0_IT);
+ writew(~0, devpriv->las0 + LAS0_CLEAR);
readw(devpriv->las0 + LAS0_CLEAR);
}
@@ -1221,7 +1293,7 @@ static void rtd_reset(struct comedi_device *dev)
*/
static void rtd_init_board(struct comedi_device *dev)
{
- struct rtdPrivate *devpriv = dev->private;
+ struct rtd_private *devpriv = dev->private;
rtd_reset(dev);
@@ -1231,16 +1303,11 @@ static void rtd_init_board(struct comedi_device *dev)
writel(0, devpriv->las0 + LAS0_DAC1_RESET);
writel(0, devpriv->las0 + LAS0_DAC2_RESET);
/* clear digital IO fifo */
- devpriv->dioStatus = 0;
- writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
- devpriv->utcCtrl[0] = (0 << 6) | 0x30;
- devpriv->utcCtrl[1] = (1 << 6) | 0x30;
- devpriv->utcCtrl[2] = (2 << 6) | 0x30;
- devpriv->utcCtrl[3] = (3 << 6) | 0x00;
- writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL);
- writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL);
- writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL);
- writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL);
+ writew(0, devpriv->las0 + LAS0_DIO_STATUS);
+ writeb((0 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
+ writeb((1 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
+ writeb((2 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
+ writeb((3 << 6) | 0x00, devpriv->las0 + LAS0_UTC_CTRL);
/* TODO: set user out source ??? */
}
@@ -1259,51 +1326,34 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev,
}
}
-static const void *rtd_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct rtdBoard *thisboard;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) {
- thisboard = &rtd520Boards[i];
- if (pcidev->device == thisboard->device_id)
- return thisboard;
- }
- return NULL;
-}
-
static int rtd_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct rtdBoard *thisboard;
- struct rtdPrivate *devpriv;
+ const struct rtd_boardinfo *board = NULL;
+ struct rtd_private *devpriv;
struct comedi_subdevice *s;
int ret;
- thisboard = rtd_find_boardinfo(dev, pcidev);
- if (!thisboard)
+ if (context < ARRAY_SIZE(rtd520Boards))
+ board = &rtd520Boards[context];
+ if (!board)
return -ENODEV;
- dev->board_ptr = thisboard;
- dev->board_name = thisboard->name;
+ dev->board_ptr = board;
+ dev->board_name = board->name;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
- dev->iobase = 1; /* the "detach" needs this */
-
- devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2),
- pci_resource_len(pcidev, 2));
- devpriv->las1 = ioremap_nocache(pci_resource_start(pcidev, 3),
- pci_resource_len(pcidev, 3));
- devpriv->lcfg = ioremap_nocache(pci_resource_start(pcidev, 0),
- pci_resource_len(pcidev, 0));
+
+ devpriv->las0 = pci_ioremap_bar(pcidev, 2);
+ devpriv->las1 = pci_ioremap_bar(pcidev, 3);
+ devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
return -ENOMEM;
@@ -1326,7 +1376,7 @@ static int rtd_auto_attach(struct comedi_device *dev,
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
s->n_chan = 16;
s->maxdata = 0x0fff;
- s->range_table = thisboard->ai_range;
+ s->range_table = board->ai_range;
s->len_chanlist = RTD_MAX_CHANLIST;
s->insn_read = rtd_ai_rinsn;
if (dev->irq) {
@@ -1370,10 +1420,10 @@ static int rtd_auto_attach(struct comedi_device *dev,
ret = rtd520_probe_fifo_depth(dev);
if (ret < 0)
return ret;
- devpriv->fifoLen = ret;
+ devpriv->fifosz = ret;
if (dev->irq)
- writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR);
+ writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
dev_info(dev->class_dev, "%s attached\n", dev->board_name);
@@ -1382,17 +1432,16 @@ static int rtd_auto_attach(struct comedi_device *dev,
static void rtd_detach(struct comedi_device *dev)
{
- struct rtdPrivate *devpriv = dev->private;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+ struct rtd_private *devpriv = dev->private;
if (devpriv) {
/* Shut down any board ops by resetting it */
if (devpriv->las0 && devpriv->lcfg)
rtd_reset(dev);
if (dev->irq) {
- writel(readl(devpriv->lcfg + LCFG_ITCSR) &
+ writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
- devpriv->lcfg + LCFG_ITCSR);
+ devpriv->lcfg + PLX_INTRCS_REG);
free_irq(dev->irq, dev);
}
if (devpriv->las0)
@@ -1402,10 +1451,7 @@ static void rtd_detach(struct comedi_device *dev)
if (devpriv->lcfg)
iounmap(devpriv->lcfg);
}
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
- }
+ comedi_pci_disable(dev);
}
static struct comedi_driver rtd520_driver = {
@@ -1416,14 +1462,14 @@ static struct comedi_driver rtd520_driver = {
};
static int rtd520_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &rtd520_driver);
+ return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) },
- { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) },
+ { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
+ { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h
deleted file mode 100644
index 25188a58145..00000000000
--- a/drivers/staging/comedi/drivers/rtd520.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- comedi/drivers/rtd520.h
- Comedi driver defines for Real Time Devices (RTD) PCI4520/DM7520
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 2001 David A. Schleef <ds@schleef.org>
-
- 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.
-*/
-
-/*
- Created by Dan Christian, NASA Ames Research Center.
- See board notes in rtd520.c
-*/
-
-/*
- * Local Address Space 0 Offsets
- */
-#define LAS0_USER_IO 0x0008 /* User I/O */
-#define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
-#define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */
-#define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */
-#define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
-#define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
-#define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
-#define LAS0_IT 0x0030 /* Interrupt Status/Enable */
-#define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
-#define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
-#define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
-#define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
-#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
-#define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
-#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
-#define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
-#define LAS0_ACNT 0x0058 /* About counter (16 bit) */
-#define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
-#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
-#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
-#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
-#define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
-#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
-#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
-#define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
-#define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
-#define LAS0_BOARD_RESET 0x0100 /* Board reset */
-#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
-#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
-#define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
-#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
-#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
-#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
-#define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
-#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
-#define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
-#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
-#define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
-#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
-#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
-#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
-#define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
-#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
-#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
-#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
-#define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
-#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
-#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
-#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
-#define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */
-#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
-#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
-#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
-#define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */
-#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
-#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
-#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
-#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
-#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
-#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
-#define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
-#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
-#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
-#define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
-#define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
-#define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
-#define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
-#define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
-#define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
-#define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
-#define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
-#define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
-#define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
-#define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
-#define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
-#define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
-
-/*
- * Local Address Space 1 Offsets
- */
-#define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
-#define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
-#define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */
-#define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */
-
-/*
- * PLX 9080 local config & runtime registers
- */
-#define LCFG_ITCSR 0x0068 /* Interrupt Control/Status */
-#define LCFG_DMAMODE0 0x0080 /* DMA0 Mode */
-#define LCFG_DMAPADR0 0x0084 /* DMA0 PCI Address */
-#define LCFG_DMALADR0 0x0088 /* DMA0 Local Address */
-#define LCFG_DMASIZ0 0x008c /* DMA0 Transfer Size (Bytes) */
-#define LCFG_DMADPR0 0x0090 /* DMA0 Descriptor Pointer */
-#define LCFG_DMAMODE1 0x0094 /* DMA1 Mode */
-#define LCFG_DMAPADR1 0x0098 /* DMA1 PCI Address */
-#define LCFG_DMALADR1 0x009c /* DMA1 Local Address */
-#define LCFG_DMASIZ1 0x00a0 /* DMA1 Transfer Size (Bytes) */
-#define LCFG_DMADPR1 0x00a4 /* DMA1 Descriptor Pointer */
-#define LCFG_DMACSR0 0x00a8 /* DMA0 Command/Status */
-#define LCFG_DMACSR1 0x00a9 /* DMA0 Command/Status */
-#define LCFG_DMAARB 0x00ac /* DMA Arbitration */
-#define LCFG_DMATHR 0x00b0 /* DMA Threshold */
-
-/* FIFO Status Word Bits (RtdFifoStatus) */
-#define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */
-#define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */
-#define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */
-#define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */
-#define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */
-#define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */
-#define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */
-#define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */
-#define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */
-#define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */
-#define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */
-#define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */
-
-/* Timer Status Word Bits (GetTimerStatus) */
-#define TS_PCLK_GATE (1 << 0) /* Pacer Clock Gate enabled */
-#define TS_BCLK_GATE (1 << 1) /* Burst Clock Gate running */
-#define TS_DCNT_GATE (1 << 2) /* Pacer Clock Delayed Start Trig. */
-#define TS_ACNT_GATE (1 << 3) /* Pacer Clock About Trig. */
-#define TS_PCLK_RUN (1 << 4) /* Pacer Clock Shutdown Flag */
-
-/* External Trigger polarity select */
-/* External Interrupt polarity select */
-#define POL_POSITIVE 0x0 /* positive edge */
-#define POL_NEGATIVE 0x1 /* negative edge */
-
-/* User Output Signal select (SetUout0Source, SetUout1Source) */
-#define UOUT_ADC 0x0 /* A/D Conversion Signal */
-#define UOUT_DAC1 0x1 /* D/A1 Update */
-#define UOUT_DAC2 0x2 /* D/A2 Update */
-#define UOUT_SOFTWARE 0x3 /* Software Programmable */
-
-/* Pacer clock select (SetPacerSource) */
-#define PCLK_INTERNAL 1 /* Internal Pacer Clock */
-#define PCLK_EXTERNAL 0 /* External Pacer Clock */
-
-/* A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter) */
-#define ADC_SCNT_CGT_RESET 0x0 /* needs restart with StartPacer */
-#define ADC_SCNT_FIFO_WRITE 0x1
-
-/* A/D Conversion Signal Select (for SetConversionSelect) */
-#define ADC_START_SOFTWARE 0x0 /* Software A/D Start */
-#define ADC_START_PCLK 0x1 /* Pacer Clock (Ext. Int. see Func.509) */
-#define ADC_START_BCLK 0x2 /* Burst Clock */
-#define ADC_START_DIGITAL_IT 0x3 /* Digital Interrupt */
-#define ADC_START_DAC1_MARKER1 0x4 /* D/A 1 Data Marker 1 */
-#define ADC_START_DAC2_MARKER1 0x5 /* D/A 2 Data Marker 1 */
-#define ADC_START_SBUS0 0x6 /* SyncBus 0 */
-#define ADC_START_SBUS1 0x7 /* SyncBus 1 */
-#define ADC_START_SBUS2 0x8 /* SyncBus 2 */
-
-/* Burst Clock start trigger select (SetBurstStart) */
-#define BCLK_START_SOFTWARE 0x0 /* Software A/D Start (StartBurst) */
-#define BCLK_START_PCLK 0x1 /* Pacer Clock */
-#define BCLK_START_ETRIG 0x2 /* External Trigger */
-#define BCLK_START_DIGITAL_IT 0x3 /* Digital Interrupt */
-#define BCLK_START_SBUS0 0x4 /* SyncBus 0 */
-#define BCLK_START_SBUS1 0x5 /* SyncBus 1 */
-#define BCLK_START_SBUS2 0x6 /* SyncBus 2 */
-
-/* Pacer Clock start trigger select (SetPacerStart) */
-#define PCLK_START_SOFTWARE 0x0 /* Software Pacer Start (StartPacer) */
-#define PCLK_START_ETRIG 0x1 /* External trigger */
-#define PCLK_START_DIGITAL_IT 0x2 /* Digital interrupt */
-#define PCLK_START_UTC2 0x3 /* User TC 2 out */
-#define PCLK_START_SBUS0 0x4 /* SyncBus 0 */
-#define PCLK_START_SBUS1 0x5 /* SyncBus 1 */
-#define PCLK_START_SBUS2 0x6 /* SyncBus 2 */
-#define PCLK_START_D_SOFTWARE 0x8 /* Delayed Software Pacer Start */
-#define PCLK_START_D_ETRIG 0x9 /* Delayed external trigger */
-#define PCLK_START_D_DIGITAL_IT 0xA /* Delayed digital interrupt */
-#define PCLK_START_D_UTC2 0xB /* Delayed User TC 2 out */
-#define PCLK_START_D_SBUS0 0xC /* Delayed SyncBus 0 */
-#define PCLK_START_D_SBUS1 0xD /* Delayed SyncBus 1 */
-#define PCLK_START_D_SBUS2 0xE /* Delayed SyncBus 2 */
-#define PCLK_START_ETRIG_GATED 0xF /* External Trigger Gated controlled mode */
-
-/* Pacer Clock Stop Trigger select (SetPacerStop) */
-#define PCLK_STOP_SOFTWARE 0x0 /* Software Pacer Stop (StopPacer) */
-#define PCLK_STOP_ETRIG 0x1 /* External Trigger */
-#define PCLK_STOP_DIGITAL_IT 0x2 /* Digital Interrupt */
-#define PCLK_STOP_ACNT 0x3 /* About Counter */
-#define PCLK_STOP_UTC2 0x4 /* User TC2 out */
-#define PCLK_STOP_SBUS0 0x5 /* SyncBus 0 */
-#define PCLK_STOP_SBUS1 0x6 /* SyncBus 1 */
-#define PCLK_STOP_SBUS2 0x7 /* SyncBus 2 */
-#define PCLK_STOP_A_SOFTWARE 0x8 /* About Software Pacer Stop */
-#define PCLK_STOP_A_ETRIG 0x9 /* About External Trigger */
-#define PCLK_STOP_A_DIGITAL_IT 0xA /* About Digital Interrupt */
-#define PCLK_STOP_A_UTC2 0xC /* About User TC2 out */
-#define PCLK_STOP_A_SBUS0 0xD /* About SyncBus 0 */
-#define PCLK_STOP_A_SBUS1 0xE /* About SyncBus 1 */
-#define PCLK_STOP_A_SBUS2 0xF /* About SyncBus 2 */
-
-/* About Counter Stop Enable */
-#define ACNT_STOP 0x0 /* stop enable */
-#define ACNT_NO_STOP 0x1 /* stop disabled */
-
-/* DAC update source (SetDAC1Start & SetDAC2Start) */
-#define DAC_START_SOFTWARE 0x0 /* Software Update */
-#define DAC_START_CGT 0x1 /* CGT controlled Update */
-#define DAC_START_DAC_CLK 0x2 /* D/A Clock */
-#define DAC_START_EPCLK 0x3 /* External Pacer Clock */
-#define DAC_START_SBUS0 0x4 /* SyncBus 0 */
-#define DAC_START_SBUS1 0x5 /* SyncBus 1 */
-#define DAC_START_SBUS2 0x6 /* SyncBus 2 */
-
-/* DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC) */
-#define DAC_CYCLE_SINGLE 0x0 /* not cycle */
-#define DAC_CYCLE_MULTI 0x1 /* cycle */
-
-/* 8254 Operation Modes (Set8254Mode, SetupTimerCounter) */
-#define M8254_EVENT_COUNTER 0 /* Event Counter */
-#define M8254_HW_ONE_SHOT 1 /* Hardware-Retriggerable One-Shot */
-#define M8254_RATE_GENERATOR 2 /* Rate Generator */
-#define M8254_SQUARE_WAVE 3 /* Square Wave Mode */
-#define M8254_SW_STROBE 4 /* Software Triggered Strobe */
-#define M8254_HW_STROBE 5 /* Hardware Triggered Strobe (Retriggerable) */
-
-/* User Timer/Counter 0 Clock Select (SetUtc0Clock) */
-#define CUTC0_8MHZ 0x0 /* 8MHz */
-#define CUTC0_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
-#define CUTC0_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
-#define CUTC0_EXT_PCLK 0x3 /* Ext. Pacer Clock */
-
-/* User Timer/Counter 1 Clock Select (SetUtc1Clock) */
-#define CUTC1_8MHZ 0x0 /* 8MHz */
-#define CUTC1_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
-#define CUTC1_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
-#define CUTC1_EXT_PCLK 0x3 /* Ext. Pacer Clock */
-#define CUTC1_UTC0_OUT 0x4 /* User Timer/Counter 0 out */
-#define CUTC1_DIN_SIGNAL 0x5 /* High-Speed Digital Input Sampling signal */
-
-/* User Timer/Counter 2 Clock Select (SetUtc2Clock) */
-#define CUTC2_8MHZ 0x0 /* 8MHz */
-#define CUTC2_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
-#define CUTC2_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
-#define CUTC2_EXT_PCLK 0x3 /* Ext. Pacer Clock */
-#define CUTC2_UTC1_OUT 0x4 /* User Timer/Counter 1 out */
-
-/* User Timer/Counter 0 Gate Select (SetUtc0Gate) */
-#define GUTC0_NOT_GATED 0x0 /* Not gated */
-#define GUTC0_GATED 0x1 /* Gated */
-#define GUTC0_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
-#define GUTC0_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
-
-/* User Timer/Counter 1 Gate Select (SetUtc1Gate) */
-#define GUTC1_NOT_GATED 0x0 /* Not gated */
-#define GUTC1_GATED 0x1 /* Gated */
-#define GUTC1_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
-#define GUTC1_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
-#define GUTC1_UTC0_OUT 0x4 /* User Timer/Counter 0 out */
-
-/* User Timer/Counter 2 Gate Select (SetUtc2Gate) */
-#define GUTC2_NOT_GATED 0x0 /* Not gated */
-#define GUTC2_GATED 0x1 /* Gated */
-#define GUTC2_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
-#define GUTC2_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
-#define GUTC2_UTC1_OUT 0x4 /* User Timer/Counter 1 out */
-
-/* Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus) */
-#define IRQM_ADC_FIFO_WRITE 0x0001 /* ADC FIFO Write */
-#define IRQM_CGT_RESET 0x0002 /* Reset CGT */
-#define IRQM_CGT_PAUSE 0x0008 /* Pause CGT */
-#define IRQM_ADC_ABOUT_CNT 0x0010 /* About Counter out */
-#define IRQM_ADC_DELAY_CNT 0x0020 /* Delay Counter out */
-#define IRQM_ADC_SAMPLE_CNT 0x0040 /* ADC Sample Counter */
-#define IRQM_DAC1_UCNT 0x0080 /* DAC1 Update Counter */
-#define IRQM_DAC2_UCNT 0x0100 /* DAC2 Update Counter */
-#define IRQM_UTC1 0x0200 /* User TC1 out */
-#define IRQM_UTC1_INV 0x0400 /* User TC1 out, inverted */
-#define IRQM_UTC2 0x0800 /* User TC2 out */
-#define IRQM_DIGITAL_IT 0x1000 /* Digital Interrupt */
-#define IRQM_EXTERNAL_IT 0x2000 /* External Interrupt */
-#define IRQM_ETRIG_RISING 0x4000 /* External Trigger rising-edge */
-#define IRQM_ETRIG_FALLING 0x8000 /* External Trigger falling-edge */
-
-/* DMA Request Sources (LAS0) */
-#define DMAS_DISABLED 0x0 /* DMA Disabled */
-#define DMAS_ADC_SCNT 0x1 /* ADC Sample Counter */
-#define DMAS_DAC1_UCNT 0x2 /* D/A1 Update Counter */
-#define DMAS_DAC2_UCNT 0x3 /* D/A2 Update Counter */
-#define DMAS_UTC1 0x4 /* User TC1 out */
-#define DMAS_ADFIFO_HALF_FULL 0x8 /* A/D FIFO half full */
-#define DMAS_DAC1_FIFO_HALF_EMPTY 0x9 /* D/A1 FIFO half empty */
-#define DMAS_DAC2_FIFO_HALF_EMPTY 0xA /* D/A2 FIFO half empty */
-
-/* DMA Local Addresses (0x40000000+LAS1 offset) */
-#define DMALADDR_ADC 0x40000000 /* A/D FIFO */
-#define DMALADDR_HDIN 0x40000004 /* High Speed Digital Input FIFO */
-#define DMALADDR_DAC1 0x40000008 /* D/A1 FIFO */
-#define DMALADDR_DAC2 0x4000000C /* D/A2 FIFO */
-
-/* Port 0 compare modes (SetDIO0CompareMode) */
-#define DIO_MODE_EVENT 0 /* Event Mode */
-#define DIO_MODE_MATCH 1 /* Match Mode */
-
-/* Digital Table Enable (Port 1 disable) */
-#define DTBL_DISABLE 0 /* Enable Digital Table */
-#define DTBL_ENABLE 1 /* Disable Digital Table */
-
-/* Sampling Signal for High Speed Digital Input (SetHdinStart) */
-#define HDIN_SOFTWARE 0x0 /* Software Trigger */
-#define HDIN_ADC 0x1 /* A/D Conversion Signal */
-#define HDIN_UTC0 0x2 /* User TC out 0 */
-#define HDIN_UTC1 0x3 /* User TC out 1 */
-#define HDIN_UTC2 0x4 /* User TC out 2 */
-#define HDIN_EPCLK 0x5 /* External Pacer Clock */
-#define HDIN_ETRG 0x6 /* External Trigger */
-
-/* Channel Gain Table / Channel Gain Latch */
-#define CSC_LATCH 0 /* Channel Gain Latch mode */
-#define CSC_CGT 1 /* Channel Gain Table mode */
-
-/* Channel Gain Table Pause Enable */
-#define CGT_PAUSE_DISABLE 0 /* Channel Gain Table Pause Disable */
-#define CGT_PAUSE_ENABLE 1 /* Channel Gain Table Pause Enable */
-
-/* DAC output type/range (p63) */
-#define AOUT_UNIP5 0 /* 0..+5 Volt */
-#define AOUT_UNIP10 1 /* 0..+10 Volt */
-#define AOUT_BIP5 2 /* -5..+5 Volt */
-#define AOUT_BIP10 3 /* -10..+10 Volt */
-
-/* Ghannel Gain Table field definitions (p61) */
-/* Gain */
-#define GAIN1 0
-#define GAIN2 1
-#define GAIN4 2
-#define GAIN8 3
-#define GAIN16 4
-#define GAIN32 5
-#define GAIN64 6
-#define GAIN128 7
-
-/* Input range/polarity */
-#define AIN_BIP5 0 /* -5..+5 Volt */
-#define AIN_BIP10 1 /* -10..+10 Volt */
-#define AIN_UNIP10 2 /* 0..+10 Volt */
-
-/* non referenced single ended select bit */
-#define NRSE_AGND 0 /* AGND referenced SE input */
-#define NRSE_AINS 1 /* AIN SENSE referenced SE input */
-
-/* single ended vs differential */
-#define GND_SE 0 /* Single-Ended */
-#define GND_DIFF 1 /* Differential */
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index 7e577e44490..f4163fd35a0 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -1,186 +1,184 @@
/*
- comedi/drivers/rti800.c
- Hardware driver for Analog Devices RTI-800/815 board
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-
- 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.
-
+ * comedi/drivers/rti800.c
+ * Hardware driver for Analog Devices RTI-800/815 board
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
+ * 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: rti800
-Description: Analog Devices RTI-800/815
-Author: ds
-Status: unknown
-Updated: Fri, 05 Sep 2008 14:50:44 +0100
-Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
-
-Configuration options:
- [0] - I/O port base address
- [1] - IRQ
- [2] - A/D reference
- 0 = differential
- 1 = pseudodifferential (common)
- 2 = single-ended
- [3] - A/D range
- 0 = [-10,10]
- 1 = [-5,5]
- 2 = [0,10]
- [4] - A/D encoding
- 0 = two's complement
- 1 = straight binary
- [5] - DAC 0 range
- 0 = [-10,10]
- 1 = [0,10]
- [6] - DAC 0 encoding
- 0 = two's complement
- 1 = straight binary
- [7] - DAC 1 range (same as DAC 0)
- [8] - DAC 1 encoding (same as DAC 0)
-*/
+ * Driver: rti800
+ * Description: Analog Devices RTI-800/815
+ * Devices: (Analog Devices) RTI-800 [rti800]
+ * (Analog Devices) RTI-815 [rti815]
+ * Author: David A. Schleef <ds@schleef.org>
+ * Status: unknown
+ * Updated: Fri, 05 Sep 2008 14:50:44 +0100
+ *
+ * Configuration options:
+ * [0] - I/O port base address
+ * [1] - IRQ (not supported / unused)
+ * [2] - A/D mux/reference (number of channels)
+ * 0 = differential
+ * 1 = pseudodifferential (common)
+ * 2 = single-ended
+ * [3] - A/D range
+ * 0 = [-10,10]
+ * 1 = [-5,5]
+ * 2 = [0,10]
+ * [4] - A/D encoding
+ * 0 = two's complement
+ * 1 = straight binary
+ * [5] - DAC 0 range
+ * 0 = [-10,10]
+ * 1 = [0,10]
+ * [6] - DAC 0 encoding
+ * 0 = two's complement
+ * 1 = straight binary
+ * [7] - DAC 1 range (same as DAC 0)
+ * [8] - DAC 1 encoding (same as DAC 0)
+ */
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
-#define RTI800_SIZE 16
-
-#define RTI800_CSR 0
-#define RTI800_MUXGAIN 1
-#define RTI800_CONVERT 2
-#define RTI800_ADCLO 3
-#define RTI800_ADCHI 4
-#define RTI800_DAC0LO 5
-#define RTI800_DAC0HI 6
-#define RTI800_DAC1LO 7
-#define RTI800_DAC1HI 8
-#define RTI800_CLRFLAGS 9
-#define RTI800_DI 10
-#define RTI800_DO 11
-#define RTI800_9513A_DATA 12
-#define RTI800_9513A_CNTRL 13
-#define RTI800_9513A_STATUS 13
-
/*
- * flags for CSR register
+ * Register map
*/
+#define RTI800_CSR 0x00
+#define RTI800_CSR_BUSY (1 << 7)
+#define RTI800_CSR_DONE (1 << 6)
+#define RTI800_CSR_OVERRUN (1 << 5)
+#define RTI800_CSR_TCR (1 << 4)
+#define RTI800_CSR_DMA_ENAB (1 << 3)
+#define RTI800_CSR_INTR_TC (1 << 2)
+#define RTI800_CSR_INTR_EC (1 << 1)
+#define RTI800_CSR_INTR_OVRN (1 << 0)
+#define RTI800_MUXGAIN 0x01
+#define RTI800_CONVERT 0x02
+#define RTI800_ADCLO 0x03
+#define RTI800_ADCHI 0x04
+#define RTI800_DAC0LO 0x05
+#define RTI800_DAC0HI 0x06
+#define RTI800_DAC1LO 0x07
+#define RTI800_DAC1HI 0x08
+#define RTI800_CLRFLAGS 0x09
+#define RTI800_DI 0x0a
+#define RTI800_DO 0x0b
+#define RTI800_9513A_DATA 0x0c
+#define RTI800_9513A_CNTRL 0x0d
+#define RTI800_9513A_STATUS 0x0d
+
+#define RTI800_IOSIZE 0x10
+
+#define RTI800_AI_TIMEOUT 100
+
+static const struct comedi_lrange range_rti800_ai_10_bipolar = {
+ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.02)
+ }
+};
-#define RTI800_BUSY 0x80
-#define RTI800_DONE 0x40
-#define RTI800_OVERRUN 0x20
-#define RTI800_TCR 0x10
-#define RTI800_DMA_ENAB 0x08
-#define RTI800_INTR_TC 0x04
-#define RTI800_INTR_EC 0x02
-#define RTI800_INTR_OVRN 0x01
-
-#define Am9513_8BITBUS
-
-#define Am9513_output_control(a) outb(a, dev->iobase+RTI800_9513A_CNTRL)
-#define Am9513_output_data(a) outb(a, dev->iobase+RTI800_9513A_DATA)
-#define Am9513_input_data() inb(dev->iobase+RTI800_9513A_DATA)
-#define Am9513_input_status() inb(dev->iobase+RTI800_9513A_STATUS)
-
-#include "am9513.h"
-
-static const struct comedi_lrange range_rti800_ai_10_bipolar = { 4, {
- BIP_RANGE
- (10),
- BIP_RANGE
- (1),
- BIP_RANGE
- (0.1),
- BIP_RANGE
- (0.02)
- }
+static const struct comedi_lrange range_rti800_ai_5_bipolar = {
+ 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01)
+ }
};
-static const struct comedi_lrange range_rti800_ai_5_bipolar = { 4, {
- BIP_RANGE
- (5),
- BIP_RANGE
- (0.5),
- BIP_RANGE
- (0.05),
- BIP_RANGE
- (0.01)
- }
+static const struct comedi_lrange range_rti800_ai_unipolar = {
+ 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.02)
+ }
};
-static const struct comedi_lrange range_rti800_ai_unipolar = { 4, {
- UNI_RANGE
- (10),
- UNI_RANGE(1),
- UNI_RANGE
- (0.1),
- UNI_RANGE
- (0.02)
- }
+static const struct comedi_lrange *const rti800_ai_ranges[] = {
+ &range_rti800_ai_10_bipolar,
+ &range_rti800_ai_5_bipolar,
+ &range_rti800_ai_unipolar,
};
-struct rti800_board {
+static const struct comedi_lrange *const rti800_ao_ranges[] = {
+ &range_bipolar10,
+ &range_unipolar10,
+};
+struct rti800_board {
const char *name;
int has_ao;
};
-static irqreturn_t rti800_interrupt(int irq, void *dev);
+static const struct rti800_board rti800_boardtypes[] = {
+ {
+ .name = "rti800",
+ }, {
+ .name = "rti815",
+ .has_ao = 1,
+ },
+};
struct rti800_private {
- enum {
- adc_diff, adc_pseudodiff, adc_singleended
- } adc_mux;
- enum {
- adc_bipolar10, adc_bipolar5, adc_unipolar10
- } adc_range;
- enum {
- adc_2comp, adc_straight
- } adc_coding;
- enum {
- dac_bipolar10, dac_unipolar10
- } dac0_range, dac1_range;
- enum {
- dac_2comp, dac_straight
- } dac0_coding, dac1_coding;
+ bool adc_2comp;
+ bool dac_2comp[2];
const struct comedi_lrange *ao_range_type_list[2];
unsigned int ao_readback[2];
- int muxgain_bits;
+ unsigned char muxgain_bits;
};
-#define RTI800_TIMEOUT 100
-
-static irqreturn_t rti800_interrupt(int irq, void *dev)
+static int rti800_ai_wait_for_conversion(struct comedi_device *dev,
+ int timeout)
{
- return IRQ_HANDLED;
-}
+ unsigned char status;
+ int i;
-/* settling delay times in usec for different gains */
-static const int gaindelay[] = { 10, 20, 40, 80 };
+ for (i = 0; i < timeout; i++) {
+ status = inb(dev->iobase + RTI800_CSR);
+ if (status & RTI800_CSR_OVERRUN) {
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+ return -EIO;
+ }
+ if (status & RTI800_CSR_DONE)
+ return 0;
+ udelay(1);
+ }
+ return -ETIME;
+}
static int rti800_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct rti800_private *devpriv = dev->private;
- int i, t;
- int status;
- int chan = CR_CHAN(insn->chanspec);
- unsigned gain = CR_RANGE(insn->chanspec);
- unsigned muxgain_bits;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int gain = CR_RANGE(insn->chanspec);
+ unsigned char muxgain_bits;
+ int ret;
+ int i;
inb(dev->iobase + RTI800_ADCHI);
outb(0, dev->iobase + RTI800_CLRFLAGS);
@@ -189,80 +187,80 @@ static int rti800_ai_insn_read(struct comedi_device *dev,
if (muxgain_bits != devpriv->muxgain_bits) {
devpriv->muxgain_bits = muxgain_bits;
outb(devpriv->muxgain_bits, dev->iobase + RTI800_MUXGAIN);
- /* without a delay here, the RTI_OVERRUN bit
- * gets set, and you will have an error. */
+ /*
+ * Without a delay here, the RTI_CSR_OVERRUN bit
+ * gets set, and you will have an error.
+ */
if (insn->n > 0) {
- BUG_ON(gain >= ARRAY_SIZE(gaindelay));
- udelay(gaindelay[gain]);
+ int delay = (gain == 0) ? 10 :
+ (gain == 1) ? 20 :
+ (gain == 2) ? 40 : 80;
+
+ udelay(delay);
}
}
for (i = 0; i < insn->n; i++) {
outb(0, dev->iobase + RTI800_CONVERT);
- for (t = RTI800_TIMEOUT; t; t--) {
- status = inb(dev->iobase + RTI800_CSR);
- if (status & RTI800_OVERRUN) {
- printk(KERN_WARNING "rti800: a/d overrun\n");
- outb(0, dev->iobase + RTI800_CLRFLAGS);
- return -EIO;
- }
- if (status & RTI800_DONE)
- break;
- udelay(1);
- }
- if (t == 0) {
- printk(KERN_WARNING "rti800: timeout\n");
- return -ETIME;
- }
+ ret = rti800_ai_wait_for_conversion(dev, RTI800_AI_TIMEOUT);
+ if (ret)
+ return ret;
+
data[i] = inb(dev->iobase + RTI800_ADCLO);
- data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
+ data[i] |= (inb(dev->iobase + RTI800_ADCHI) & 0xf) << 8;
- if (devpriv->adc_coding == adc_2comp)
+ if (devpriv->adc_2comp)
data[i] ^= 0x800;
}
- return i;
+ return insn->n;
}
static int rti800_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct rti800_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
int i;
- int chan = CR_CHAN(insn->chanspec);
for (i = 0; i < insn->n; i++)
data[i] = devpriv->ao_readback[chan];
- return i;
+ return insn->n;
}
static int rti800_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct rti800_private *devpriv = dev->private;
- int chan = CR_CHAN(insn->chanspec);
- int d;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int reg_lo = chan ? RTI800_DAC1LO : RTI800_DAC0LO;
+ int reg_hi = chan ? RTI800_DAC1HI : RTI800_DAC0HI;
+ int val = devpriv->ao_readback[chan];
int i;
for (i = 0; i < insn->n; i++) {
- devpriv->ao_readback[chan] = d = data[i];
- if (devpriv->dac0_coding == dac_2comp)
- d ^= 0x800;
-
- outb(d & 0xff,
- dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
- outb(d >> 8,
- dev->iobase + (chan ? RTI800_DAC1HI : RTI800_DAC0HI));
+ val = data[i];
+ if (devpriv->dac_2comp[chan])
+ val ^= 0x800;
+
+ outb(val & 0xff, dev->iobase + reg_lo);
+ outb((val >> 8) & 0xff, dev->iobase + reg_hi);
}
- return i;
+
+ devpriv->ao_readback[chan] = val;
+
+ return insn->n;
}
static int rti800_di_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
data[1] = inb(dev->iobase + RTI800_DI);
return insn->n;
@@ -270,11 +268,16 @@ static int rti800_di_insn_bits(struct comedi_device *dev,
static int rti800_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- if (data[0]) {
- s->state &= ~data[0];
- s->state |= data[0] & data[1];
+ unsigned int mask = data[0];
+ unsigned int bits = data[1];
+
+ if (mask) {
+ s->state &= ~mask;
+ s->state |= (bits & mask);
+
/* Outputs are inverted... */
outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
}
@@ -284,186 +287,106 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
return insn->n;
}
-/*
- options[0] - I/O port
- options[1] - irq
- options[2] - a/d mux
- 0=differential, 1=pseudodiff, 2=single
- options[3] - a/d range
- 0=bipolar10, 1=bipolar5, 2=unipolar10
- options[4] - a/d coding
- 0=2's comp, 1=straight binary
- options[5] - dac0 range
- 0=bipolar10, 1=unipolar10
- options[6] - dac0 coding
- 0=2's comp, 1=straight binary
- options[7] - dac1 range
- options[8] - dac1 coding
- */
-
static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct rti800_board *board = comedi_board(dev);
struct rti800_private *devpriv;
- unsigned int irq;
- unsigned long iobase;
- int ret;
struct comedi_subdevice *s;
+ int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: rti800: 0x%04lx\n", dev->minor, iobase);
- if (!request_region(iobase, RTI800_SIZE, "rti800")) {
- printk(KERN_WARNING "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "fingerprint=%x,%x,%x,%x,%x ",
- inb(dev->iobase + 0),
- inb(dev->iobase + 1),
- inb(dev->iobase + 2),
- inb(dev->iobase + 3), inb(dev->iobase + 4));
-#endif
+ ret = comedi_request_region(dev, it->options[0], RTI800_IOSIZE);
+ if (ret)
+ return ret;
outb(0, dev->iobase + RTI800_CSR);
inb(dev->iobase + RTI800_ADCHI);
outb(0, dev->iobase + RTI800_CLRFLAGS);
- irq = it->options[1];
- if (irq) {
- printk(KERN_INFO "( irq = %u )\n", irq);
- ret = request_irq(irq, rti800_interrupt, 0, "rti800", dev);
- if (ret < 0) {
- printk(KERN_WARNING " Failed to allocate IRQ\n");
- return ret;
- }
- dev->irq = irq;
- } else {
- printk(KERN_INFO "( no irq )\n");
- }
-
- dev->board_name = board->name;
-
- ret = comedi_alloc_subdevices(dev, 4);
- if (ret)
- return ret;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- devpriv->adc_mux = it->options[2];
- devpriv->adc_range = it->options[3];
- devpriv->adc_coding = it->options[4];
- devpriv->dac0_range = it->options[5];
- devpriv->dac0_coding = it->options[6];
- devpriv->dac1_range = it->options[7];
- devpriv->dac1_coding = it->options[8];
- devpriv->muxgain_bits = -1;
+ devpriv->adc_2comp = (it->options[4] == 0);
+ devpriv->dac_2comp[0] = (it->options[6] == 0);
+ devpriv->dac_2comp[1] = (it->options[8] == 0);
+ /* invalid, forces the MUXGAIN register to be set when first used */
+ devpriv->muxgain_bits = 0xff;
+
+ ret = comedi_alloc_subdevices(dev, 4);
+ if (ret)
+ return ret;
s = &dev->subdevices[0];
/* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = (devpriv->adc_mux ? 16 : 8);
- s->insn_read = rti800_ai_insn_read;
- s->maxdata = 0xfff;
- switch (devpriv->adc_range) {
- case adc_bipolar10:
- s->range_table = &range_rti800_ai_10_bipolar;
- break;
- case adc_bipolar5:
- s->range_table = &range_rti800_ai_5_bipolar;
- break;
- case adc_unipolar10:
- s->range_table = &range_rti800_ai_unipolar;
- break;
- }
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = (it->options[2] ? 16 : 8);
+ s->insn_read = rti800_ai_insn_read;
+ s->maxdata = 0x0fff;
+ s->range_table = (it->options[3] < ARRAY_SIZE(rti800_ai_ranges))
+ ? rti800_ai_ranges[it->options[3]]
+ : &range_unknown;
s = &dev->subdevices[1];
if (board->has_ao) {
/* ao subdevice (only on rti815) */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
- s->insn_read = rti800_ao_insn_read;
- s->insn_write = rti800_ao_insn_write;
- s->maxdata = 0xfff;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = rti800_ao_insn_read;
+ s->insn_write = rti800_ao_insn_write;
+ s->maxdata = 0x0fff;
s->range_table_list = devpriv->ao_range_type_list;
- switch (devpriv->dac0_range) {
- case dac_bipolar10:
- devpriv->ao_range_type_list[0] = &range_bipolar10;
- break;
- case dac_unipolar10:
- devpriv->ao_range_type_list[0] = &range_unipolar10;
- break;
- }
- switch (devpriv->dac1_range) {
- case dac_bipolar10:
- devpriv->ao_range_type_list[1] = &range_bipolar10;
- break;
- case dac_unipolar10:
- devpriv->ao_range_type_list[1] = &range_unipolar10;
- break;
- }
+ devpriv->ao_range_type_list[0] =
+ (it->options[5] < ARRAY_SIZE(rti800_ao_ranges))
+ ? rti800_ao_ranges[it->options[5]]
+ : &range_unknown;
+ devpriv->ao_range_type_list[1] =
+ (it->options[7] < ARRAY_SIZE(rti800_ao_ranges))
+ ? rti800_ao_ranges[it->options[7]]
+ : &range_unknown;
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[2];
/* di */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 8;
- s->insn_bits = rti800_di_insn_bits;
- s->maxdata = 1;
- s->range_table = &range_digital;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = rti800_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
s = &dev->subdevices[3];
/* do */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->insn_bits = rti800_do_insn_bits;
- s->maxdata = 1;
- s->range_table = &range_digital;
-
-/* don't yet know how to deal with counter/timers */
-#if 0
- s = &dev->subdevices[4];
- /* do */
- s->type = COMEDI_SUBD_TIMER;
-#endif
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_bits = rti800_do_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ /*
+ * There is also an Am9513 timer on these boards. This subdevice
+ * is not currently supported.
+ */
return 0;
}
-static void rti800_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, RTI800_SIZE);
- if (dev->irq)
- free_irq(dev->irq, dev);
-}
-
-static const struct rti800_board boardtypes[] = {
- { "rti800", 0 },
- { "rti815", 1 },
-};
-
static struct comedi_driver rti800_driver = {
.driver_name = "rti800",
.module = THIS_MODULE,
.attach = rti800_attach,
- .detach = rti800_detach,
- .num_names = ARRAY_SIZE(boardtypes),
- .board_name = &boardtypes[0].name,
+ .detach = comedi_legacy_detach,
+ .num_names = ARRAY_SIZE(rti800_boardtypes),
+ .board_name = &rti800_boardtypes[0].name,
.offset = sizeof(struct rti800_board),
};
module_comedi_driver(rti800_driver);
+MODULE_DESCRIPTION("Comedi: RTI-800 Multifunction Analog/Digital board");
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index 2185ca1bcf0..46dbbe6cdd7 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -92,18 +92,11 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct rti802_private *devpriv;
struct comedi_subdevice *s;
int i;
- unsigned long iobase;
int ret;
- iobase = it->options[0];
- printk(KERN_INFO "comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
- if (!request_region(iobase, RTI802_SIZE, "rti802")) {
- printk(KERN_WARNING "I/O port conflict\n");
- return -EIO;
- }
- dev->iobase = iobase;
-
- dev->board_name = "rti802";
+ ret = comedi_request_region(dev, it->options[0], RTI802_SIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -135,17 +128,11 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
return 0;
}
-static void rti802_detach(struct comedi_device *dev)
-{
- if (dev->iobase)
- release_region(dev->iobase, RTI802_SIZE);
-}
-
static struct comedi_driver rti802_driver = {
.driver_name = "rti802",
.module = THIS_MODULE,
.attach = rti802_attach,
- .detach = rti802_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(rti802_driver);
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index 39232b35945..d240ce87bd6 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -552,17 +552,11 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct s526_private *devpriv;
struct comedi_subdevice *s;
- int iobase;
int ret;
- dev->board_name = dev->driver->driver_name;
-
- iobase = it->options[0];
- if (!iobase || !request_region(iobase, S526_IOSIZE, dev->board_name)) {
- comedi_error(dev, "I/O port conflict");
- return -EIO;
- }
- dev->iobase = iobase;
+ ret = comedi_request_region(dev, it->options[0], S526_IOSIZE);
+ if (ret)
+ return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
@@ -616,22 +610,14 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->insn_bits = s526_dio_insn_bits;
s->insn_config = s526_dio_insn_config;
- dev_info(dev->class_dev, "%s attached\n", dev->board_name);
-
return 1;
}
-static void s526_detach(struct comedi_device *dev)
-{
- if (dev->iobase > 0)
- release_region(dev->iobase, S526_IOSIZE);
-}
-
static struct comedi_driver s526_driver = {
.driver_name = "s526",
.module = THIS_MODULE,
.attach = s526_attach,
- .detach = s526_detach,
+ .detach = comedi_legacy_detach,
};
module_comedi_driver(s526_driver);
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 81a1fe66157..0cf4b3d1279 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -80,7 +80,7 @@ INSN_CONFIG instructions:
#define PCI_SUBDEVICE_ID_S626 0x0272
struct s626_private {
- void __iomem *base_addr;
+ void __iomem *mmio;
uint8_t ai_cmd_running; /* ai_cmd is running */
uint8_t ai_continous; /* continous acquisition */
int ai_sample_count; /* number of samples to acquire */
@@ -106,64 +106,6 @@ struct s626_private {
unsigned int ao_readback[S626_DAC_CHANNELS];
};
-struct dio_private {
- uint16_t RDDIn;
- uint16_t WRDOut;
- uint16_t RDEdgSel;
- uint16_t WREdgSel;
- uint16_t RDCapSel;
- uint16_t WRCapSel;
- uint16_t RDCapFlg;
- uint16_t RDIntSel;
- uint16_t WRIntSel;
-};
-
-static struct dio_private dio_private_A = {
- .RDDIn = LP_RDDINA,
- .WRDOut = LP_WRDOUTA,
- .RDEdgSel = LP_RDEDGSELA,
- .WREdgSel = LP_WREDGSELA,
- .RDCapSel = LP_RDCAPSELA,
- .WRCapSel = LP_WRCAPSELA,
- .RDCapFlg = LP_RDCAPFLGA,
- .RDIntSel = LP_RDINTSELA,
- .WRIntSel = LP_WRINTSELA,
-};
-
-static struct dio_private dio_private_B = {
- .RDDIn = LP_RDDINB,
- .WRDOut = LP_WRDOUTB,
- .RDEdgSel = LP_RDEDGSELB,
- .WREdgSel = LP_WREDGSELB,
- .RDCapSel = LP_RDCAPSELB,
- .WRCapSel = LP_WRCAPSELB,
- .RDCapFlg = LP_RDCAPFLGB,
- .RDIntSel = LP_RDINTSELB,
- .WRIntSel = LP_WRINTSELB,
-};
-
-static struct dio_private dio_private_C = {
- .RDDIn = LP_RDDINC,
- .WRDOut = LP_WRDOUTC,
- .RDEdgSel = LP_RDEDGSELC,
- .WREdgSel = LP_WREDGSELC,
- .RDCapSel = LP_RDCAPSELC,
- .WRCapSel = LP_WRCAPSELC,
- .RDCapFlg = LP_RDCAPFLGC,
- .RDIntSel = LP_RDINTSELC,
- .WRIntSel = LP_WRINTSELC,
-};
-
-/* to group dio devices (48 bits mask and data are not allowed ???)
-static struct dio_private *dio_private_word[]={
- &dio_private_A,
- &dio_private_B,
- &dio_private_C,
-};
-*/
-
-#define diopriv ((struct dio_private *)s->private)
-
/* COUNTER OBJECT ------------------------------------------------ */
struct enc_private {
/* Pointers to functions that differ for A and B counters: */
@@ -195,37 +137,53 @@ struct enc_private {
/* Translation table to map IntSrc into equivalent RDMISC2 event flag bits. */
/* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
-/* enab/disable a function or test status bit(s) that are accessed */
-/* through Main Control Registers 1 or 2. */
-#define MC_ENABLE(REGADRS, CTRLWORD) writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS))
+/*
+ * Enable/disable a function or test status bit(s) that are accessed
+ * through Main Control Registers 1 or 2.
+ */
+static void s626_mc_enable(struct comedi_device *dev,
+ unsigned int cmd, unsigned int reg)
+{
+ struct s626_private *devpriv = dev->private;
+ unsigned int val = (cmd << 16) | cmd;
-#define MC_DISABLE(REGADRS, CTRLWORD) writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS))
+ writel(val, devpriv->mmio + reg);
+}
-#define MC_TEST(REGADRS, CTRLWORD) ((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0)
+static void s626_mc_disable(struct comedi_device *dev,
+ unsigned int cmd, unsigned int reg)
+{
+ struct s626_private *devpriv = dev->private;
-/* #define WR7146(REGARDS,CTRLWORD)
- writel(CTRLWORD,(uint32_t)(devpriv->base_addr+(REGARDS))) */
-#define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS))
+ writel(cmd << 16 , devpriv->mmio + reg);
+}
-/* #define RR7146(REGARDS)
- readl((uint32_t)(devpriv->base_addr+(REGARDS))) */
-#define RR7146(REGARDS) readl(devpriv->base_addr+(REGARDS))
+static bool s626_mc_test(struct comedi_device *dev,
+ unsigned int cmd, unsigned int reg)
+{
+ struct s626_private *devpriv = dev->private;
+ unsigned int val;
+
+ val = readl(devpriv->mmio + reg);
+
+ return (val & cmd) ? true : false;
+}
#define BUGFIX_STREG(REGADRS) (REGADRS - 4)
/* Write a time slot control record to TSL2. */
#define VECTPORT(VECTNUM) (P_TSL2 + ((VECTNUM) << 2))
-#define SETVECT(VECTNUM, VECTVAL) WR7146(VECTPORT(VECTNUM), (VECTVAL))
/* Code macros used for constructing I2C command bytes. */
#define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
#define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
#define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
-static const struct comedi_lrange s626_range_table = { 2, {
- RANGE(-5, 5),
- RANGE(-10, 10),
- }
+static const struct comedi_lrange s626_range_table = {
+ 2, {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ }
};
/* Execute a DEBI transfer. This must be called from within a */
@@ -234,16 +192,18 @@ static void DEBItransfer(struct comedi_device *dev)
{
struct s626_private *devpriv = dev->private;
- /* Initiate upload of shadow RAM to DEBI control register. */
- MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
+ /* Initiate upload of shadow RAM to DEBI control register */
+ s626_mc_enable(dev, MC2_UPLD_DEBI, P_MC2);
- /* Wait for completion of upload from shadow RAM to DEBI control */
- /* register. */
- while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
+ /*
+ * Wait for completion of upload from shadow RAM to
+ * DEBI control register.
+ */
+ while (!s626_mc_test(dev, MC2_UPLD_DEBI, P_MC2))
;
- /* Wait until DEBI transfer is done. */
- while (RR7146(P_PSR) & PSR_DEBI_S)
+ /* Wait until DEBI transfer is done */
+ while (readl(devpriv->mmio + P_PSR) & PSR_DEBI_S)
;
}
@@ -252,19 +212,14 @@ static void DEBItransfer(struct comedi_device *dev)
static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
{
struct s626_private *devpriv = dev->private;
- uint16_t retval;
- /* Set up DEBI control register value in shadow RAM. */
- WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
+ /* Set up DEBI control register value in shadow RAM */
+ writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD);
/* Execute the DEBI transfer. */
DEBItransfer(dev);
- /* Fetch target register value. */
- retval = (uint16_t) RR7146(P_DEBIAD);
-
- /* Return register value. */
- return retval;
+ return readl(devpriv->mmio + P_DEBIAD);
}
/* Write a value to a gate array register. */
@@ -272,9 +227,9 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
{
struct s626_private *devpriv = dev->private;
- /* Set up DEBI control register value in shadow RAM. */
- WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
- WR7146(P_DEBIAD, wdata);
+ /* Set up DEBI control register value in shadow RAM */
+ writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD);
+ writel(wdata, devpriv->mmio + P_DEBIAD);
/* Execute the DEBI transfer. */
DEBItransfer(dev);
@@ -284,23 +239,22 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
* specifies bits that are to be preserved, wdata is new value to be
* or'd with the masked original.
*/
-static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
- uint16_t wdata)
+static void DEBIreplace(struct comedi_device *dev, unsigned int addr,
+ unsigned int mask, unsigned int wdata)
{
struct s626_private *devpriv = dev->private;
+ unsigned int val;
- /* Copy target gate array register into P_DEBIAD register. */
- WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
- /* Set up DEBI control reg value in shadow RAM. */
- DEBItransfer(dev); /* Execute the DEBI Read transfer. */
-
- /* Write back the modified image. */
- WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
- /* Set up DEBI control reg value in shadow RAM. */
+ addr &= 0xffff;
+ writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD);
+ DEBItransfer(dev);
- WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));
- /* Modify the register image. */
- DEBItransfer(dev); /* Execute the DEBI Write transfer. */
+ writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD);
+ val = readl(devpriv->mmio + P_DEBIAD);
+ val &= mask;
+ val |= wdata;
+ writel(val & 0xffff, devpriv->mmio + P_DEBIAD);
+ DEBItransfer(dev);
}
/* ************** EEPROM ACCESS FUNCTIONS ************** */
@@ -308,31 +262,32 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
{
struct s626_private *devpriv = dev->private;
+ unsigned int ctrl;
- /* Write I2C command to I2C Transfer Control shadow register. */
- WR7146(P_I2CCTRL, val);
-
- /* Upload I2C shadow registers into working registers and wait for */
- /* upload confirmation. */
-
- MC_ENABLE(P_MC2, MC2_UPLD_IIC);
- while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
- ;
+ /* Write I2C command to I2C Transfer Control shadow register */
+ writel(val, devpriv->mmio + P_I2CCTRL);
- /* Wait until I2C bus transfer is finished or an error occurs. */
- while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY)
+ /*
+ * Upload I2C shadow registers into working registers and
+ * wait for upload confirmation.
+ */
+ s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
+ while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2))
;
- /* Return non-zero if I2C error occurred. */
- return RR7146(P_I2CCTRL) & I2C_ERR;
+ /* Wait until I2C bus transfer is finished or an error occurs */
+ do {
+ ctrl = readl(devpriv->mmio + P_I2CCTRL);
+ } while ((ctrl & (I2C_BUSY | I2C_ERR)) == I2C_BUSY);
+ /* Return non-zero if I2C error occurred */
+ return ctrl & I2C_ERR;
}
/* Read uint8_t from EEPROM. */
static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
{
struct s626_private *devpriv = dev->private;
- uint8_t rtnval;
/* Send EEPROM target address. */
if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
@@ -360,9 +315,8 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
/* Abort function and declare error if handshake failed. */
return 0;
}
- /* Return copy of EEPROM value. */
- rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16);
- return rtnval;
+
+ return (readl(devpriv->mmio + P_I2CCTRL) >> 16) & 0xff;
}
/* *********** DAC FUNCTIONS *********** */
@@ -402,23 +356,25 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
/* Copy DAC setpoint value to DAC's output DMA buffer. */
- /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */
+ /* writel(val, devpriv->mmio + (uint32_t)devpriv->pDacWBuf); */
*devpriv->pDacWBuf = val;
- /* enab the output DMA transfer. This will cause the DMAC to copy
- * the DAC's data value to A2's output FIFO. The DMA transfer will
+ /*
+ * Enable the output DMA transfer. This will cause the DMAC to copy
+ * the DAC's data value to A2's output FIFO. The DMA transfer will
* then immediately terminate because the protection address is
* reached upon transfer of the first DWORD value.
*/
- MC_ENABLE(P_MC1, MC1_A2OUT);
+ s626_mc_enable(dev, MC1_A2OUT, P_MC1);
/* While the DMA transfer is executing ... */
- /* Reset Audio2 output FIFO's underflow flag (along with any other
- * FIFO underflow/overflow flags). When set, this flag will
- * indicate that we have emerged from slot 0.
+ /*
+ * Reset Audio2 output FIFO's underflow flag (along with any
+ * other FIFO underflow/overflow flags). When set, this flag
+ * will indicate that we have emerged from slot 0.
*/
- WR7146(P_ISR, ISR_AFOU);
+ writel(ISR_AFOU, devpriv->mmio + P_ISR);
/* Wait for the DMA transfer to finish so that there will be data
* available in the FIFO when time slot 1 tries to transfer a DWORD
@@ -426,7 +382,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
* Done by polling the DMAC enable flag; this flag is automatically
* cleared when the transfer has finished.
*/
- while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
+ while (readl(devpriv->mmio + P_MC1) & MC1_A2OUT)
;
/* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
@@ -436,7 +392,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
* will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
* detection.
*/
- SETVECT(0, XSD2 | RSD3 | SIB_A2);
+ writel(XSD2 | RSD3 | SIB_A2, devpriv->mmio + VECTPORT(0));
/* Wait for slot 1 to execute to ensure that the Packet will be
* transmitted. This is detected by polling the Audio2 output FIFO
@@ -444,7 +400,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
* finished transferring the DAC's data DWORD from the output FIFO
* to the output buffer register.
*/
- while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
+ while (!(readl(devpriv->mmio + P_SSR) & SSR_AF2_OUT))
;
/* Set up to trap execution at slot 0 when the TSL sequencer cycles
@@ -453,7 +409,8 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
* stored in the last byte to be shifted out of the FIFO's DWORD
* buffer register.
*/
- SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS);
+ writel(XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS,
+ devpriv->mmio + VECTPORT(0));
/* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
@@ -474,14 +431,14 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
* we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
* the TSL has not yet finished executing slot 5 ...
*/
- if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) {
+ if (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000) {
/* The trap was set on time and we are still executing somewhere
* in slots 2-5, so we now wait for slot 0 to execute and trap
* TSL execution. This is detected when FB_BUFFER2 MSB changes
* from 0xFF to 0x00, which slot 0 causes to happen by shifting
* out/in on SD2 the 0x00 that is always referenced by slot 5.
*/
- while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0)
+ while (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000)
;
}
/* Either (1) we were too late setting the slot 0 trap; the TSL
@@ -492,13 +449,13 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
* In order to do this, we reprogram slot 0 so that it will shift in
* SD3, which is driven only by a pull-up resistor.
*/
- SETVECT(0, RSD3 | SIB_A2 | EOS);
+ writel(RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0));
/* Wait for slot 0 to execute, at which time the TSL is setup for
* the next DAC write. This is detected when FB_BUFFER2 MSB changes
* from 0x00 to 0xFF.
*/
- while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
+ while (!(readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000))
;
}
@@ -532,16 +489,16 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
* disables gating for the DAC clock and all DAC chip selects.
*/
+ /* Choose DAC chip select to be asserted */
WSImage = (chan & 2) ? WS1 : WS2;
- /* Choose DAC chip select to be asserted. */
- SETVECT(2, XSD2 | XFIFO_1 | WSImage);
- /* Slot 2: Transmit high data byte to target DAC. */
- SETVECT(3, XSD2 | XFIFO_0 | WSImage);
- /* Slot 3: Transmit low data byte to target DAC. */
- SETVECT(4, XSD2 | XFIFO_3 | WS3);
+ /* Slot 2: Transmit high data byte to target DAC */
+ writel(XSD2 | XFIFO_1 | WSImage, devpriv->mmio + VECTPORT(2));
+ /* Slot 3: Transmit low data byte to target DAC */
+ writel(XSD2 | XFIFO_0 | WSImage, devpriv->mmio + VECTPORT(3));
/* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
- SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);
- /* Slot 5: running after writing target DAC's low data byte. */
+ writel(XSD2 | XFIFO_3 | WS3, devpriv->mmio + VECTPORT(4));
+ /* Slot 5: running after writing target DAC's low data byte */
+ writel(XSD2 | XFIFO_2 | WS3 | EOS, devpriv->mmio + VECTPORT(5));
/* Construct and transmit target DAC's serial packet:
* ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
@@ -577,14 +534,14 @@ static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
* can be detected.
*/
- SETVECT(2, XSD2 | XFIFO_1 | WS3);
- /* Slot 2: Send high uint8_t to target TrimDac. */
- SETVECT(3, XSD2 | XFIFO_0 | WS3);
- /* Slot 3: Send low uint8_t to target TrimDac. */
- SETVECT(4, XSD2 | XFIFO_3 | WS1);
- /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */
- SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);
- /* Slot 5: Send NOP low uint8_t to DAC0. */
+ /* Slot 2: Send high uint8_t to target TrimDac */
+ writel(XSD2 | XFIFO_1 | WS3, devpriv->mmio + VECTPORT(2));
+ /* Slot 3: Send low uint8_t to target TrimDac */
+ writel(XSD2 | XFIFO_0 | WS3, devpriv->mmio + VECTPORT(3));
+ /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */
+ writel(XSD2 | XFIFO_3 | WS1, devpriv->mmio + VECTPORT(4));
+ /* Slot 5: Send NOP low uint8_t to DAC0 */
+ writel(XSD2 | XFIFO_2 | WS1 | EOS, devpriv->mmio + VECTPORT(5));
/* Construct and transmit target DAC's serial packet:
* ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
@@ -638,8 +595,8 @@ static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
uint16_t value)
{
DEBIreplace(dev, k->MyCRB,
- (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)),
- (uint16_t) (value << CRBBIT_LATCHSRC));
+ ~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC),
+ value << CRBBIT_LATCHSRC);
}
/* Write value into counter preload register. */
@@ -670,43 +627,24 @@ static unsigned int s626_ai_reg_to_uint(int data)
static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
{
- unsigned int group;
- unsigned int bitmask;
+ unsigned int group = chan / 16;
+ unsigned int mask = 1 << (chan - (16 * group));
unsigned int status;
- /* select dio bank */
- group = chan / 16;
- bitmask = 1 << (chan - (16 * group));
-
/* set channel to capture positive edge */
- status = DEBIread(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->RDEdgSel);
- DEBIwrite(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->WREdgSel,
- bitmask | status);
+ status = DEBIread(dev, LP_RDEDGSEL(group));
+ DEBIwrite(dev, LP_WREDGSEL(group), mask | status);
/* enable interrupt on selected channel */
- status = DEBIread(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->RDIntSel);
- DEBIwrite(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->WRIntSel,
- bitmask | status);
+ status = DEBIread(dev, LP_RDINTSEL(group));
+ DEBIwrite(dev, LP_WRINTSEL(group), mask | status);
/* enable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
/* enable edge capture on selected channel */
- status = DEBIread(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->RDCapSel);
- DEBIwrite(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->WRCapSel,
- bitmask | status);
+ status = DEBIread(dev, LP_RDCAPSEL(group));
+ DEBIwrite(dev, LP_WRCAPSEL(group), mask | status);
return 0;
}
@@ -718,9 +656,7 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
/* enable edge capture on selected channel */
- DEBIwrite(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->WRCapSel, mask);
+ DEBIwrite(dev, LP_WRCAPSEL(group), mask);
return 0;
}
@@ -732,244 +668,249 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
/* disable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
- for (group = 0; group < S626_DIO_BANKS; group++) {
- /* clear pending events and interrupt */
- DEBIwrite(dev,
- ((struct dio_private *)(dev->subdevices + 2 +
- group)->private)->WRCapSel,
- 0xffff);
- }
+ /* clear all dio pending events and interrupt */
+ for (group = 0; group < S626_DIO_BANKS; group++)
+ DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
return 0;
}
-static irqreturn_t s626_irq_handler(int irq, void *d)
+static void handle_dio_interrupt(struct comedi_device *dev,
+ uint16_t irqbit, uint8_t group)
{
- struct comedi_device *dev = d;
struct s626_private *devpriv = dev->private;
- struct comedi_subdevice *s;
- struct comedi_cmd *cmd;
- struct enc_private *k;
- unsigned long flags;
- int32_t *readaddr;
- uint32_t irqtype, irqstatus;
- int i = 0;
- short tempdata;
- uint8_t group;
- uint16_t irqbit;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
- if (dev->attached == 0)
- return IRQ_NONE;
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&dev->spinlock, flags);
+ s626_dio_reset_irq(dev, group, irqbit);
- /* save interrupt enable register state */
- irqstatus = readl(devpriv->base_addr + P_IER);
+ if (devpriv->ai_cmd_running) {
+ /* check if interrupt is an ai acquisition start trigger */
+ if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 &&
+ cmd->start_src == TRIG_EXT) {
+ /* Start executing the RPS program */
+ s626_mc_enable(dev, MC1_ERPS1, P_MC1);
+
+ if (cmd->scan_begin_src == TRIG_EXT)
+ s626_dio_set_irq(dev, cmd->scan_begin_arg);
+ }
+ if ((irqbit >> (cmd->scan_begin_arg - (16 * group))) == 1 &&
+ cmd->scan_begin_src == TRIG_EXT) {
+ /* Trigger ADC scan loop start */
+ s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
- /* read interrupt type */
- irqtype = readl(devpriv->base_addr + P_ISR);
+ if (cmd->convert_src == TRIG_EXT) {
+ devpriv->ai_convert_count = cmd->chanlist_len;
- /* disable master interrupt */
- writel(0, devpriv->base_addr + P_IER);
+ s626_dio_set_irq(dev, cmd->convert_arg);
+ }
- /* clear interrupt */
- writel(irqtype, devpriv->base_addr + P_ISR);
+ if (cmd->convert_src == TRIG_TIMER) {
+ struct enc_private *k = &encpriv[5];
- switch (irqtype) {
- case IRQ_RPS1: /* end_of_scan occurs */
- /* manage ai subdevice */
- s = dev->subdevices;
- cmd = &(s->async->cmd);
+ devpriv->ai_convert_count = cmd->chanlist_len;
+ k->SetEnable(dev, k, CLKENAB_ALWAYS);
+ }
+ }
+ if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 &&
+ cmd->convert_src == TRIG_EXT) {
+ /* Trigger ADC scan loop start */
+ s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+
+ devpriv->ai_convert_count--;
+ if (devpriv->ai_convert_count > 0)
+ s626_dio_set_irq(dev, cmd->convert_arg);
+ }
+ }
+}
- /* Init ptr to DMA buffer that holds new ADC data. We skip the
- * first uint16_t in the buffer because it contains junk data from
- * the final ADC of the previous poll list scan.
- */
- readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1;
-
- /* get the data and hand it over to comedi */
- for (i = 0; i < (s->async->cmd.chanlist_len); i++) {
- /* Convert ADC data to 16-bit integer values and copy to application */
- /* buffer. */
- tempdata = s626_ai_reg_to_uint((int)*readaddr);
- readaddr++;
-
- /* put data into read buffer */
- /* comedi_buf_put(s->async, tempdata); */
- if (cfc_write_to_buffer(s, tempdata) == 0)
- printk
- ("s626_irq_handler: cfc_write_to_buffer error!\n");
+static void check_dio_interrupts(struct comedi_device *dev)
+{
+ uint16_t irqbit;
+ uint8_t group;
+
+ for (group = 0; group < S626_DIO_BANKS; group++) {
+ irqbit = 0;
+ /* read interrupt type */
+ irqbit = DEBIread(dev, LP_RDCAPFLG(group));
+
+ /* check if interrupt is generated from dio channels */
+ if (irqbit) {
+ handle_dio_interrupt(dev, irqbit, group);
+ return;
}
+ }
+}
- /* end of scan occurs */
- s->async->events |= COMEDI_CB_EOS;
+static void check_counter_interrupts(struct comedi_device *dev)
+{
+ struct s626_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ struct enc_private *k;
+ uint16_t irqbit;
- if (!(devpriv->ai_continous))
- devpriv->ai_sample_count--;
- if (devpriv->ai_sample_count <= 0) {
- devpriv->ai_cmd_running = 0;
+ /* read interrupt type */
+ irqbit = DEBIread(dev, LP_RDMISC2);
- /* Stop RPS program. */
- MC_DISABLE(P_MC1, MC1_ERPS1);
+ /* check interrupt on counters */
+ if (irqbit & IRQ_COINT1A) {
+ k = &encpriv[0];
- /* send end of acquisition */
- s->async->events |= COMEDI_CB_EOA;
+ /* clear interrupt capture flag */
+ k->ResetCapFlags(dev, k);
+ }
+ if (irqbit & IRQ_COINT2A) {
+ k = &encpriv[1];
- /* disable master interrupt */
- irqstatus = 0;
- }
+ /* clear interrupt capture flag */
+ k->ResetCapFlags(dev, k);
+ }
+ if (irqbit & IRQ_COINT3A) {
+ k = &encpriv[2];
- if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT)
- s626_dio_set_irq(dev, cmd->scan_begin_arg);
- /* tell comedi that data is there */
- comedi_event(dev, s);
- break;
- case IRQ_GPIO3: /* check dio and conter interrupt */
- /* manage ai subdevice */
- s = dev->subdevices;
- cmd = &(s->async->cmd);
+ /* clear interrupt capture flag */
+ k->ResetCapFlags(dev, k);
+ }
+ if (irqbit & IRQ_COINT1B) {
+ k = &encpriv[3];
- /* s626_dio_clear_irq(dev); */
+ /* clear interrupt capture flag */
+ k->ResetCapFlags(dev, k);
+ }
+ if (irqbit & IRQ_COINT2B) {
+ k = &encpriv[4];
+
+ /* clear interrupt capture flag */
+ k->ResetCapFlags(dev, k);
+
+ if (devpriv->ai_convert_count > 0) {
+ devpriv->ai_convert_count--;
+ if (devpriv->ai_convert_count == 0)
+ k->SetEnable(dev, k, CLKENAB_INDEX);
- for (group = 0; group < S626_DIO_BANKS; group++) {
- irqbit = 0;
- /* read interrupt type */
- irqbit = DEBIread(dev,
- ((struct dio_private *)(dev->
- subdevices +
- 2 +
- group)->
- private)->RDCapFlg);
-
- /* check if interrupt is generated from dio channels */
- if (irqbit) {
- s626_dio_reset_irq(dev, group, irqbit);
- if (devpriv->ai_cmd_running) {
- /* check if interrupt is an ai acquisition start trigger */
- if ((irqbit >> (cmd->start_arg -
- (16 * group)))
- == 1 && cmd->start_src == TRIG_EXT) {
- /* Start executing the RPS program. */
- MC_ENABLE(P_MC1, MC1_ERPS1);
-
- if (cmd->scan_begin_src ==
- TRIG_EXT) {
- s626_dio_set_irq(dev,
- cmd->scan_begin_arg);
- }
- }
- if ((irqbit >> (cmd->scan_begin_arg -
- (16 * group)))
- == 1
- && cmd->scan_begin_src ==
- TRIG_EXT) {
- /* Trigger ADC scan loop start by setting RPS Signal 0. */
- MC_ENABLE(P_MC2, MC2_ADC_RPS);
-
- if (cmd->convert_src ==
- TRIG_EXT) {
- devpriv->ai_convert_count
- = cmd->chanlist_len;
-
- s626_dio_set_irq(dev,
- cmd->convert_arg);
- }
-
- if (cmd->convert_src ==
- TRIG_TIMER) {
- k = &encpriv[5];
- devpriv->ai_convert_count
- = cmd->chanlist_len;
- k->SetEnable(dev, k,
- CLKENAB_ALWAYS);
- }
- }
- if ((irqbit >> (cmd->convert_arg -
- (16 * group)))
- == 1
- && cmd->convert_src == TRIG_EXT) {
- /* Trigger ADC scan loop start by setting RPS Signal 0. */
- MC_ENABLE(P_MC2, MC2_ADC_RPS);
-
- devpriv->ai_convert_count--;
-
- if (devpriv->ai_convert_count >
- 0) {
- s626_dio_set_irq(dev,
- cmd->convert_arg);
- }
- }
- }
- break;
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Trigger ADC scan loop start */
+ s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
}
}
+ }
+ if (irqbit & IRQ_COINT3B) {
+ k = &encpriv[5];
- /* read interrupt type */
- irqbit = DEBIread(dev, LP_RDMISC2);
-
- /* check interrupt on counters */
- if (irqbit & IRQ_COINT1A) {
- k = &encpriv[0];
+ /* clear interrupt capture flag */
+ k->ResetCapFlags(dev, k);
- /* clear interrupt capture flag */
- k->ResetCapFlags(dev, k);
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Trigger ADC scan loop start */
+ s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
}
- if (irqbit & IRQ_COINT2A) {
- k = &encpriv[1];
- /* clear interrupt capture flag */
- k->ResetCapFlags(dev, k);
+ if (cmd->convert_src == TRIG_TIMER) {
+ k = &encpriv[4];
+ devpriv->ai_convert_count = cmd->chanlist_len;
+ k->SetEnable(dev, k, CLKENAB_ALWAYS);
}
- if (irqbit & IRQ_COINT3A) {
- k = &encpriv[2];
+ }
+}
- /* clear interrupt capture flag */
- k->ResetCapFlags(dev, k);
- }
- if (irqbit & IRQ_COINT1B) {
- k = &encpriv[3];
+static bool handle_eos_interrupt(struct comedi_device *dev)
+{
+ struct s626_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ /*
+ * Init ptr to DMA buffer that holds new ADC data. We skip the
+ * first uint16_t in the buffer because it contains junk data
+ * from the final ADC of the previous poll list scan.
+ */
+ int32_t *readaddr = (int32_t *)devpriv->ANABuf.LogicalBase + 1;
+ bool finished = false;
+ int i;
- /* clear interrupt capture flag */
- k->ResetCapFlags(dev, k);
- }
- if (irqbit & IRQ_COINT2B) {
- k = &encpriv[4];
+ /* get the data and hand it over to comedi */
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ short tempdata;
- /* clear interrupt capture flag */
- k->ResetCapFlags(dev, k);
+ /*
+ * Convert ADC data to 16-bit integer values and copy
+ * to application buffer.
+ */
+ tempdata = s626_ai_reg_to_uint((int)*readaddr);
+ readaddr++;
- if (devpriv->ai_convert_count > 0) {
- devpriv->ai_convert_count--;
- if (devpriv->ai_convert_count == 0)
- k->SetEnable(dev, k, CLKENAB_INDEX);
+ /* put data into read buffer */
+ /* comedi_buf_put(async, tempdata); */
+ cfc_write_to_buffer(s, tempdata);
+ }
- if (cmd->convert_src == TRIG_TIMER) {
- /* Trigger ADC scan loop start by setting RPS Signal 0. */
- MC_ENABLE(P_MC2, MC2_ADC_RPS);
- }
- }
- }
- if (irqbit & IRQ_COINT3B) {
- k = &encpriv[5];
+ /* end of scan occurs */
+ async->events |= COMEDI_CB_EOS;
- /* clear interrupt capture flag */
- k->ResetCapFlags(dev, k);
+ if (!devpriv->ai_continous)
+ devpriv->ai_sample_count--;
+ if (devpriv->ai_sample_count <= 0) {
+ devpriv->ai_cmd_running = 0;
- if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Trigger ADC scan loop start by setting RPS Signal 0. */
- MC_ENABLE(P_MC2, MC2_ADC_RPS);
- }
+ /* Stop RPS program */
+ s626_mc_disable(dev, MC1_ERPS1, P_MC1);
- if (cmd->convert_src == TRIG_TIMER) {
- k = &encpriv[4];
- devpriv->ai_convert_count = cmd->chanlist_len;
- k->SetEnable(dev, k, CLKENAB_ALWAYS);
- }
- }
+ /* send end of acquisition */
+ async->events |= COMEDI_CB_EOA;
+
+ /* disable master interrupt */
+ finished = true;
+ }
+
+ if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT)
+ s626_dio_set_irq(dev, cmd->scan_begin_arg);
+
+ /* tell comedi that data is there */
+ comedi_event(dev, s);
+
+ return finished;
+}
+
+static irqreturn_t s626_irq_handler(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct s626_private *devpriv = dev->private;
+ unsigned long flags;
+ uint32_t irqtype, irqstatus;
+
+ if (!dev->attached)
+ return IRQ_NONE;
+ /* lock to avoid race with comedi_poll */
+ spin_lock_irqsave(&dev->spinlock, flags);
+
+ /* save interrupt enable register state */
+ irqstatus = readl(devpriv->mmio + P_IER);
+
+ /* read interrupt type */
+ irqtype = readl(devpriv->mmio + P_ISR);
+
+ /* disable master interrupt */
+ writel(0, devpriv->mmio + P_IER);
+
+ /* clear interrupt */
+ writel(irqtype, devpriv->mmio + P_ISR);
+
+ switch (irqtype) {
+ case IRQ_RPS1: /* end_of_scan occurs */
+ if (handle_eos_interrupt(dev))
+ irqstatus = 0;
+ break;
+ case IRQ_GPIO3: /* check dio and conter interrupt */
+ /* s626_dio_clear_irq(dev); */
+ check_dio_interrupts(dev);
+ check_counter_interrupts(dev);
+ break;
}
/* enable interrupt */
- writel(irqstatus, devpriv->base_addr + P_IER);
+ writel(irqstatus, devpriv->mmio + P_IER);
spin_unlock_irqrestore(&dev->spinlock, flags);
return IRQ_HANDLED;
@@ -988,14 +929,15 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl)
uint32_t LocalPPL;
struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
- /* Stop RPS program in case it is currently running. */
- MC_DISABLE(P_MC1, MC1_ERPS1);
+ /* Stop RPS program in case it is currently running */
+ s626_mc_disable(dev, MC1_ERPS1, P_MC1);
/* Set starting logical address to write RPS commands. */
pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
- /* Initialize RPS instruction pointer. */
- WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
+ /* Initialize RPS instruction pointer */
+ writel((uint32_t)devpriv->RPSBuf.PhysicalBase,
+ devpriv->mmio + P_RPSADDR1);
/* Construct RPS program in RPSBuf DMA buffer */
@@ -1165,41 +1107,42 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl)
/* End of RPS program build */
}
-/* TO COMPLETE, IF NECESSARY */
-static int s626_ai_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+#ifdef unused_code
+static int s626_ai_rinsn(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ struct s626_private *devpriv = dev->private;
+ register uint8_t i;
+ register int32_t *readaddr;
- return -EINVAL;
-}
-
-/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */
-/* { */
-/* struct s626_private *devpriv = dev->private; */
-/* register uint8_t i; */
-/* register int32_t *readaddr; */
-
-/* Trigger ADC scan loop start by setting RPS Signal 0. */
-/* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
+ /* Trigger ADC scan loop start */
+ s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
-/* Wait until ADC scan loop is finished (RPS Signal 0 reset). */
-/* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */
+ /* Wait until ADC scan loop is finished (RPS Signal 0 reset) */
+ while (s626_mc_test(dev, MC2_ADC_RPS, P_MC2))
+ ;
-/* Init ptr to DMA buffer that holds new ADC data. We skip the
- * first uint16_t in the buffer because it contains junk data from
- * the final ADC of the previous poll list scan.
- */
-/* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */
+ /*
+ * Init ptr to DMA buffer that holds new ADC data. We skip the
+ * first uint16_t in the buffer because it contains junk data from
+ * the final ADC of the previous poll list scan.
+ */
+ readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1;
-/* Convert ADC data to 16-bit integer values and copy to application buffer. */
-/* for ( i = 0; i < devpriv->AdcItems; i++ ) { */
-/* *data = s626_ai_reg_to_uint( *readaddr++ ); */
-/* data++; */
-/* } */
+ /*
+ * Convert ADC data to 16-bit integer values and
+ * copy to application buffer.
+ */
+ for (i = 0; i < devpriv->AdcItems; i++) {
+ *data = s626_ai_reg_to_uint(*readaddr++);
+ data++;
+ }
-/* return i; */
-/* } */
+ return i;
+}
+#endif
static int s626_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -1210,14 +1153,9 @@ static int s626_ai_insn_read(struct comedi_device *dev,
uint16_t range = CR_RANGE(insn->chanspec);
uint16_t AdcSpec = 0;
uint32_t GpioImage;
+ int tmp;
int n;
- /* interrupt call test */
-/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */
- /* Writing a logical 1 into any of the RPS_PSR bits causes the
- * corresponding interrupt to be generated if enabled
- */
-
/* Convert application's ADC specification into form
* appropriate for register programming.
*/
@@ -1237,27 +1175,29 @@ static int s626_ai_insn_read(struct comedi_device *dev,
/* Delay 10 microseconds for analog input settling. */
udelay(10);
- /* Start ADC by pulsing GPIO1 low. */
- GpioImage = RR7146(P_GPIO);
- /* Assert ADC Start command */
- WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- /* and stretch it out. */
- WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- /* Negate ADC Start command. */
- WR7146(P_GPIO, GpioImage | GPIO1_HI);
+ /* Start ADC by pulsing GPIO1 low */
+ GpioImage = readl(devpriv->mmio + P_GPIO);
+ /* Assert ADC Start command */
+ writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+ /* and stretch it out */
+ writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+ writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+ /* Negate ADC Start command */
+ writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO);
/* Wait for ADC to complete (GPIO2 is asserted high when */
/* ADC not busy) and for data from previous conversion to */
/* shift into FB BUFFER 1 register. */
- /* Wait for ADC done. */
- while (!(RR7146(P_PSR) & PSR_GPIO2))
+ /* Wait for ADC done */
+ while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2))
;
- /* Fetch ADC data. */
- if (n != 0)
- data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
+ /* Fetch ADC data */
+ if (n != 0) {
+ tmp = readl(devpriv->mmio + P_FB_BUFFER1);
+ data[n - 1] = s626_ai_reg_to_uint(tmp);
+ }
/* Allow the ADC to stabilize for 4 microseconds before
* starting the next (final) conversion. This delay is
@@ -1272,27 +1212,28 @@ static int s626_ai_insn_read(struct comedi_device *dev,
/* Start a dummy conversion to cause the data from the
* previous conversion to be shifted in. */
- GpioImage = RR7146(P_GPIO);
-
+ GpioImage = readl(devpriv->mmio + P_GPIO);
/* Assert ADC Start command */
- WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- /* and stretch it out. */
- WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- /* Negate ADC Start command. */
- WR7146(P_GPIO, GpioImage | GPIO1_HI);
+ writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+ /* and stretch it out */
+ writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+ writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+ /* Negate ADC Start command */
+ writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO);
/* Wait for the data to arrive in FB BUFFER 1 register. */
- /* Wait for ADC done. */
- while (!(RR7146(P_PSR) & PSR_GPIO2))
+ /* Wait for ADC done */
+ while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2))
;
/* Fetch ADC data from audio interface's input shift register. */
- /* Fetch ADC data. */
- if (n != 0)
- data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
+ /* Fetch ADC data */
+ if (n != 0) {
+ tmp = readl(devpriv->mmio + P_FB_BUFFER1);
+ data[n - 1] = s626_ai_reg_to_uint(tmp);
+ }
return n;
}
@@ -1317,13 +1258,11 @@ static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
static int s626_ai_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s, unsigned int trignum)
{
- struct s626_private *devpriv = dev->private;
-
if (trignum != 0)
return -EINVAL;
- /* Start executing the RPS program. */
- MC_ENABLE(P_MC1, MC1_ERPS1);
+ /* Start executing the RPS program */
+ s626_mc_enable(dev, MC1_ERPS1, P_MC1);
s->async->inttrig = NULL;
@@ -1407,10 +1346,10 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return -EBUSY;
}
/* disable interrupt */
- writel(0, devpriv->base_addr + P_IER);
+ writel(0, devpriv->mmio + P_IER);
/* clear interrupt request */
- writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR);
+ writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->mmio + P_ISR);
/* clear any pending interrupt */
s626_dio_clear_irq(dev);
@@ -1483,7 +1422,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
case TRIG_NONE:
/* continous acquisition */
devpriv->ai_continous = 1;
- devpriv->ai_sample_count = 0;
+ devpriv->ai_sample_count = 1;
break;
}
@@ -1491,11 +1430,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
switch (cmd->start_src) {
case TRIG_NOW:
- /* Trigger ADC scan loop start by setting RPS Signal 0. */
- /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
+ /* Trigger ADC scan loop start */
+ /* s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); */
- /* Start executing the RPS program. */
- MC_ENABLE(P_MC1, MC1_ERPS1);
+ /* Start executing the RPS program */
+ s626_mc_enable(dev, MC1_ERPS1, P_MC1);
s->async->inttrig = NULL;
break;
@@ -1511,7 +1450,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* enable interrupt */
- writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER);
+ writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->mmio + P_IER);
return 0;
}
@@ -1628,11 +1567,11 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct s626_private *devpriv = dev->private;
- /* Stop RPS program in case it is currently running. */
- MC_DISABLE(P_MC1, MC1_ERPS1);
+ /* Stop RPS program in case it is currently running */
+ s626_mc_disable(dev, MC1_ERPS1, P_MC1);
/* disable master interrupt */
- writel(0, devpriv->base_addr + P_IER);
+ writel(0, devpriv->mmio + P_IER);
devpriv->ai_cmd_running = 0;
@@ -1679,84 +1618,74 @@ static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
static void s626_dio_init(struct comedi_device *dev)
{
uint16_t group;
- struct comedi_subdevice *s;
/* Prepare to treat writes to WRCapSel as capture disables. */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
/* For each group of sixteen channels ... */
for (group = 0; group < S626_DIO_BANKS; group++) {
- s = dev->subdevices + 2 + group;
- DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */
- DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */
- /* captures. */
- DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */
- /* default edge */
- /* polarity. */
- DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */
- /* to inactive state. */
+ /* Disable all interrupts */
+ DEBIwrite(dev, LP_WRINTSEL(group), 0);
+ /* Disable all event captures */
+ DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
+ /* Init all DIOs to default edge polarity */
+ DEBIwrite(dev, LP_WREDGSEL(group), 0);
+ /* Program all outputs to inactive state */
+ DEBIwrite(dev, LP_WRDOUT(group), 0);
}
}
-/* DIO devices are slightly special. Although it is possible to
- * implement the insn_read/insn_write interface, it is much more
- * useful to applications if you implement the insn_bits interface.
- * This allows packed reading/writing of the DIO channels. The comedi
- * core can convert between insn_bits and insn_read/write */
-
static int s626_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- /*
- * The insn data consists of a mask in data[0] and the new data in
- * data[1]. The mask defines which bits we are concerning about.
- * The new data must be anded with the mask. Each channel
- * corresponds to a bit.
- */
- if (data[0]) {
- /* Check if requested ports are configured for output */
- if ((s->io_bits & data[0]) != data[0])
- return -EIO;
+ unsigned long group = (unsigned long)s->private;
+ unsigned long mask = data[0];
+ unsigned long bits = data[1];
- s->state &= ~data[0];
- s->state |= data[0] & data[1];
+ if (mask) {
+ /* Check if requested channels are configured for output */
+ if ((s->io_bits & mask) != mask)
+ return -EIO;
- /* Write out the new digital output lines */
+ s->state &= ~mask;
+ s->state |= (bits & mask);
- DEBIwrite(dev, diopriv->WRDOut, s->state);
+ DEBIwrite(dev, LP_WRDOUT(group), s->state);
}
- data[1] = DEBIread(dev, diopriv->RDDIn);
+ data[1] = DEBIread(dev, LP_RDDIN(group));
return insn->n;
}
static int s626_dio_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
+ unsigned long group = (unsigned long)s->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int mask = 1 << chan;
switch (data[0]) {
case INSN_CONFIG_DIO_QUERY:
- data[1] =
- (s->
- io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
- COMEDI_INPUT;
+ data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
return insn->n;
break;
case COMEDI_INPUT:
- s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ s->io_bits &= ~mask;
break;
case COMEDI_OUTPUT:
- s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ s->io_bits |= mask;
break;
default:
return -EINVAL;
break;
}
- DEBIwrite(dev, diopriv->WRDOut, s->io_bits);
+ DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
- return 1;
+ return insn->n;
}
/* Now this function initializes the value of the counter (data[0])
@@ -1861,13 +1790,13 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
{
- DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
+ DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
}
static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
{
- DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
+ DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
}
@@ -2012,8 +1941,7 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
/* While retaining CounterB and LatchSrc configurations, program the */
/* new counter operating mode. */
DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
- DEBIreplace(dev, k->MyCRB,
- (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
+ DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A), crb);
}
static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
@@ -2074,8 +2002,7 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
/* While retaining CounterA and LatchSrc configurations, program the */
/* new counter operating mode. */
- DEBIreplace(dev, k->MyCRA,
- (uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra);
+ DEBIreplace(dev, k->MyCRA, ~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B), cra);
DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
}
@@ -2084,17 +2011,15 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
uint16_t enab)
{
- DEBIreplace(dev, k->MyCRB,
- (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)),
- (uint16_t) (enab << CRBBIT_CLKENAB_A));
+ DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A),
+ enab << CRBBIT_CLKENAB_A);
}
static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
uint16_t enab)
{
- DEBIreplace(dev, k->MyCRB,
- (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
- (uint16_t) (enab << CRBBIT_CLKENAB_B));
+ DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B),
+ enab << CRBBIT_CLKENAB_B);
}
static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
@@ -2123,16 +2048,15 @@ static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
uint16_t Trig)
{
- DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A),
- (uint16_t) (Trig << CRABIT_LOADSRC_A));
+ DEBIreplace(dev, k->MyCRA, ~CRAMSK_LOADSRC_A,
+ Trig << CRABIT_LOADSRC_A);
}
static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
uint16_t Trig)
{
- DEBIreplace(dev, k->MyCRB,
- (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
- (uint16_t) (Trig << CRBBIT_LOADSRC_B));
+ DEBIreplace(dev, k->MyCRB, ~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL),
+ Trig << CRBBIT_LOADSRC_B);
}
static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
@@ -2156,12 +2080,12 @@ static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
struct s626_private *devpriv = dev->private;
/* Reset any pending counter overflow or index captures. */
- DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
+ DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
/* Program counter interrupt source. */
DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
- (uint16_t) (IntSource << CRABIT_INTSRC_A));
+ IntSource << CRABIT_INTSRC_A);
/* Update MISC2 interrupt enable mask. */
devpriv->CounterIntEnabs =
@@ -2430,7 +2354,7 @@ static void s626_initialize(struct comedi_device *dev)
int i;
/* Enable DEBI and audio pins, enable I2C interface */
- MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C);
+ s626_mc_enable(dev, MC1_DEBI | MC1_AUDIO | MC1_I2C, P_MC1);
/*
* Configure DEBI operating mode
@@ -2440,15 +2364,16 @@ static void s626_initialize(struct comedi_device *dev)
* Set up byte lane steering
* Intel-compatible local bus (DEBI never times out)
*/
- WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 |
- (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
- DEBI_SWAP | DEBI_CFG_INTEL);
+ writel(DEBI_CFG_SLAVE16 |
+ (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
+ DEBI_SWAP | DEBI_CFG_INTEL,
+ devpriv->mmio + P_DEBICFG);
/* Disable MMU paging */
- WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE);
+ writel(DEBI_PAGE_DISABLE, devpriv->mmio + P_DEBIPAGE);
/* Init GPIO so that ADC Start* is negated */
- WR7146(P_GPIO, GPIO_BASE | GPIO1_HI);
+ writel(GPIO_BASE | GPIO1_HI, devpriv->mmio + P_GPIO);
/* I2C device address for onboard eeprom (revb) */
devpriv->I2CAdrs = 0xA0;
@@ -2457,9 +2382,9 @@ static void s626_initialize(struct comedi_device *dev)
* Issue an I2C ABORT command to halt any I2C
* operation in progress and reset BUSY flag.
*/
- WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);
- MC_ENABLE(P_MC2, MC2_UPLD_IIC);
- while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0)
+ writel(I2C_CLKSEL | I2C_ABORT, devpriv->mmio + P_I2CSTAT);
+ s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
+ while (!(readl(devpriv->mmio + P_MC2) & MC2_UPLD_IIC))
;
/*
@@ -2467,9 +2392,9 @@ static void s626_initialize(struct comedi_device *dev)
* reg twice to reset all I2C error flags.
*/
for (i = 0; i < 2; i++) {
- WR7146(P_I2CSTAT, I2C_CLKSEL);
- MC_ENABLE(P_MC2, MC2_UPLD_IIC);
- while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+ writel(I2C_CLKSEL, devpriv->mmio + P_I2CSTAT);
+ s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
+ while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2))
;
}
@@ -2479,7 +2404,7 @@ static void s626_initialize(struct comedi_device *dev)
* DAC data setup times are satisfied, enable DAC serial
* clock out.
*/
- WR7146(P_ACON2, ACON2_INIT);
+ writel(ACON2_INIT, devpriv->mmio + P_ACON2);
/*
* Set up TSL1 slot list, which is used to control the
@@ -2487,22 +2412,23 @@ static void s626_initialize(struct comedi_device *dev)
* SIB_A1 = store data uint8_t at next available location
* in FB BUFFER1 register.
*/
- WR7146(P_TSL1, RSD1 | SIB_A1);
- WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);
+ writel(RSD1 | SIB_A1, devpriv->mmio + P_TSL1);
+ writel(RSD1 | SIB_A1 | EOS, devpriv->mmio + P_TSL1 + 4);
/* Enable TSL1 slot list so that it executes all the time */
- WR7146(P_ACON1, ACON1_ADCSTART);
+ writel(ACON1_ADCSTART, devpriv->mmio + P_ACON1);
/*
* Initialize RPS registers used for ADC
*/
/* Physical start of RPS program */
- WR7146(P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase);
+ writel((uint32_t)devpriv->RPSBuf.PhysicalBase,
+ devpriv->mmio + P_RPSADDR1);
/* RPS program performs no explicit mem writes */
- WR7146(P_RPSPAGE1, 0);
+ writel(0, devpriv->mmio + P_RPSPAGE1);
/* Disable RPS timeouts */
- WR7146(P_RPS1_TOUT, 0);
+ writel(0, devpriv->mmio + P_RPS1_TOUT);
#if 0
/*
@@ -2558,7 +2484,7 @@ static void s626_initialize(struct comedi_device *dev)
* burst length = 1 DWORD
* threshold = 1 DWORD.
*/
- WR7146(P_PCI_BT_A, 0);
+ writel(0, devpriv->mmio + P_PCI_BT_A);
/*
* Init Audio2's output DMA physical addresses. The protection
@@ -2568,8 +2494,9 @@ static void s626_initialize(struct comedi_device *dev)
*/
pPhysBuf = devpriv->ANABuf.PhysicalBase +
(DAC_WDMABUF_OS * sizeof(uint32_t));
- WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf);
- WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t)));
+ writel((uint32_t)pPhysBuf, devpriv->mmio + P_BASEA2_OUT);
+ writel((uint32_t)(pPhysBuf + sizeof(uint32_t)),
+ devpriv->mmio + P_PROTA2_OUT);
/*
* Cache Audio2's output DMA buffer logical address. This is
@@ -2584,7 +2511,7 @@ static void s626_initialize(struct comedi_device *dev)
* DMAC will automatically halt and its PCI address pointer
* will be reset when the protection address is reached.
*/
- WR7146(P_PAGEA2_OUT, 8);
+ writel(8, devpriv->mmio + P_PAGEA2_OUT);
/*
* Initialize time slot list 2 (TSL2), which is used to control
@@ -2599,7 +2526,7 @@ static void s626_initialize(struct comedi_device *dev)
*/
/* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */
- SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);
+ writel(XSD2 | RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0));
/*
* Initialize slot 1, which is constant. Slot 1 causes a
@@ -2611,10 +2538,10 @@ static void s626_initialize(struct comedi_device *dev)
*/
/* Slot 1: Fetch DWORD from Audio2's output FIFO */
- SETVECT(1, LF_A2);
+ writel(LF_A2, devpriv->mmio + VECTPORT(1));
/* Start DAC's audio interface (TSL2) running */
- WR7146(P_ACON1, ACON1_DACSTART);
+ writel(ACON1_DACSTART, devpriv->mmio + P_ACON1);
/*
* Init Trim DACs to calibrated values. Do it twice because the
@@ -2653,9 +2580,6 @@ static void s626_initialize(struct comedi_device *dev)
/* Initialize the digital I/O subsystem */
s626_dio_init(dev);
-
- /* enable interrupt test */
- /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */
}
static int s626_auto_attach(struct comedi_device *dev,
@@ -2666,28 +2590,24 @@ static int s626_auto_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
- dev->iobase = 1; /* detach needs this */
- devpriv->base_addr = ioremap(pci_resource_start(pcidev, 0),
- pci_resource_len(pcidev, 0));
- if (!devpriv->base_addr)
+ devpriv->mmio = pci_ioremap_bar(pcidev, 0);
+ if (!devpriv->mmio)
return -ENOMEM;
/* disable master interrupt */
- writel(0, devpriv->base_addr + P_IER);
+ writel(0, devpriv->mmio + P_IER);
/* soft reset */
- writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1);
+ writel(MC1_SOFT_RESET, devpriv->mmio + P_MC1);
/* DMA FIXME DMA// */
@@ -2707,79 +2627,79 @@ static int s626_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- s = dev->subdevices + 0;
+ s = &dev->subdevices[0];
/* analog input subdevice */
- dev->read_subdev = s;
- /* we support single-ended (ground) and differential */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ;
- s->n_chan = S626_ADC_CHANNELS;
- s->maxdata = (0xffff >> 2);
- s->range_table = &s626_range_table;
- s->len_chanlist = S626_ADC_CHANNELS;
- s->insn_config = s626_ai_insn_config;
- s->insn_read = s626_ai_insn_read;
- s->do_cmd = s626_ai_cmd;
- s->do_cmdtest = s626_ai_cmdtest;
- s->cancel = s626_ai_cancel;
-
- s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = S626_ADC_CHANNELS;
+ s->maxdata = 0x3fff;
+ s->range_table = &s626_range_table;
+ s->len_chanlist = S626_ADC_CHANNELS;
+ s->insn_read = s626_ai_insn_read;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->do_cmd = s626_ai_cmd;
+ s->do_cmdtest = s626_ai_cmdtest;
+ s->cancel = s626_ai_cancel;
+ }
+
+ s = &dev->subdevices[1];
/* analog output subdevice */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = S626_DAC_CHANNELS;
- s->maxdata = (0x3fff);
- s->range_table = &range_bipolar10;
- s->insn_write = s626_ao_winsn;
- s->insn_read = s626_ao_rinsn;
-
- s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = S626_DAC_CHANNELS;
+ s->maxdata = 0x3fff;
+ s->range_table = &range_bipolar10;
+ s->insn_write = s626_ao_winsn;
+ s->insn_read = s626_ao_rinsn;
+
+ s = &dev->subdevices[2];
/* digital I/O subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->io_bits = 0xffff;
- s->private = &dio_private_A;
- s->range_table = &range_digital;
- s->insn_config = s626_dio_insn_config;
- s->insn_bits = s626_dio_insn_bits;
-
- s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->io_bits = 0xffff;
+ s->private = (void *)0; /* DIO group 0 */
+ s->range_table = &range_digital;
+ s->insn_config = s626_dio_insn_config;
+ s->insn_bits = s626_dio_insn_bits;
+
+ s = &dev->subdevices[3];
/* digital I/O subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->io_bits = 0xffff;
- s->private = &dio_private_B;
- s->range_table = &range_digital;
- s->insn_config = s626_dio_insn_config;
- s->insn_bits = s626_dio_insn_bits;
-
- s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->io_bits = 0xffff;
+ s->private = (void *)1; /* DIO group 1 */
+ s->range_table = &range_digital;
+ s->insn_config = s626_dio_insn_config;
+ s->insn_bits = s626_dio_insn_bits;
+
+ s = &dev->subdevices[4];
/* digital I/O subdevice */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->n_chan = 16;
- s->maxdata = 1;
- s->io_bits = 0xffff;
- s->private = &dio_private_C;
- s->range_table = &range_digital;
- s->insn_config = s626_dio_insn_config;
- s->insn_bits = s626_dio_insn_bits;
-
- s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->io_bits = 0xffff;
+ s->private = (void *)2; /* DIO group 2 */
+ s->range_table = &range_digital;
+ s->insn_config = s626_dio_insn_config;
+ s->insn_bits = s626_dio_insn_bits;
+
+ s = &dev->subdevices[5];
/* encoder (counter) subdevice */
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
- s->n_chan = S626_ENCODER_CHANNELS;
- s->private = enc_private_data;
- s->insn_config = s626_enc_insn_config;
- s->insn_read = s626_enc_insn_read;
- s->insn_write = s626_enc_insn_write;
- s->maxdata = 0xffffff;
- s->range_table = &range_unknown;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = S626_ENCODER_CHANNELS;
+ s->maxdata = 0xffffff;
+ s->private = enc_private_data;
+ s->range_table = &range_unknown;
+ s->insn_config = s626_enc_insn_config;
+ s->insn_read = s626_enc_insn_read;
+ s->insn_write = s626_enc_insn_write;
s626_initialize(dev);
@@ -2790,24 +2710,26 @@ static int s626_auto_attach(struct comedi_device *dev,
static void s626_detach(struct comedi_device *dev)
{
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct s626_private *devpriv = dev->private;
if (devpriv) {
/* stop ai_command */
devpriv->ai_cmd_running = 0;
- if (devpriv->base_addr) {
+ if (devpriv->mmio) {
/* interrupt mask */
- WR7146(P_IER, 0); /* Disable master interrupt. */
- WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); /* Clear board's IRQ status flag. */
+ /* Disable master interrupt */
+ writel(0, devpriv->mmio + P_IER);
+ /* Clear board's IRQ status flag */
+ writel(IRQ_GPIO3 | IRQ_RPS1,
+ devpriv->mmio + P_ISR);
/* Disable the watchdog timer and battery charger. */
WriteMISC2(dev, 0);
- /* Close all interfaces on 7146 device. */
- WR7146(P_MC1, MC1_SHUTDOWN);
- WR7146(P_ACON1, ACON1_BASE);
+ /* Close all interfaces on 7146 device */
+ writel(MC1_SHUTDOWN, devpriv->mmio + P_MC1);
+ writel(ACON1_BASE, devpriv->mmio + P_ACON1);
CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE);
CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
@@ -2815,13 +2737,10 @@ static void s626_detach(struct comedi_device *dev)
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv->base_addr)
- iounmap(devpriv->base_addr);
- }
- if (pcidev) {
- if (dev->iobase)
- comedi_pci_disable(pcidev);
+ if (devpriv->mmio)
+ iounmap(devpriv->mmio);
}
+ comedi_pci_disable(dev);
}
static struct comedi_driver s626_driver = {
@@ -2832,9 +2751,9 @@ static struct comedi_driver s626_driver = {
};
static int s626_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &s626_driver);
+ return comedi_pci_auto_config(dev, &s626_driver, id->driver_data);
}
/*
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index ff4b3a5e4e5..99cd57b092e 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -267,36 +267,17 @@
#define LP_DACPOL 0x0082 /* Write DAC polarity. */
#define LP_GSEL 0x0084 /* Write ADC gain. */
#define LP_ISEL 0x0086 /* Write ADC channel select. */
-/* Digital I/O (write only): */
-#define LP_WRINTSELA 0x0042 /* Write A interrupt enable. */
-#define LP_WREDGSELA 0x0044 /* Write A edge selection. */
-#define LP_WRCAPSELA 0x0046 /* Write A capture enable. */
-#define LP_WRDOUTA 0x0048 /* Write A digital output. */
-#define LP_WRINTSELB 0x0052 /* Write B interrupt enable. */
-#define LP_WREDGSELB 0x0054 /* Write B edge selection. */
-#define LP_WRCAPSELB 0x0056 /* Write B capture enable. */
-#define LP_WRDOUTB 0x0058 /* Write B digital output. */
-#define LP_WRINTSELC 0x0062 /* Write C interrupt enable. */
-#define LP_WREDGSELC 0x0064 /* Write C edge selection. */
-#define LP_WRCAPSELC 0x0066 /* Write C capture enable. */
-#define LP_WRDOUTC 0x0068 /* Write C digital output. */
-
-/* Digital I/O (read only): */
-#define LP_RDDINA 0x0040 /* Read digital input. */
-#define LP_RDCAPFLGA 0x0048 /* Read edges captured. */
-#define LP_RDINTSELA 0x004A /* Read interrupt enable register. */
-#define LP_RDEDGSELA 0x004C /* Read edge selection register. */
-#define LP_RDCAPSELA 0x004E /* Read capture enable register. */
-#define LP_RDDINB 0x0050 /* Read digital input. */
-#define LP_RDCAPFLGB 0x0058 /* Read edges captured. */
-#define LP_RDINTSELB 0x005A /* Read interrupt enable register. */
-#define LP_RDEDGSELB 0x005C /* Read edge selection register. */
-#define LP_RDCAPSELB 0x005E /* Read capture enable register. */
-#define LP_RDDINC 0x0060 /* Read digital input. */
-#define LP_RDCAPFLGC 0x0068 /* Read edges captured. */
-#define LP_RDINTSELC 0x006A /* Read interrupt enable register. */
-#define LP_RDEDGSELC 0x006C /* Read edge selection register. */
-#define LP_RDCAPSELC 0x006E /* Read capture enable register. */
+
+/* Digital I/O registers */
+#define LP_RDDIN(x) (0x0040 + (x) * 0x10) /* R: digital input */
+#define LP_WRINTSEL(x) (0x0042 + (x) * 0x10) /* W: int enable */
+#define LP_WREDGSEL(x) (0x0044 + (x) * 0x10) /* W: edge selection */
+#define LP_WRCAPSEL(x) (0x0046 + (x) * 0x10) /* W: capture enable */
+#define LP_RDCAPFLG(x) (0x0048 + (x) * 0x10) /* R: edges captured */
+#define LP_WRDOUT(x) (0x0048 + (x) * 0x10) /* W: digital output */
+#define LP_RDINTSEL(x) (0x004a + (x) * 0x10) /* R: int enable */
+#define LP_RDEDGSEL(x) (0x004c + (x) * 0x10) /* R: edge selection */
+#define LP_RDCAPSEL(x) (0x004e + (x) * 0x10) /* R: capture enable */
/* Counter Registers (read/write): */
#define LP_CR0A 0x0000 /* 0A setup register. */
@@ -661,27 +642,27 @@
/* Bit field masks for CRA and CRB. */
-#define CRAMSK_INDXSRC_B ((uint16_t)(3 << CRABIT_INDXSRC_B))
-#define CRAMSK_CLKSRC_B ((uint16_t)(3 << CRABIT_CLKSRC_B))
-#define CRAMSK_INDXPOL_A ((uint16_t)(1 << CRABIT_INDXPOL_A))
-#define CRAMSK_LOADSRC_A ((uint16_t)(3 << CRABIT_LOADSRC_A))
-#define CRAMSK_CLKMULT_A ((uint16_t)(3 << CRABIT_CLKMULT_A))
-#define CRAMSK_INTSRC_A ((uint16_t)(3 << CRABIT_INTSRC_A))
-#define CRAMSK_CLKPOL_A ((uint16_t)(3 << CRABIT_CLKPOL_A))
-#define CRAMSK_INDXSRC_A ((uint16_t)(3 << CRABIT_INDXSRC_A))
-#define CRAMSK_CLKSRC_A ((uint16_t)(3 << CRABIT_CLKSRC_A))
-
-#define CRBMSK_INTRESETCMD ((uint16_t)(1 << CRBBIT_INTRESETCMD))
-#define CRBMSK_INTRESET_B ((uint16_t)(1 << CRBBIT_INTRESET_B))
-#define CRBMSK_INTRESET_A ((uint16_t)(1 << CRBBIT_INTRESET_A))
-#define CRBMSK_CLKENAB_A ((uint16_t)(1 << CRBBIT_CLKENAB_A))
-#define CRBMSK_INTSRC_B ((uint16_t)(3 << CRBBIT_INTSRC_B))
-#define CRBMSK_LATCHSRC ((uint16_t)(3 << CRBBIT_LATCHSRC))
-#define CRBMSK_LOADSRC_B ((uint16_t)(3 << CRBBIT_LOADSRC_B))
-#define CRBMSK_CLKMULT_B ((uint16_t)(3 << CRBBIT_CLKMULT_B))
-#define CRBMSK_CLKENAB_B ((uint16_t)(1 << CRBBIT_CLKENAB_B))
-#define CRBMSK_INDXPOL_B ((uint16_t)(1 << CRBBIT_INDXPOL_B))
-#define CRBMSK_CLKPOL_B ((uint16_t)(1 << CRBBIT_CLKPOL_B))
+#define CRAMSK_INDXSRC_B (3 << CRABIT_INDXSRC_B)
+#define CRAMSK_CLKSRC_B (3 << CRABIT_CLKSRC_B)
+#define CRAMSK_INDXPOL_A (1 << CRABIT_INDXPOL_A)
+#define CRAMSK_LOADSRC_A (3 << CRABIT_LOADSRC_A)
+#define CRAMSK_CLKMULT_A (3 << CRABIT_CLKMULT_A)
+#define CRAMSK_INTSRC_A (3 << CRABIT_INTSRC_A)
+#define CRAMSK_CLKPOL_A (3 << CRABIT_CLKPOL_A)
+#define CRAMSK_INDXSRC_A (3 << CRABIT_INDXSRC_A)
+#define CRAMSK_CLKSRC_A (3 << CRABIT_CLKSRC_A)
+
+#define CRBMSK_INTRESETCMD (1 << CRBBIT_INTRESETCMD)
+#define CRBMSK_INTRESET_B (1 << CRBBIT_INTRESET_B)
+#define CRBMSK_INTRESET_A (1 << CRBBIT_INTRESET_A)
+#define CRBMSK_CLKENAB_A (1 << CRBBIT_CLKENAB_A)
+#define CRBMSK_INTSRC_B (3 << CRBBIT_INTSRC_B)
+#define CRBMSK_LATCHSRC (3 << CRBBIT_LATCHSRC)
+#define CRBMSK_LOADSRC_B (3 << CRBBIT_LOADSRC_B)
+#define CRBMSK_CLKMULT_B (3 << CRBBIT_CLKMULT_B)
+#define CRBMSK_CLKENAB_B (1 << CRBBIT_CLKENAB_B)
+#define CRBMSK_INDXPOL_B (1 << CRBBIT_INDXPOL_B)
+#define CRBMSK_CLKPOL_B (1 << CRBBIT_CLKPOL_B)
#define CRBMSK_INTCTRL (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B) /* Interrupt reset control bits. */
@@ -699,15 +680,15 @@
/* Bit field masks for standardized SETUP structure. */
-#define STDMSK_INTSRC ((uint16_t)(3 << STDBIT_INTSRC))
-#define STDMSK_LATCHSRC ((uint16_t)(3 << STDBIT_LATCHSRC))
-#define STDMSK_LOADSRC ((uint16_t)(3 << STDBIT_LOADSRC))
-#define STDMSK_INDXSRC ((uint16_t)(1 << STDBIT_INDXSRC))
-#define STDMSK_INDXPOL ((uint16_t)(1 << STDBIT_INDXPOL))
-#define STDMSK_CLKSRC ((uint16_t)(3 << STDBIT_CLKSRC))
-#define STDMSK_CLKPOL ((uint16_t)(1 << STDBIT_CLKPOL))
-#define STDMSK_CLKMULT ((uint16_t)(3 << STDBIT_CLKMULT))
-#define STDMSK_CLKENAB ((uint16_t)(1 << STDBIT_CLKENAB))
+#define STDMSK_INTSRC (3 << STDBIT_INTSRC)
+#define STDMSK_LATCHSRC (3 << STDBIT_LATCHSRC)
+#define STDMSK_LOADSRC (3 << STDBIT_LOADSRC)
+#define STDMSK_INDXSRC (1 << STDBIT_INDXSRC)
+#define STDMSK_INDXPOL (1 << STDBIT_INDXPOL)
+#define STDMSK_CLKSRC (3 << STDBIT_CLKSRC)
+#define STDMSK_CLKPOL (1 << STDBIT_CLKPOL)
+#define STDMSK_CLKMULT (3 << STDBIT_CLKMULT)
+#define STDMSK_CLKENAB (1 << STDBIT_CLKENAB)
struct bufferDMA {
dma_addr_t PhysicalBase;
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index e6177b48cca..8900086374d 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -31,8 +31,6 @@ Status: in development
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include "../comedidev.h"
#include <linux/delay.h>
@@ -72,7 +70,40 @@ struct serial_data {
unsigned long value;
};
-static long tty_ioctl(struct file *f, unsigned op, unsigned long param)
+/*
+ * The configuration serial_data.value read from the device is
+ * a bitmask that defines specific options of a channel:
+ *
+ * 4:0 - the channel to configure
+ * 7:5 - the kind of channel
+ * 9:8 - the command used to configure the channel
+ *
+ * The remaining bits vary in use depending on the command:
+ *
+ * BITS 15:10 - the channel bits (maxdata)
+ * MIN/MAX 12:10 - the units multiplier for the scale
+ * 13 - the sign of the scale
+ * 33:14 - the base value for the range
+ */
+#define S2002_CFG_CHAN(x) ((x) & 0x1f)
+#define S2002_CFG_KIND(x) (((x) >> 5) & 0x7)
+#define S2002_CFG_KIND_INVALID 0
+#define S2002_CFG_KIND_DIGITAL_IN 1
+#define S2002_CFG_KIND_DIGITAL_OUT 2
+#define S2002_CFG_KIND_ANALOG_IN 3
+#define S2002_CFG_KIND_ANALOG_OUT 4
+#define S2002_CFG_KIND_ENCODER_IN 5
+#define S2002_CFG_CMD(x) (((x) >> 8) & 0x3)
+#define S2002_CFG_CMD_BITS 0
+#define S2002_CFG_CMD_MIN 1
+#define S2002_CFG_CMD_MAX 2
+#define S2002_CFG_BITS(x) (((x) >> 10) & 0x3f)
+#define S2002_CFG_UNITS(x) (((x) >> 10) & 0x7)
+#define S2002_CFG_SIGN(x) (((x) >> 13) & 0x1)
+#define S2002_CFG_BASE(x) (((x) >> 14) & 0xfffff)
+
+static long serial2002_tty_ioctl(struct file *f, unsigned op,
+ unsigned long param)
{
if (f->f_op->unlocked_ioctl)
return f->f_op->unlocked_ioctl(f, op, param);
@@ -80,39 +111,58 @@ static long tty_ioctl(struct file *f, unsigned op, unsigned long param)
return -ENOSYS;
}
-static int tty_write(struct file *f, unsigned char *buf, int count)
+static int serial2002_tty_write(struct file *f, unsigned char *buf, int count)
{
+ const char __user *p = (__force const char __user *)buf;
int result;
mm_segment_t oldfs;
oldfs = get_fs();
set_fs(KERNEL_DS);
f->f_pos = 0;
- result = f->f_op->write(f, buf, count, &f->f_pos);
+ result = f->f_op->write(f, p, count, &f->f_pos);
set_fs(oldfs);
return result;
}
-#if 0
-/*
- * On 2.6.26.3 this occaisonally gave me page faults, worked around by
- * settings.c_cc[VMIN] = 0; settings.c_cc[VTIME] = 0
- */
-static int tty_available(struct file *f)
+static int serial2002_tty_readb(struct file *f, unsigned char *buf)
{
- long result = 0;
- mm_segment_t oldfs;
+ char __user *p = (__force char __user *)buf;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- tty_ioctl(f, FIONREAD, (unsigned long)&result);
- set_fs(oldfs);
- return result;
+ f->f_pos = 0;
+ return f->f_op->read(f, p, 1, &f->f_pos);
+}
+
+static void serial2002_tty_read_poll_wait(struct file *f, int timeout)
+{
+ struct poll_wqueues table;
+ struct timeval start, now;
+
+ do_gettimeofday(&start);
+ poll_initwait(&table);
+ while (1) {
+ long elapsed;
+ int mask;
+
+ mask = f->f_op->poll(f, &table.pt);
+ if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
+ POLLHUP | POLLERR)) {
+ break;
+ }
+ do_gettimeofday(&now);
+ elapsed = (1000000 * (now.tv_sec - start.tv_sec) +
+ now.tv_usec - start.tv_usec);
+ if (elapsed > timeout)
+ break;
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(((timeout - elapsed) * HZ) / 10000);
+ }
+ poll_freewait(&table);
}
-#endif
-static int tty_read(struct file *f, int timeout)
+static int serial2002_tty_read(struct file *f, int timeout)
{
+ unsigned char ch;
int result;
result = -1;
@@ -122,50 +172,19 @@ static int tty_read(struct file *f, int timeout)
oldfs = get_fs();
set_fs(KERNEL_DS);
if (f->f_op->poll) {
- struct poll_wqueues table;
- struct timeval start, now;
-
- do_gettimeofday(&start);
- poll_initwait(&table);
- while (1) {
- long elapsed;
- int mask;
-
- mask = f->f_op->poll(f, &table.pt);
- if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
- POLLHUP | POLLERR)) {
- break;
- }
- do_gettimeofday(&now);
- elapsed =
- (1000000 * (now.tv_sec - start.tv_sec) +
- now.tv_usec - start.tv_usec);
- if (elapsed > timeout)
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(((timeout -
- elapsed) * HZ) / 10000);
- }
- poll_freewait(&table);
- {
- unsigned char ch;
+ serial2002_tty_read_poll_wait(f, timeout);
- f->f_pos = 0;
- if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1)
- result = ch;
- }
+ if (serial2002_tty_readb(f, &ch) == 1)
+ result = ch;
} else {
/* Device does not support poll, busy wait */
int retries = 0;
while (1) {
- unsigned char ch;
-
retries++;
if (retries >= timeout)
break;
- f->f_pos = 0;
- if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+ if (serial2002_tty_readb(f, &ch) == 1) {
result = ch;
break;
}
@@ -177,90 +196,76 @@ static int tty_read(struct file *f, int timeout)
return result;
}
-static void tty_setspeed(struct file *f, int speed)
+static void serial2002_tty_setspeed(struct file *f, int speed)
{
+ struct termios termios;
+ struct serial_struct serial;
mm_segment_t oldfs;
oldfs = get_fs();
set_fs(KERNEL_DS);
- {
- /* Set speed */
- struct termios settings;
-
- tty_ioctl(f, TCGETS, (unsigned long)&settings);
-/* printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX)); */
- settings.c_iflag = 0;
- settings.c_oflag = 0;
- settings.c_lflag = 0;
- settings.c_cflag = CLOCAL | CS8 | CREAD;
- settings.c_cc[VMIN] = 0;
- settings.c_cc[VTIME] = 0;
- switch (speed) {
- case 2400:{
- settings.c_cflag |= B2400;
- }
- break;
- case 4800:{
- settings.c_cflag |= B4800;
- }
- break;
- case 9600:{
- settings.c_cflag |= B9600;
- }
- break;
- case 19200:{
- settings.c_cflag |= B19200;
- }
- break;
- case 38400:{
- settings.c_cflag |= B38400;
- }
- break;
- case 57600:{
- settings.c_cflag |= B57600;
- }
- break;
- case 115200:{
- settings.c_cflag |= B115200;
- }
- break;
- default:{
- settings.c_cflag |= B9600;
- }
- break;
- }
- tty_ioctl(f, TCSETS, (unsigned long)&settings);
-/* printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX)); */
- }
- {
- /* Set low latency */
- struct serial_struct settings;
- tty_ioctl(f, TIOCGSERIAL, (unsigned long)&settings);
- settings.flags |= ASYNC_LOW_LATENCY;
- tty_ioctl(f, TIOCSSERIAL, (unsigned long)&settings);
+ /* Set speed */
+ serial2002_tty_ioctl(f, TCGETS, (unsigned long)&termios);
+ termios.c_iflag = 0;
+ termios.c_oflag = 0;
+ termios.c_lflag = 0;
+ termios.c_cflag = CLOCAL | CS8 | CREAD;
+ termios.c_cc[VMIN] = 0;
+ termios.c_cc[VTIME] = 0;
+ switch (speed) {
+ case 2400:
+ termios.c_cflag |= B2400;
+ break;
+ case 4800:
+ termios.c_cflag |= B4800;
+ break;
+ case 9600:
+ termios.c_cflag |= B9600;
+ break;
+ case 19200:
+ termios.c_cflag |= B19200;
+ break;
+ case 38400:
+ termios.c_cflag |= B38400;
+ break;
+ case 57600:
+ termios.c_cflag |= B57600;
+ break;
+ case 115200:
+ termios.c_cflag |= B115200;
+ break;
+ default:
+ termios.c_cflag |= B9600;
+ break;
}
+ serial2002_tty_ioctl(f, TCSETS, (unsigned long)&termios);
+
+ /* Set low latency */
+ serial2002_tty_ioctl(f, TIOCGSERIAL, (unsigned long)&serial);
+ serial.flags |= ASYNC_LOW_LATENCY;
+ serial2002_tty_ioctl(f, TIOCSSERIAL, (unsigned long)&serial);
set_fs(oldfs);
}
-static void poll_digital(struct file *f, int channel)
+static void serial2002_poll_digital(struct file *f, int channel)
{
char cmd;
cmd = 0x40 | (channel & 0x1f);
- tty_write(f, &cmd, 1);
+ serial2002_tty_write(f, &cmd, 1);
}
-static void poll_channel(struct file *f, int channel)
+static void serial2002_poll_channel(struct file *f, int channel)
{
char cmd;
cmd = 0x60 | (channel & 0x1f);
- tty_write(f, &cmd, 1);
+ serial2002_tty_write(f, &cmd, 1);
}
-static struct serial_data serial_read(struct file *f, int timeout)
+static struct serial_data serial2002_read(struct file *f, int timeout)
{
struct serial_data result;
int length;
@@ -270,26 +275,23 @@ static struct serial_data serial_read(struct file *f, int timeout)
result.value = 0;
length = 0;
while (1) {
- int data = tty_read(f, timeout);
+ int data = serial2002_tty_read(f, timeout);
length++;
if (data < 0) {
- pr_err("Failed to read serial.\n");
break;
} else if (data & 0x80) {
result.value = (result.value << 7) | (data & 0x7f);
} else {
if (length == 1) {
switch ((data >> 5) & 0x03) {
- case 0:{
- result.value = 0;
- result.kind = is_digital;
- }
+ case 0:
+ result.value = 0;
+ result.kind = is_digital;
break;
- case 1:{
- result.value = 1;
- result.kind = is_digital;
- }
+ case 1:
+ result.value = 1;
+ result.kind = is_digital;
break;
}
} else {
@@ -305,12 +307,12 @@ static struct serial_data serial_read(struct file *f, int timeout)
}
-static void serial_write(struct file *f, struct serial_data data)
+static void serial2002_write(struct file *f, struct serial_data data)
{
if (data.kind == is_digital) {
unsigned char ch =
((data.value << 5) & 0x20) | (data.index & 0x1f);
- tty_write(f, &ch, 1);
+ serial2002_tty_write(f, &ch, 1);
} else {
unsigned char ch[6];
int i = 0;
@@ -334,319 +336,250 @@ static void serial_write(struct file *f, struct serial_data data)
i++;
ch[i] = ((data.value << 5) & 0x60) | (data.index & 0x1f);
i++;
- tty_write(f, ch, i);
+ serial2002_tty_write(f, ch, i);
}
}
-static int serial_2002_open(struct comedi_device *dev)
+struct config_t {
+ short int kind;
+ short int bits;
+ int min;
+ int max;
+};
+
+static int serial2002_setup_subdevice(struct comedi_subdevice *s,
+ struct config_t *cfg,
+ struct serial2002_range_table_t *range,
+ unsigned char *mapping,
+ int kind)
{
- struct serial2002_private *devpriv = dev->private;
- int result;
- char port[20];
+ const struct comedi_lrange **range_table_list = NULL;
+ unsigned int *maxdata_list;
+ int j, chan;
- sprintf(port, "/dev/ttyS%d", devpriv->port);
- devpriv->tty = filp_open(port, O_RDWR, 0);
- if (IS_ERR(devpriv->tty)) {
- result = (int)PTR_ERR(devpriv->tty);
- dev_err(dev->class_dev, "file open error = %d\n", result);
- } else {
- struct config_t {
-
- short int kind;
- short int bits;
- int min;
- int max;
- };
-
- struct config_t *dig_in_config;
- struct config_t *dig_out_config;
- struct config_t *chan_in_config;
- struct config_t *chan_out_config;
- int i;
-
- result = 0;
- dig_in_config = kcalloc(32, sizeof(struct config_t),
- GFP_KERNEL);
- dig_out_config = kcalloc(32, sizeof(struct config_t),
- GFP_KERNEL);
- chan_in_config = kcalloc(32, sizeof(struct config_t),
- GFP_KERNEL);
- chan_out_config = kcalloc(32, sizeof(struct config_t),
- GFP_KERNEL);
- if (!dig_in_config || !dig_out_config
- || !chan_in_config || !chan_out_config) {
- result = -ENOMEM;
- goto err_alloc_configs;
+ for (chan = 0, j = 0; j < 32; j++) {
+ if (cfg[j].kind == kind)
+ chan++;
+ }
+ s->n_chan = chan;
+ s->maxdata = 0;
+ kfree(s->maxdata_list);
+ maxdata_list = kmalloc(sizeof(unsigned int) * s->n_chan, GFP_KERNEL);
+ if (!maxdata_list)
+ return -ENOMEM;
+ s->maxdata_list = maxdata_list;
+ kfree(s->range_table_list);
+ s->range_table = NULL;
+ s->range_table_list = NULL;
+ if (kind == 1 || kind == 2) {
+ s->range_table = &range_digital;
+ } else if (range) {
+ range_table_list =
+ kmalloc(sizeof(struct serial2002_range_table_t) *
+ s->n_chan, GFP_KERNEL);
+ if (!range_table_list)
+ return -ENOMEM;
+ s->range_table_list = range_table_list;
+ }
+ for (chan = 0, j = 0; j < 32; j++) {
+ if (cfg[j].kind == kind) {
+ if (mapping)
+ mapping[chan] = j;
+ if (range) {
+ range[j].length = 1;
+ range[j].range.min = cfg[j].min;
+ range[j].range.max = cfg[j].max;
+ range_table_list[chan] =
+ (const struct comedi_lrange *)&range[j];
+ }
+ maxdata_list[chan] = ((long long)1 << cfg[j].bits) - 1;
+ chan++;
}
+ }
+ return 0;
+}
- tty_setspeed(devpriv->tty, devpriv->speed);
- poll_channel(devpriv->tty, 31); /* Start reading configuration */
- while (1) {
- struct serial_data data;
+static int serial2002_setup_subdevs(struct comedi_device *dev)
+{
+ struct serial2002_private *devpriv = dev->private;
+ struct config_t *di_cfg;
+ struct config_t *do_cfg;
+ struct config_t *ai_cfg;
+ struct config_t *ao_cfg;
+ struct config_t *cfg;
+ struct comedi_subdevice *s;
+ int result = 0;
+ int i;
- data = serial_read(devpriv->tty, 1000);
- if (data.kind != is_channel || data.index != 31
- || !(data.value & 0xe0)) {
- break;
- } else {
- int command, channel, kind;
- struct config_t *cur_config = NULL;
-
- channel = data.value & 0x1f;
- kind = (data.value >> 5) & 0x7;
- command = (data.value >> 8) & 0x3;
- switch (kind) {
- case 1:{
- cur_config = dig_in_config;
- }
- break;
- case 2:{
- cur_config = dig_out_config;
- }
- break;
- case 3:{
- cur_config = chan_in_config;
- }
- break;
- case 4:{
- cur_config = chan_out_config;
- }
- break;
- case 5:{
- cur_config = chan_in_config;
- }
- break;
- }
+ /* Allocate the temporary structs to hold the configuration data */
+ di_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
+ do_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
+ ai_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
+ ao_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
+ if (!di_cfg || !do_cfg || !ai_cfg || !ao_cfg) {
+ result = -ENOMEM;
+ goto err_alloc_configs;
+ }
- if (cur_config) {
- cur_config[channel].kind = kind;
- switch (command) {
- case 0:{
- cur_config[channel].bits
- =
- (data.value >> 10) &
- 0x3f;
- }
- break;
- case 1:{
- int unit, sign, min;
- unit =
- (data.value >> 10) &
- 0x7;
- sign =
- (data.value >> 13) &
- 0x1;
- min =
- (data.value >> 14) &
- 0xfffff;
-
- switch (unit) {
- case 0:{
- min =
- min
- *
- 1000000;
- }
- break;
- case 1:{
- min =
- min
- *
- 1000;
- }
- break;
- case 2:{
- min =
- min
- * 1;
- }
- break;
- }
- if (sign)
- min = -min;
- cur_config[channel].min
- = min;
- }
- break;
- case 2:{
- int unit, sign, max;
- unit =
- (data.value >> 10) &
- 0x7;
- sign =
- (data.value >> 13) &
- 0x1;
- max =
- (data.value >> 14) &
- 0xfffff;
-
- switch (unit) {
- case 0:{
- max =
- max
- *
- 1000000;
- }
- break;
- case 1:{
- max =
- max
- *
- 1000;
- }
- break;
- case 2:{
- max =
- max
- * 1;
- }
- break;
- }
- if (sign)
- max = -max;
- cur_config[channel].max
- = max;
- }
- break;
- }
- }
- }
- }
- for (i = 0; i <= 4; i++) {
- /* Fill in subdev data */
- struct config_t *c;
- unsigned char *mapping = NULL;
- struct serial2002_range_table_t *range = NULL;
- int kind = 0;
-
- switch (i) {
- case 0:{
- c = dig_in_config;
- mapping = devpriv->digital_in_mapping;
- kind = 1;
- }
+ /* Read the configuration from the connected device */
+ serial2002_tty_setspeed(devpriv->tty, devpriv->speed);
+ serial2002_poll_channel(devpriv->tty, 31);
+ while (1) {
+ struct serial_data data;
+
+ data = serial2002_read(devpriv->tty, 1000);
+ if (data.kind != is_channel || data.index != 31 ||
+ S2002_CFG_KIND(data.value) == S2002_CFG_KIND_INVALID) {
+ break;
+ } else {
+ int channel = S2002_CFG_CHAN(data.value);
+ int range = S2002_CFG_BASE(data.value);
+
+ switch (S2002_CFG_KIND(data.value)) {
+ case S2002_CFG_KIND_DIGITAL_IN:
+ cfg = di_cfg;
break;
- case 1:{
- c = dig_out_config;
- mapping = devpriv->digital_out_mapping;
- kind = 2;
- }
+ case S2002_CFG_KIND_DIGITAL_OUT:
+ cfg = do_cfg;
break;
- case 2:{
- c = chan_in_config;
- mapping = devpriv->analog_in_mapping;
- range = devpriv->in_range;
- kind = 3;
- }
+ case S2002_CFG_KIND_ANALOG_IN:
+ cfg = ai_cfg;
break;
- case 3:{
- c = chan_out_config;
- mapping = devpriv->analog_out_mapping;
- range = devpriv->out_range;
- kind = 4;
- }
+ case S2002_CFG_KIND_ANALOG_OUT:
+ cfg = ao_cfg;
break;
- case 4:{
- c = chan_in_config;
- mapping = devpriv->encoder_in_mapping;
- range = devpriv->in_range;
- kind = 5;
- }
+ case S2002_CFG_KIND_ENCODER_IN:
+ cfg = ai_cfg;
break;
- default:{
- c = NULL;
- }
+ default:
+ cfg = NULL;
break;
}
- if (c) {
- struct comedi_subdevice *s;
- const struct comedi_lrange **range_table_list =
- NULL;
- unsigned int *maxdata_list;
- int j, chan;
-
- for (chan = 0, j = 0; j < 32; j++) {
- if (c[j].kind == kind)
- chan++;
- }
- s = &dev->subdevices[i];
- s->n_chan = chan;
- s->maxdata = 0;
- kfree(s->maxdata_list);
- s->maxdata_list = maxdata_list =
- kmalloc(sizeof(unsigned int) * s->n_chan,
- GFP_KERNEL);
- if (!s->maxdata_list)
- break; /* error handled below */
- kfree(s->range_table_list);
- s->range_table = NULL;
- s->range_table_list = NULL;
- if (kind == 1 || kind == 2) {
- s->range_table = &range_digital;
- } else if (range) {
- s->range_table_list = range_table_list =
- kmalloc(sizeof
- (struct
- serial2002_range_table_t) *
- s->n_chan, GFP_KERNEL);
- if (!s->range_table_list)
- break; /* err handled below */
- }
- for (chan = 0, j = 0; j < 32; j++) {
- if (c[j].kind == kind) {
- if (mapping)
- mapping[chan] = j;
- if (range) {
- range[j].length = 1;
- range[j].range.min =
- c[j].min;
- range[j].range.max =
- c[j].max;
- range_table_list[chan] =
- (const struct
- comedi_lrange *)
- &range[j];
- }
- maxdata_list[chan] =
- ((long long)1 << c[j].bits)
- - 1;
- chan++;
- }
+ if (!cfg)
+ continue; /* unknown kind, skip it */
+
+ cfg[channel].kind = S2002_CFG_KIND(data.value);
+
+ switch (S2002_CFG_CMD(data.value)) {
+ case S2002_CFG_CMD_BITS:
+ cfg[channel].bits = S2002_CFG_BITS(data.value);
+ break;
+ case S2002_CFG_CMD_MIN:
+ case S2002_CFG_CMD_MAX:
+ switch (S2002_CFG_UNITS(data.value)) {
+ case 0:
+ range *= 1000000;
+ break;
+ case 1:
+ range *= 1000;
+ break;
+ case 2:
+ range *= 1;
+ break;
}
+ if (S2002_CFG_SIGN(data.value))
+ range = -range;
+ if (S2002_CFG_CMD(data.value) ==
+ S2002_CFG_CMD_MIN)
+ cfg[channel].min = range;
+ else
+ cfg[channel].max = range;
+ break;
}
}
- if (i <= 4) {
- /* Failed to allocate maxdata_list or range_table_list
- * for a subdevice that needed it. */
- result = -ENOMEM;
- for (i = 0; i <= 4; i++) {
- struct comedi_subdevice *s;
-
- s = &dev->subdevices[i];
- kfree(s->maxdata_list);
- s->maxdata_list = NULL;
- kfree(s->range_table_list);
- s->range_table_list = NULL;
- }
+ }
+
+ /* Fill in subdevice data */
+ for (i = 0; i <= 4; i++) {
+ unsigned char *mapping = NULL;
+ struct serial2002_range_table_t *range = NULL;
+ int kind = 0;
+
+ s = &dev->subdevices[i];
+
+ switch (i) {
+ case 0:
+ cfg = di_cfg;
+ mapping = devpriv->digital_in_mapping;
+ kind = S2002_CFG_KIND_DIGITAL_IN;
+ break;
+ case 1:
+ cfg = do_cfg;
+ mapping = devpriv->digital_out_mapping;
+ kind = S2002_CFG_KIND_DIGITAL_OUT;
+ break;
+ case 2:
+ cfg = ai_cfg;
+ mapping = devpriv->analog_in_mapping;
+ range = devpriv->in_range;
+ kind = S2002_CFG_KIND_ANALOG_IN;
+ break;
+ case 3:
+ cfg = ao_cfg;
+ mapping = devpriv->analog_out_mapping;
+ range = devpriv->out_range;
+ kind = S2002_CFG_KIND_ANALOG_OUT;
+ break;
+ case 4:
+ cfg = ai_cfg;
+ mapping = devpriv->encoder_in_mapping;
+ range = devpriv->in_range;
+ kind = S2002_CFG_KIND_ENCODER_IN;
+ break;
}
+ if (serial2002_setup_subdevice(s, cfg, range, mapping, kind))
+ break; /* err handled below */
+ }
+ if (i <= 4) {
+ /*
+ * Failed to allocate maxdata_list or range_table_list
+ * for a subdevice that needed it.
+ */
+ result = -ENOMEM;
+ for (i = 0; i <= 4; i++) {
+ s = &dev->subdevices[i];
+ kfree(s->maxdata_list);
+ s->maxdata_list = NULL;
+ kfree(s->range_table_list);
+ s->range_table_list = NULL;
+ }
+ }
+
err_alloc_configs:
- kfree(dig_in_config);
- kfree(dig_out_config);
- kfree(chan_in_config);
- kfree(chan_out_config);
-
- if (result) {
- if (devpriv->tty) {
- filp_close(devpriv->tty, NULL);
- devpriv->tty = NULL;
- }
+ kfree(di_cfg);
+ kfree(do_cfg);
+ kfree(ai_cfg);
+ kfree(ao_cfg);
+
+ if (result) {
+ if (devpriv->tty) {
+ filp_close(devpriv->tty, NULL);
+ devpriv->tty = NULL;
}
}
+
+ return result;
+}
+
+static int serial2002_open(struct comedi_device *dev)
+{
+ struct serial2002_private *devpriv = dev->private;
+ int result;
+ char port[20];
+
+ sprintf(port, "/dev/ttyS%d", devpriv->port);
+ devpriv->tty = filp_open(port, O_RDWR, 0);
+ if (IS_ERR(devpriv->tty)) {
+ result = (int)PTR_ERR(devpriv->tty);
+ dev_err(dev->class_dev, "file open error = %d\n", result);
+ } else {
+ result = serial2002_setup_subdevs(dev);
+ }
return result;
}
-static void serial_2002_close(struct comedi_device *dev)
+static void serial2002_close(struct comedi_device *dev)
{
struct serial2002_private *devpriv = dev->private;
@@ -654,9 +587,10 @@ static void serial_2002_close(struct comedi_device *dev)
filp_close(devpriv->tty, NULL);
}
-static int serial2002_di_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int serial2002_di_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct serial2002_private *devpriv = dev->private;
int n;
@@ -666,9 +600,9 @@ static int serial2002_di_rinsn(struct comedi_device *dev,
for (n = 0; n < insn->n; n++) {
struct serial_data read;
- poll_digital(devpriv->tty, chan);
+ serial2002_poll_digital(devpriv->tty, chan);
while (1) {
- read = serial_read(devpriv->tty, 1000);
+ read = serial2002_read(devpriv->tty, 1000);
if (read.kind != is_digital || read.index == chan)
break;
}
@@ -677,9 +611,10 @@ static int serial2002_di_rinsn(struct comedi_device *dev,
return n;
}
-static int serial2002_do_winsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int serial2002_do_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct serial2002_private *devpriv = dev->private;
int n;
@@ -692,14 +627,15 @@ static int serial2002_do_winsn(struct comedi_device *dev,
write.kind = is_digital;
write.index = chan;
write.value = data[n];
- serial_write(devpriv->tty, write);
+ serial2002_write(devpriv->tty, write);
}
return n;
}
-static int serial2002_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int serial2002_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct serial2002_private *devpriv = dev->private;
int n;
@@ -709,9 +645,9 @@ static int serial2002_ai_rinsn(struct comedi_device *dev,
for (n = 0; n < insn->n; n++) {
struct serial_data read;
- poll_channel(devpriv->tty, chan);
+ serial2002_poll_channel(devpriv->tty, chan);
while (1) {
- read = serial_read(devpriv->tty, 1000);
+ read = serial2002_read(devpriv->tty, 1000);
if (read.kind != is_channel || read.index == chan)
break;
}
@@ -720,9 +656,10 @@ static int serial2002_ai_rinsn(struct comedi_device *dev,
return n;
}
-static int serial2002_ao_winsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int serial2002_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct serial2002_private *devpriv = dev->private;
int n;
@@ -735,15 +672,16 @@ static int serial2002_ao_winsn(struct comedi_device *dev,
write.kind = is_channel;
write.index = chan;
write.value = data[n];
- serial_write(devpriv->tty, write);
+ serial2002_write(devpriv->tty, write);
devpriv->ao_readback[chan] = data[n];
}
return n;
}
-static int serial2002_ao_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int serial2002_ao_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct serial2002_private *devpriv = dev->private;
int n;
@@ -755,9 +693,10 @@ static int serial2002_ao_rinsn(struct comedi_device *dev,
return n;
}
-static int serial2002_ei_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int serial2002_encoder_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct serial2002_private *devpriv = dev->private;
int n;
@@ -767,9 +706,9 @@ static int serial2002_ei_rinsn(struct comedi_device *dev,
for (n = 0; n < insn->n; n++) {
struct serial_data read;
- poll_channel(devpriv->tty, chan);
+ serial2002_poll_channel(devpriv->tty, chan);
while (1) {
- read = serial_read(devpriv->tty, 1000);
+ read = serial2002_read(devpriv->tty, 1000);
if (read.kind != is_channel || read.index == chan)
break;
}
@@ -785,20 +724,13 @@ static int serial2002_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- dev_dbg(dev->class_dev, "serial2002: attach\n");
- dev->board_name = dev->driver->driver_name;
-
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
- dev->open = serial_2002_open;
- dev->close = serial_2002_close;
devpriv->port = it->options[0];
devpriv->speed = it->options[1];
- dev_dbg(dev->class_dev, "/dev/ttyS%d @ %d\n", devpriv->port,
- devpriv->speed);
ret = comedi_alloc_subdevices(dev, 5);
if (ret)
@@ -806,51 +738,54 @@ static int serial2002_attach(struct comedi_device *dev,
/* digital input subdevice */
s = &dev->subdevices[0];
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 0;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_read = &serial2002_di_rinsn;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_read = serial2002_di_insn_read;
/* digital output subdevice */
s = &dev->subdevices[1];
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITEABLE;
- s->n_chan = 0;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_write = &serial2002_do_winsn;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_write = serial2002_do_insn_write;
/* analog input subdevice */
s = &dev->subdevices[2];
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 0;
- s->maxdata = 1;
- s->range_table = NULL;
- s->insn_read = &serial2002_ai_rinsn;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = NULL;
+ s->insn_read = serial2002_ai_insn_read;
/* analog output subdevice */
s = &dev->subdevices[3];
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITEABLE;
- s->n_chan = 0;
- s->maxdata = 1;
- s->range_table = NULL;
- s->insn_write = &serial2002_ao_winsn;
- s->insn_read = &serial2002_ao_rinsn;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = NULL;
+ s->insn_write = serial2002_ao_insn_write;
+ s->insn_read = serial2002_ao_insn_read;
/* encoder input subdevice */
s = &dev->subdevices[4];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
- s->n_chan = 0;
- s->maxdata = 1;
- s->range_table = NULL;
- s->insn_read = &serial2002_ei_rinsn;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = NULL;
+ s->insn_read = serial2002_encoder_insn_read;
+
+ dev->open = serial2002_open;
+ dev->close = serial2002_close;
- return 1;
+ return 0;
}
static void serial2002_detach(struct comedi_device *dev)
@@ -858,7 +793,7 @@ static void serial2002_detach(struct comedi_device *dev)
struct comedi_subdevice *s;
int i;
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < dev->n_subdevices; i++) {
s = &dev->subdevices[i];
kfree(s->maxdata_list);
kfree(s->range_table_list);
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index cb83f6ae48b..dbc8c54d6da 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -90,29 +90,30 @@ Configuration Options:
* boards in this way is optional, and completely driver-dependent.
* Some drivers use arrays such as this, other do not.
*/
+enum skel_boardid {
+ BOARD_SKEL100,
+ BOARD_SKEL200,
+};
+
struct skel_board {
const char *name;
- unsigned int devid;
int ai_chans;
int ai_bits;
int have_dio;
};
static const struct skel_board skel_boards[] = {
- {
- .name = "skel-100",
- .devid = 0x100,
- .ai_chans = 16,
- .ai_bits = 12,
- .have_dio = 1,
- },
- {
- .name = "skel-200",
- .devid = 0x200,
- .ai_chans = 8,
- .ai_bits = 16,
- .have_dio = 0,
- },
+ [BOARD_SKEL100] = {
+ .name = "skel-100",
+ .ai_chans = 16,
+ .ai_bits = 12,
+ .have_dio = 1,
+ },
+ [BOARD_SKEL200] = {
+ .name = "skel-200",
+ .ai_chans = 8,
+ .ai_bits = 16,
+ },
};
/* this structure is for data unique to this hardware driver. If
@@ -394,22 +395,6 @@ static int skel_dio_insn_config(struct comedi_device *dev,
return insn->n;
}
-static const struct skel_board *skel_find_pci_board(struct pci_dev *pcidev)
-{
- unsigned int i;
-
-/*
- * This example code assumes all the entries in skel_boards[] are PCI boards
- * and all use the same PCI vendor ID. If skel_boards[] contains a mixture
- * of PCI and non-PCI boards, this loop should skip over the non-PCI boards.
- */
- for (i = 0; i < ARRAY_SIZE(skel_boards); i++)
- if (/* skel_boards[i].bustype == pci_bustype && */
- pcidev->device == skel_boards[i].devid)
- return &skel_boards[i];
- return NULL;
-}
-
/*
* Handle common part of skel_attach() and skel_auto_attach().
*/
@@ -496,10 +481,12 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it)
thisboard = comedi_board(dev);
-/*
- * Initialize dev->board_name.
- */
- dev->board_name = thisboard->name;
+ /*
+ * The dev->board_name is initialized by the comedi core before
+ * calling the (*attach) function. It can be optionally set by
+ * the driver if additional probing has been done.
+ */
+ /* dev->board_name = thisboard->name; */
/* Allocate the private data */
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
@@ -541,16 +528,13 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it)
* comedi_usb_auto_config(), etc.) to handle devices that can be attached
* to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl.
*
- * The context parameter is usually unused, but if the driver called
- * comedi_auto_config() directly instead of the comedi_pci_auto_config()
- * wrapper function, this will be a copy of the context passed to
- * comedi_auto_config().
+ * The context parameter is driver dependent.
*/
static int skel_auto_attach(struct comedi_device *dev,
- unsigned long context)
+ unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct skel_board *thisboard;
+ const struct skel_board *thisboard = NULL;
struct skel_private *devpriv;
int ret;
@@ -558,12 +542,18 @@ static int skel_auto_attach(struct comedi_device *dev,
if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS))
return -EINVAL;
- /* Find a matching board in skel_boards[]. */
- thisboard = skel_find_pci_board(pcidev);
- if (!thisboard) {
- dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
- return -EINVAL;
- }
+ /*
+ * In this example, the _auto_attach is for a PCI device.
+ *
+ * The 'context' passed to this function is the id->driver_data
+ * associated with the PCI device found in the id_table during
+ * the modprobe. This 'context' is the index of the entry in
+ * skel_boards[i] that contains the boardinfo for the PCI device.
+ */
+ if (context < ARRAY_SIZE(skel_boards))
+ thisboard = &skel_boards[context];
+ if (!thisboard)
+ return -ENODEV;
/*
* Point the struct comedi_device to the matching board info
@@ -579,7 +569,7 @@ static int skel_auto_attach(struct comedi_device *dev,
dev->private = devpriv;
/* Enable the PCI device. */
- ret = comedi_pci_enable(pcidev, dev->board_name);
+ ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -618,7 +608,6 @@ static void skel_detach(struct comedi_device *dev)
{
const struct skel_board *thisboard = comedi_board(dev);
struct skel_private *devpriv = dev->private;
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
if (!thisboard || !devpriv)
return;
@@ -638,17 +627,17 @@ static void skel_detach(struct comedi_device *dev)
* If PCI device enabled by _auto_attach() (or _attach()),
* disable it here.
*/
- if (pcidev && dev->iobase)
- comedi_pci_disable(pcidev);
+ comedi_pci_disable(dev);
} else {
/*
* ISA board
*
- * If I/O regions successfully requested by _attach(),
- * release them here.
+ * Release the first I/O region requested during the
+ * _attach(). This is safe to call even if the request
+ * failed. If any additional I/O regions are requested
+ * they need to be released by the driver.
*/
- if (dev->iobase)
- release_region(dev->iobase, SKEL_SIZE);
+ comedi_legacy_detach(dev);
}
}
@@ -689,28 +678,33 @@ static struct comedi_driver skel_driver = {
#ifdef CONFIG_COMEDI_PCI_DRIVERS
-/* This is used by modprobe to translate PCI IDs to drivers. Should
- * only be used for PCI and ISA-PnP devices */
-/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
- * upstream. */
-#define PCI_VENDOR_ID_SKEL 0xdafe
+static int skel_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &skel_driver, id->driver_data);
+}
+
+/*
+ * Please add your PCI vendor ID to comedidev.h, and it will
+ * be forwarded upstream.
+ */
+#define PCI_VENDOR_ID_SKEL 0xdafe
+
+/*
+ * This is used by modprobe to translate PCI IDs to drivers.
+ * Should only be used for PCI and ISA-PnP devices
+ */
static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
- { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) },
- { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) },
+ { PCI_VDEVICE(SKEL, 0x0100), BOARD_SKEL100 },
+ { PCI_VDEVICE(SKEL, 0x0200), BOARD_SKEL200 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, skel_pci_table);
-static int skel_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *ent)
-{
- return comedi_pci_auto_config(dev, &skel_driver);
-}
-
static struct pci_driver skel_pci_driver = {
- .name = "dummy",
- .id_table = skel_pci_table,
- .probe = &skel_pci_probe,
+ .name = "dummy",
+ .id_table = skel_pci_table,
+ .probe = skel_pci_probe,
.remove = comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(skel_driver, skel_pci_driver);
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
index afa4016f906..a76df092a57 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -167,8 +167,6 @@ static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
index 74b974bf103..0c243477cbe 100644
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -367,24 +367,24 @@ static int unioxx5_insn_config(struct comedi_device *dev,
}
/* initializing subdevice with given address */
-static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
- int subdev_iobase, int minor)
+static int __unioxx5_subdev_init(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ int iobase)
{
struct unioxx5_subd_priv *usp;
int i, to, ndef_flag = 0;
-
- if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) {
- dev_err(subdev->class_dev,
- "comedi%d: I/O port conflict\n", minor);
- return -EIO;
- }
+ int ret;
usp = kzalloc(sizeof(*usp), GFP_KERNEL);
if (usp == NULL)
- return -1;
+ return -ENOMEM;
- usp->usp_iobase = subdev_iobase;
- dev_info(subdev->class_dev, "comedi%d: |", minor);
+ ret = __comedi_request_region(dev, iobase, UNIOXX5_SIZE);
+ if (ret) {
+ kfree(usp);
+ return ret;
+ }
+ usp->usp_iobase = iobase;
/* defining modules types */
for (i = 0; i < 12; i++) {
@@ -392,14 +392,14 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
__unioxx5_analog_config(usp, i * 2);
/* sends channel number to card */
- outb(i + 1, subdev_iobase + 5);
- outb('H', subdev_iobase + 6); /* requests EEPROM world */
- while (!(inb(subdev_iobase + 0) & TxBE))
+ outb(i + 1, iobase + 5);
+ outb('H', iobase + 6); /* requests EEPROM world */
+ while (!(inb(iobase + 0) & TxBE))
; /* waits while writting will be allowed */
- outb(0, subdev_iobase + 6);
+ outb(0, iobase + 6);
/* waits while reading of two bytes will be allowed */
- while (!(inb(subdev_iobase + 0) & Rx2CA)) {
+ while (!(inb(iobase + 0) & Rx2CA)) {
if (--to <= 0) {
ndef_flag = 1;
break;
@@ -410,25 +410,22 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
usp->usp_module_type[i] = 0;
ndef_flag = 0;
} else
- usp->usp_module_type[i] = inb(subdev_iobase + 6);
+ usp->usp_module_type[i] = inb(iobase + 6);
- printk(" [%d] 0x%02x |", i, usp->usp_module_type[i]);
udelay(1);
}
- printk("\n");
-
/* initial subdevice for digital or analog i/o */
- subdev->type = COMEDI_SUBD_DIO;
- subdev->private = usp;
- subdev->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- subdev->n_chan = UNIOXX5_NUM_OF_CHANS;
- subdev->maxdata = 0xFFF;
- subdev->range_table = &range_digital;
- subdev->insn_read = unioxx5_subdev_read;
- subdev->insn_write = unioxx5_subdev_write;
+ s->type = COMEDI_SUBD_DIO;
+ s->private = usp;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = UNIOXX5_NUM_OF_CHANS;
+ s->maxdata = 0xFFF;
+ s->range_table = &range_digital;
+ s->insn_read = unioxx5_subdev_read;
+ s->insn_write = unioxx5_subdev_write;
/* for digital modules only!!! */
- subdev->insn_config = unioxx5_insn_config;
+ s->insn_config = unioxx5_insn_config;
return 0;
}
@@ -436,13 +433,13 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev,
static int unioxx5_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
+ struct comedi_subdevice *s;
int iobase, i, n_subd;
int id, num, ba;
int ret;
iobase = it->options[0];
- dev->board_name = DRIVER_NAME;
dev->iobase = iobase;
iobase += UNIOXX5_SUBDEV_BASE;
@@ -470,9 +467,10 @@ static int unioxx5_attach(struct comedi_device *dev,
/* initializing each of for same subdevices */
for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) {
- if (__unioxx5_subdev_init(&dev->subdevices[i], iobase,
- dev->minor) < 0)
- return -1;
+ s = &dev->subdevices[i];
+ ret = __unioxx5_subdev_init(dev, s, iobase);
+ if (ret)
+ return ret;
}
return 0;
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 1a0062a0445..6f5da67e26c 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -56,7 +56,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
* functions firmware upload is by fxload and no longer by comedi (due to
* enumeration)
* 0.97: USB IDs received, adjusted table
- * 0.98: SMP, locking, memroy alloc: moved all usb memory alloc
+ * 0.98: SMP, locking, memory alloc: moved all usb memory alloc
* to the usb subsystem and moved all comedi related memory
* alloc to comedi.
* | kernel | registration | usbdux-usb | usbdux-comedi | comedi |
@@ -250,26 +250,26 @@ struct usbduxsub {
/* pointer to the usb-device */
struct usb_device *usbdev;
/* actual number of in-buffers */
- int numOfInBuffers;
+ int num_in_buffers;
/* actual number of out-buffers */
- int numOfOutBuffers;
+ int num_out_buffers;
/* ISO-transfer handling: buffers */
- struct urb **urbIn;
- struct urb **urbOut;
+ struct urb **urb_in;
+ struct urb **urb_out;
/* pwm-transfer handling */
- struct urb *urbPwm;
+ struct urb *urb_pwm;
/* PWM period */
- unsigned int pwmPeriod;
+ unsigned int pwm_period;
/* PWM internal delay for the GPIF in the FX2 */
- int8_t pwmDelay;
+ int8_t pwn_delay;
/* size of the PWM buffer which holds the bit pattern */
- int sizePwmBuf;
+ int size_pwm_buf;
/* input buffer for the ISO-transfer */
- int16_t *inBuffer;
+ int16_t *in_buffer;
/* input buffer for single insn */
- int16_t *insnBuffer;
+ int16_t *insn_buffer;
/* output buffer for single DA outputs */
- int16_t *outBuffer;
+ int16_t *out_buffer;
/* interface number */
int ifnum;
/* interface structure in 2.6 */
@@ -319,17 +319,17 @@ static DEFINE_SEMAPHORE(start_stop_sem);
* Stops the data acquision
* It should be safe to call this function from any context
*/
-static int usbduxsub_unlink_InURBs(struct usbduxsub *usbduxsub_tmp)
+static int usbduxsub_unlink_inurbs(struct usbduxsub *usbduxsub_tmp)
{
int i = 0;
int err = 0;
- if (usbduxsub_tmp && usbduxsub_tmp->urbIn) {
- for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
- if (usbduxsub_tmp->urbIn[i]) {
+ if (usbduxsub_tmp && usbduxsub_tmp->urb_in) {
+ for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) {
+ if (usbduxsub_tmp->urb_in[i]) {
/* We wait here until all transfers have been
* cancelled. */
- usb_kill_urb(usbduxsub_tmp->urbIn[i]);
+ usb_kill_urb(usbduxsub_tmp->urb_in[i]);
}
dev_dbg(&usbduxsub_tmp->interface->dev,
"comedi: usbdux: unlinked InURB %d, err=%d\n",
@@ -356,7 +356,7 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
if (do_unlink) {
/* stop aquistion */
- ret = usbduxsub_unlink_InURBs(this_usbduxsub);
+ ret = usbduxsub_unlink_inurbs(this_usbduxsub);
}
this_usbduxsub->ai_cmd_running = 0;
@@ -394,7 +394,7 @@ static int usbdux_ai_cancel(struct comedi_device *dev,
}
/* analogue IN - interrupt service routine */
-static void usbduxsub_ai_IsocIrq(struct urb *urb)
+static void usbduxsub_ai_isoc_irq(struct urb *urb)
{
int i, err, n;
struct usbduxsub *this_usbduxsub;
@@ -412,7 +412,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
switch (urb->status) {
case 0:
/* copy the result in the transfer buffer */
- memcpy(this_usbduxsub->inBuffer,
+ memcpy(this_usbduxsub->in_buffer,
urb->transfer_buffer, SIZEINBUF);
break;
case -EILSEQ:
@@ -517,11 +517,11 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
err = comedi_buf_put
(s->async,
- le16_to_cpu(this_usbduxsub->inBuffer[i]) ^ 0x800);
+ le16_to_cpu(this_usbduxsub->in_buffer[i]) ^ 0x800);
} else {
err = comedi_buf_put
(s->async,
- le16_to_cpu(this_usbduxsub->inBuffer[i]));
+ le16_to_cpu(this_usbduxsub->in_buffer[i]));
}
if (unlikely(err == 0)) {
/* buffer overflow */
@@ -534,15 +534,15 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
comedi_event(this_usbduxsub->comedidev, s);
}
-static int usbduxsub_unlink_OutURBs(struct usbduxsub *usbduxsub_tmp)
+static int usbduxsub_unlink_outurbs(struct usbduxsub *usbduxsub_tmp)
{
int i = 0;
int err = 0;
- if (usbduxsub_tmp && usbduxsub_tmp->urbOut) {
- for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
- if (usbduxsub_tmp->urbOut[i])
- usb_kill_urb(usbduxsub_tmp->urbOut[i]);
+ if (usbduxsub_tmp && usbduxsub_tmp->urb_out) {
+ for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) {
+ if (usbduxsub_tmp->urb_out[i])
+ usb_kill_urb(usbduxsub_tmp->urb_out[i]);
dev_dbg(&usbduxsub_tmp->interface->dev,
"comedi: usbdux: unlinked OutURB %d: res=%d\n",
@@ -564,7 +564,7 @@ static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n");
if (do_unlink)
- ret = usbduxsub_unlink_OutURBs(this_usbduxsub);
+ ret = usbduxsub_unlink_outurbs(this_usbduxsub);
this_usbduxsub->ao_cmd_running = 0;
@@ -593,7 +593,7 @@ static int usbdux_ao_cancel(struct comedi_device *dev,
return res;
}
-static void usbduxsub_ao_IsocIrq(struct urb *urb)
+static void usbduxsub_ao_isoc_irq(struct urb *urb)
{
int i, ret;
int8_t *datap;
@@ -730,10 +730,14 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
static int usbduxsub_start(struct usbduxsub *usbduxsub)
{
int errcode = 0;
- uint8_t local_transfer_buffer[16];
+ uint8_t *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to zero */
- local_transfer_buffer[0] = 0;
+ *local_transfer_buffer = 0;
errcode = usb_control_msg(usbduxsub->usbdev,
/* create a pipe for a control transfer */
usb_sndctrlpipe(usbduxsub->usbdev, 0),
@@ -751,22 +755,25 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (start)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_stop(struct usbduxsub *usbduxsub)
{
int errcode = 0;
+ uint8_t *local_transfer_buffer;
- uint8_t local_transfer_buffer[16];
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to one */
- local_transfer_buffer[0] = 1;
+ *local_transfer_buffer = 1;
errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* bRequest, "Firmware" */
@@ -781,17 +788,17 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (stop)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_upload(struct usbduxsub *usbduxsub,
uint8_t *local_transfer_buffer,
- unsigned int startAddr, unsigned int len)
+ unsigned int start_addr, unsigned int len)
{
int errcode;
@@ -802,7 +809,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
/* bmRequestType */
VENDOR_DIR_OUT,
/* value */
- startAddr,
+ start_addr,
/* index */
0x0000,
/* our local safe buffer */
@@ -821,24 +828,24 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
#define FIRMWARE_MAX_LEN 0x2000
-static int firmwareUpload(struct usbduxsub *usbduxsub,
- const u8 *firmwareBinary, int sizeFirmware)
+static int firmware_upload(struct usbduxsub *usbduxsub,
+ const u8 *firmware_binary, int size_firmware)
{
int ret;
- uint8_t *fwBuf;
+ uint8_t *fw_buf;
- if (!firmwareBinary)
+ if (!firmware_binary)
return 0;
- if (sizeFirmware > FIRMWARE_MAX_LEN) {
+ if (size_firmware > FIRMWARE_MAX_LEN) {
dev_err(&usbduxsub->interface->dev,
"usbdux firmware binary it too large for FX2.\n");
return -ENOMEM;
}
/* we generate a local buffer for the firmware */
- fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL);
- if (!fwBuf) {
+ fw_buf = kmemdup(firmware_binary, size_firmware, GFP_KERNEL);
+ if (!fw_buf) {
dev_err(&usbduxsub->interface->dev,
"comedi_: mem alloc for firmware failed\n");
return -ENOMEM;
@@ -848,81 +855,81 @@ static int firmwareUpload(struct usbduxsub *usbduxsub,
if (ret < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: can not stop firmware\n");
- kfree(fwBuf);
+ kfree(fw_buf);
return ret;
}
- ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware);
+ ret = usbduxsub_upload(usbduxsub, fw_buf, 0, size_firmware);
if (ret < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: firmware upload failed\n");
- kfree(fwBuf);
+ kfree(fw_buf);
return ret;
}
ret = usbduxsub_start(usbduxsub);
if (ret < 0) {
dev_err(&usbduxsub->interface->dev,
"comedi_: can not start firmware\n");
- kfree(fwBuf);
+ kfree(fw_buf);
return ret;
}
- kfree(fwBuf);
+ kfree(fw_buf);
return 0;
}
-static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub)
+static int usbduxsub_submit_inurbs(struct usbduxsub *usbduxsub)
{
- int i, errFlag;
+ int i, err_flag;
if (!usbduxsub)
return -EFAULT;
/* Submit all URBs and start the transfer on the bus */
- for (i = 0; i < usbduxsub->numOfInBuffers; i++) {
+ for (i = 0; i < usbduxsub->num_in_buffers; i++) {
/* in case of a resubmission after an unlink... */
- usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval;
- usbduxsub->urbIn[i]->context = usbduxsub->comedidev;
- usbduxsub->urbIn[i]->dev = usbduxsub->usbdev;
- usbduxsub->urbIn[i]->status = 0;
- usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP;
+ usbduxsub->urb_in[i]->interval = usbduxsub->ai_interval;
+ usbduxsub->urb_in[i]->context = usbduxsub->comedidev;
+ usbduxsub->urb_in[i]->dev = usbduxsub->usbdev;
+ usbduxsub->urb_in[i]->status = 0;
+ usbduxsub->urb_in[i]->transfer_flags = URB_ISO_ASAP;
dev_dbg(&usbduxsub->interface->dev,
"comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n",
usbduxsub->comedidev->minor, i,
- (usbduxsub->urbIn[i]->context),
- (usbduxsub->urbIn[i]->dev),
- (usbduxsub->urbIn[i]->interval));
- errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC);
- if (errFlag) {
+ (usbduxsub->urb_in[i]->context),
+ (usbduxsub->urb_in[i]->dev),
+ (usbduxsub->urb_in[i]->interval));
+ err_flag = usb_submit_urb(usbduxsub->urb_in[i], GFP_ATOMIC);
+ if (err_flag) {
dev_err(&usbduxsub->interface->dev,
"comedi_: ai: usb_submit_urb(%d) error %d\n",
- i, errFlag);
- return errFlag;
+ i, err_flag);
+ return err_flag;
}
}
return 0;
}
-static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
+static int usbduxsub_submit_outurbs(struct usbduxsub *usbduxsub)
{
- int i, errFlag;
+ int i, err_flag;
if (!usbduxsub)
return -EFAULT;
- for (i = 0; i < usbduxsub->numOfOutBuffers; i++) {
+ for (i = 0; i < usbduxsub->num_out_buffers; i++) {
dev_dbg(&usbduxsub->interface->dev,
"comedi_: submitting out-urb[%d]\n", i);
/* in case of a resubmission after an unlink... */
- usbduxsub->urbOut[i]->context = usbduxsub->comedidev;
- usbduxsub->urbOut[i]->dev = usbduxsub->usbdev;
- usbduxsub->urbOut[i]->status = 0;
- usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP;
- errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC);
- if (errFlag) {
+ usbduxsub->urb_out[i]->context = usbduxsub->comedidev;
+ usbduxsub->urb_out[i]->dev = usbduxsub->usbdev;
+ usbduxsub->urb_out[i]->status = 0;
+ usbduxsub->urb_out[i]->transfer_flags = URB_ISO_ASAP;
+ err_flag = usb_submit_urb(usbduxsub->urb_out[i], GFP_ATOMIC);
+ if (err_flag) {
dev_err(&usbduxsub->interface->dev,
"comedi_: ao: usb_submit_urb(%d) error %d\n",
- i, errFlag);
- return errFlag;
+ i, err_flag);
+ return err_flag;
}
}
return 0;
@@ -933,7 +940,7 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
{
struct usbduxsub *this_usbduxsub = dev->private;
int err = 0, i;
- unsigned int tmpTimer;
+ unsigned int tmp_timer;
if (!(this_usbduxsub->probed))
return -ENODEV;
@@ -983,7 +990,7 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
1000000 / 8 * i);
/* now calc the real sampling rate with all the
* rounding errors */
- tmpTimer =
+ tmp_timer =
((unsigned int)(cmd->scan_begin_arg / 125000)) *
125000;
} else {
@@ -994,11 +1001,11 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
/*
* calc the real sampling rate with the rounding errors
*/
- tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
+ tmp_timer = ((unsigned int)(cmd->scan_begin_arg /
1000000)) * 1000000;
}
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg,
- tmpTimer);
+ tmp_timer);
}
err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
@@ -1074,7 +1081,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
result = usb_bulk_msg(this_usbduxsub->usbdev,
usb_rcvbulkpipe(this_usbduxsub->usbdev,
COMMAND_IN_EP),
- this_usbduxsub->insnBuffer, SIZEINSNBUF,
+ this_usbduxsub->insn_buffer, SIZEINSNBUF,
&nrec, BULK_TIMEOUT);
if (result < 0) {
dev_err(&this_usbduxsub->interface->dev, "comedi%d: "
@@ -1082,7 +1089,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
"\n", this_usbduxsub->comedidev->minor, result);
return result;
}
- if (le16_to_cpu(this_usbduxsub->insnBuffer[0]) == command)
+ if (le16_to_cpu(this_usbduxsub->insn_buffer[0]) == command)
return result;
}
/* this is only reached if the data has been requested a couple of
@@ -1090,7 +1097,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: "
"wrong data returned from firmware: want cmd %d, got cmd %d.\n",
this_usbduxsub->comedidev->minor, command,
- le16_to_cpu(this_usbduxsub->insnBuffer[0]));
+ le16_to_cpu(this_usbduxsub->insn_buffer[0]));
return -EFAULT;
}
@@ -1119,7 +1126,7 @@ static int usbdux_ai_inttrig(struct comedi_device *dev,
}
if (!(this_usbduxsub->ai_cmd_running)) {
this_usbduxsub->ai_cmd_running = 1;
- ret = usbduxsub_submit_InURBs(this_usbduxsub);
+ ret = usbduxsub_submit_inurbs(this_usbduxsub);
if (ret < 0) {
dev_err(&this_usbduxsub->interface->dev,
"comedi%d: usbdux_ai_inttrig: "
@@ -1236,7 +1243,7 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (cmd->start_src == TRIG_NOW) {
/* enable this acquisition operation */
this_usbduxsub->ai_cmd_running = 1;
- ret = usbduxsub_submit_InURBs(this_usbduxsub);
+ ret = usbduxsub_submit_inurbs(this_usbduxsub);
if (ret < 0) {
this_usbduxsub->ai_cmd_running = 0;
/* fixme: unlink here?? */
@@ -1304,7 +1311,7 @@ static int usbdux_ai_insn_read(struct comedi_device *dev,
up(&this_usbduxsub->sem);
return 0;
}
- one = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
+ one = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
if (CR_RANGE(insn->chanspec) <= 1)
one = one ^ 0x800;
@@ -1334,7 +1341,7 @@ static int usbdux_ao_insn_read(struct comedi_device *dev,
return -ENODEV;
}
for (i = 0; i < insn->n; i++)
- data[i] = this_usbduxsub->outBuffer[chan];
+ data[i] = this_usbduxsub->out_buffer[chan];
up(&this_usbduxsub->sem);
return i;
@@ -1377,7 +1384,7 @@ static int usbdux_ao_insn_write(struct comedi_device *dev,
/* one 16 bit value */
*((int16_t *) (this_usbduxsub->dux_commands + 2)) =
cpu_to_le16(data[i]);
- this_usbduxsub->outBuffer[chan] = data[i];
+ this_usbduxsub->out_buffer[chan] = data[i];
/* channel number */
this_usbduxsub->dux_commands[4] = (chan << 6);
err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS);
@@ -1414,7 +1421,7 @@ static int usbdux_ao_inttrig(struct comedi_device *dev,
}
if (!(this_usbduxsub->ao_cmd_running)) {
this_usbduxsub->ao_cmd_running = 1;
- ret = usbduxsub_submit_OutURBs(this_usbduxsub);
+ ret = usbduxsub_submit_outurbs(this_usbduxsub);
if (ret < 0) {
dev_err(&this_usbduxsub->interface->dev,
"comedi%d: usbdux_ao_inttrig: submitURB: "
@@ -1609,7 +1616,7 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (cmd->start_src == TRIG_NOW) {
/* enable this acquisition operation */
this_usbduxsub->ao_cmd_running = 1;
- ret = usbduxsub_submit_OutURBs(this_usbduxsub);
+ ret = usbduxsub_submit_outurbs(this_usbduxsub);
if (ret < 0) {
this_usbduxsub->ao_cmd_running = 0;
/* fixme: unlink here?? */
@@ -1697,7 +1704,7 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev,
return err;
}
- data[1] = le16_to_cpu(this_usbduxsub->insnBuffer[1]);
+ data[1] = le16_to_cpu(this_usbduxsub->insn_buffer[1]);
up(&this_usbduxsub->sem);
return insn->n;
}
@@ -1733,7 +1740,7 @@ static int usbdux_counter_read(struct comedi_device *dev,
return err;
}
- data[0] = le16_to_cpu(this_usbduxsub->insnBuffer[chan + 1]);
+ data[0] = le16_to_cpu(this_usbduxsub->insn_buffer[chan + 1]);
up(&this_usbduxsub->sem);
return 1;
}
@@ -1780,13 +1787,13 @@ static int usbdux_counter_config(struct comedi_device *dev,
/***********************************/
/* PWM */
-static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp)
+static int usbduxsub_unlink_pwm_urbs(struct usbduxsub *usbduxsub_tmp)
{
int err = 0;
- if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) {
- if (usbduxsub_tmp->urbPwm)
- usb_kill_urb(usbduxsub_tmp->urbPwm);
+ if (usbduxsub_tmp && usbduxsub_tmp->urb_pwm) {
+ if (usbduxsub_tmp->urb_pwm)
+ usb_kill_urb(usbduxsub_tmp->urb_pwm);
dev_dbg(&usbduxsub_tmp->interface->dev,
"comedi: unlinked PwmURB: res=%d\n", err);
}
@@ -1805,7 +1812,7 @@ static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__);
if (do_unlink)
- ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
+ ret = usbduxsub_unlink_pwm_urbs(this_usbduxsub);
this_usbduxsub->pwm_cmd_running = 0;
@@ -1878,7 +1885,7 @@ static void usbduxsub_pwm_irq(struct urb *urb)
if (!(this_usbduxsub->pwm_cmd_running))
return;
- urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf;
+ urb->transfer_buffer_length = this_usbduxsub->size_pwm_buf;
urb->dev = this_usbduxsub->usbdev;
urb->status = 0;
if (this_usbduxsub->pwm_cmd_running) {
@@ -1898,9 +1905,9 @@ static void usbduxsub_pwm_irq(struct urb *urb)
}
}
-static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
+static int usbduxsub_submit_pwm_urbs(struct usbduxsub *usbduxsub)
{
- int errFlag;
+ int err_flag;
if (!usbduxsub)
return -EFAULT;
@@ -1908,19 +1915,19 @@ static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n");
/* in case of a resubmission after an unlink... */
- usb_fill_bulk_urb(usbduxsub->urbPwm,
+ usb_fill_bulk_urb(usbduxsub->urb_pwm,
usbduxsub->usbdev,
usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
- usbduxsub->urbPwm->transfer_buffer,
- usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
+ usbduxsub->urb_pwm->transfer_buffer,
+ usbduxsub->size_pwm_buf, usbduxsub_pwm_irq,
usbduxsub->comedidev);
- errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
- if (errFlag) {
+ err_flag = usb_submit_urb(usbduxsub->urb_pwm, GFP_ATOMIC);
+ if (err_flag) {
dev_err(&usbduxsub->interface->dev,
"comedi_: usbdux: pwm: usb_submit_urb error %d\n",
- errFlag);
- return errFlag;
+ err_flag);
+ return err_flag;
}
return 0;
}
@@ -1945,8 +1952,8 @@ static int usbdux_pwm_period(struct comedi_device *dev,
return -EAGAIN;
}
}
- this_usbduxsub->pwmDelay = fx2delay;
- this_usbduxsub->pwmPeriod = period;
+ this_usbduxsub->pwn_delay = fx2delay;
+ this_usbduxsub->pwm_period = period;
dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n",
__func__, period, fx2delay);
return 0;
@@ -1967,17 +1974,17 @@ static int usbdux_pwm_start(struct comedi_device *dev,
return 0;
}
- this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwmDelay);
+ this_usbduxsub->dux_commands[1] = ((int8_t) this_usbduxsub->pwn_delay);
ret = send_dux_commands(this_usbduxsub, SENDPWMON);
if (ret < 0)
return ret;
/* initialise the buffer */
- for (i = 0; i < this_usbduxsub->sizePwmBuf; i++)
- ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0;
+ for (i = 0; i < this_usbduxsub->size_pwm_buf; i++)
+ ((char *)(this_usbduxsub->urb_pwm->transfer_buffer))[i] = 0;
this_usbduxsub->pwm_cmd_running = 1;
- ret = usbduxsub_submit_PwmURBs(this_usbduxsub);
+ ret = usbduxsub_submit_pwm_urbs(this_usbduxsub);
if (ret < 0) {
this_usbduxsub->pwm_cmd_running = 0;
return ret;
@@ -1992,7 +1999,7 @@ static int usbdux_pwm_pattern(struct comedi_device *dev,
{
struct usbduxsub *this_usbduxsub = dev->private;
int i, szbuf;
- char *pBuf;
+ char *p_buf;
char pwm_mask;
char sgn_mask;
char c;
@@ -2006,10 +2013,10 @@ static int usbdux_pwm_pattern(struct comedi_device *dev,
sgn_mask = (16 << channel);
/* this is the buffer which will be filled with the with bit */
/* pattern for one period */
- szbuf = this_usbduxsub->sizePwmBuf;
- pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer);
+ szbuf = this_usbduxsub->size_pwm_buf;
+ p_buf = (char *)(this_usbduxsub->urb_pwm->transfer_buffer);
for (i = 0; i < szbuf; i++) {
- c = *pBuf;
+ c = *p_buf;
/* reset bits */
c = c & (~pwm_mask);
/* set the bit as long as the index is lower than the value */
@@ -2023,7 +2030,7 @@ static int usbdux_pwm_pattern(struct comedi_device *dev,
/* negative value */
c = c | sgn_mask;
}
- *(pBuf++) = c;
+ *(p_buf++) = c;
}
return 1;
}
@@ -2095,7 +2102,7 @@ static int usbdux_pwm_config(struct comedi_device *dev,
"comedi%d: %s: setting period\n", dev->minor, __func__);
return usbdux_pwm_period(dev, s, data[1]);
case INSN_CONFIG_PWM_GET_PERIOD:
- data[1] = this_usbduxsub->pwmPeriod;
+ data[1] = this_usbduxsub->pwm_period;
return 0;
case INSN_CONFIG_PWM_SET_H_BRIDGE:
/* value in the first byte and the sign in the second for a
@@ -2131,55 +2138,55 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
usbduxsub_tmp->probed = 0;
- if (usbduxsub_tmp->urbIn) {
+ if (usbduxsub_tmp->urb_in) {
if (usbduxsub_tmp->ai_cmd_running) {
usbduxsub_tmp->ai_cmd_running = 0;
- usbduxsub_unlink_InURBs(usbduxsub_tmp);
+ usbduxsub_unlink_inurbs(usbduxsub_tmp);
}
- for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) {
- kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer);
- usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL;
- usb_kill_urb(usbduxsub_tmp->urbIn[i]);
- usb_free_urb(usbduxsub_tmp->urbIn[i]);
- usbduxsub_tmp->urbIn[i] = NULL;
+ for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) {
+ kfree(usbduxsub_tmp->urb_in[i]->transfer_buffer);
+ usbduxsub_tmp->urb_in[i]->transfer_buffer = NULL;
+ usb_kill_urb(usbduxsub_tmp->urb_in[i]);
+ usb_free_urb(usbduxsub_tmp->urb_in[i]);
+ usbduxsub_tmp->urb_in[i] = NULL;
}
- kfree(usbduxsub_tmp->urbIn);
- usbduxsub_tmp->urbIn = NULL;
+ kfree(usbduxsub_tmp->urb_in);
+ usbduxsub_tmp->urb_in = NULL;
}
- if (usbduxsub_tmp->urbOut) {
+ if (usbduxsub_tmp->urb_out) {
if (usbduxsub_tmp->ao_cmd_running) {
usbduxsub_tmp->ao_cmd_running = 0;
- usbduxsub_unlink_OutURBs(usbduxsub_tmp);
+ usbduxsub_unlink_outurbs(usbduxsub_tmp);
}
- for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
- kfree(usbduxsub_tmp->urbOut[i]->transfer_buffer);
- usbduxsub_tmp->urbOut[i]->transfer_buffer = NULL;
- if (usbduxsub_tmp->urbOut[i]) {
- usb_kill_urb(usbduxsub_tmp->urbOut[i]);
- usb_free_urb(usbduxsub_tmp->urbOut[i]);
- usbduxsub_tmp->urbOut[i] = NULL;
+ for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) {
+ kfree(usbduxsub_tmp->urb_out[i]->transfer_buffer);
+ usbduxsub_tmp->urb_out[i]->transfer_buffer = NULL;
+ if (usbduxsub_tmp->urb_out[i]) {
+ usb_kill_urb(usbduxsub_tmp->urb_out[i]);
+ usb_free_urb(usbduxsub_tmp->urb_out[i]);
+ usbduxsub_tmp->urb_out[i] = NULL;
}
}
- kfree(usbduxsub_tmp->urbOut);
- usbduxsub_tmp->urbOut = NULL;
+ kfree(usbduxsub_tmp->urb_out);
+ usbduxsub_tmp->urb_out = NULL;
}
- if (usbduxsub_tmp->urbPwm) {
+ if (usbduxsub_tmp->urb_pwm) {
if (usbduxsub_tmp->pwm_cmd_running) {
usbduxsub_tmp->pwm_cmd_running = 0;
- usbduxsub_unlink_PwmURBs(usbduxsub_tmp);
+ usbduxsub_unlink_pwm_urbs(usbduxsub_tmp);
}
- kfree(usbduxsub_tmp->urbPwm->transfer_buffer);
- usbduxsub_tmp->urbPwm->transfer_buffer = NULL;
- usb_kill_urb(usbduxsub_tmp->urbPwm);
- usb_free_urb(usbduxsub_tmp->urbPwm);
- usbduxsub_tmp->urbPwm = NULL;
- }
- kfree(usbduxsub_tmp->inBuffer);
- usbduxsub_tmp->inBuffer = NULL;
- kfree(usbduxsub_tmp->insnBuffer);
- usbduxsub_tmp->insnBuffer = NULL;
- kfree(usbduxsub_tmp->outBuffer);
- usbduxsub_tmp->outBuffer = NULL;
+ kfree(usbduxsub_tmp->urb_pwm->transfer_buffer);
+ usbduxsub_tmp->urb_pwm->transfer_buffer = NULL;
+ usb_kill_urb(usbduxsub_tmp->urb_pwm);
+ usb_free_urb(usbduxsub_tmp->urb_pwm);
+ usbduxsub_tmp->urb_pwm = NULL;
+ }
+ kfree(usbduxsub_tmp->in_buffer);
+ usbduxsub_tmp->in_buffer = NULL;
+ kfree(usbduxsub_tmp->insn_buffer);
+ usbduxsub_tmp->insn_buffer = NULL;
+ kfree(usbduxsub_tmp->out_buffer);
+ usbduxsub_tmp->out_buffer = NULL;
kfree(usbduxsub_tmp->dac_commands);
usbduxsub_tmp->dac_commands = NULL;
kfree(usbduxsub_tmp->dux_commands);
@@ -2200,8 +2207,6 @@ static int usbdux_attach_common(struct comedi_device *dev,
/* pointer back to the corresponding comedi device */
udev->comedidev = dev;
- dev->board_name = "usbdux";
-
/* set number of subdevices */
if (udev->high_speed) {
/* with pwm */
@@ -2302,7 +2307,7 @@ static int usbdux_attach_common(struct comedi_device *dev,
s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE;
s->n_chan = 8;
/* this defines the max duty cycle resolution */
- s->maxdata = udev->sizePwmBuf;
+ s->maxdata = udev->size_pwm_buf;
s->insn_write = usbdux_pwm_write;
s->insn_read = usbdux_pwm_read;
s->insn_config = usbdux_pwm_config;
@@ -2381,7 +2386,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
* we need to upload the firmware here because fw will be
* freed once we've left this function
*/
- ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size);
+ ret = firmware_upload(usbduxsub_tmp, fw->data, fw->size);
if (ret) {
dev_err(&uinterf->dev,
@@ -2457,22 +2462,22 @@ static int usbdux_usb_probe(struct usb_interface *uinterf,
return -ENOMEM;
}
/* create space for the in buffer and set it to zero */
- usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL);
- if (!(usbduxsub[index].inBuffer)) {
+ usbduxsub[index].in_buffer = kzalloc(SIZEINBUF, GFP_KERNEL);
+ if (!(usbduxsub[index].in_buffer)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
/* create space of the instruction buffer */
- usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
- if (!(usbduxsub[index].insnBuffer)) {
+ usbduxsub[index].insn_buffer = kzalloc(SIZEINSNBUF, GFP_KERNEL);
+ if (!(usbduxsub[index].insn_buffer)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
/* create space for the outbuffer */
- usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
- if (!(usbduxsub[index].outBuffer)) {
+ usbduxsub[index].out_buffer = kzalloc(SIZEOUTBUF, GFP_KERNEL);
+ if (!(usbduxsub[index].out_buffer)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
@@ -2489,124 +2494,124 @@ static int usbdux_usb_probe(struct usb_interface *uinterf,
return -ENODEV;
}
if (usbduxsub[index].high_speed)
- usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH;
+ usbduxsub[index].num_in_buffers = NUMOFINBUFFERSHIGH;
else
- usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
+ usbduxsub[index].num_in_buffers = NUMOFINBUFFERSFULL;
- usbduxsub[index].urbIn =
- kcalloc(usbduxsub[index].numOfInBuffers, sizeof(struct urb *),
+ usbduxsub[index].urb_in =
+ kcalloc(usbduxsub[index].num_in_buffers, sizeof(struct urb *),
GFP_KERNEL);
- if (!(usbduxsub[index].urbIn)) {
+ if (!(usbduxsub[index].urb_in)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) {
+ for (i = 0; i < usbduxsub[index].num_in_buffers; i++) {
/* one frame: 1ms */
- usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL);
- if (usbduxsub[index].urbIn[i] == NULL) {
+ usbduxsub[index].urb_in[i] = usb_alloc_urb(1, GFP_KERNEL);
+ if (usbduxsub[index].urb_in[i] == NULL) {
dev_err(dev, "comedi_: usbdux%d: "
"Could not alloc. urb(%d)\n", index, i);
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev;
+ usbduxsub[index].urb_in[i]->dev = usbduxsub[index].usbdev;
/* will be filled later with a pointer to the comedi-device */
/* and ONLY then the urb should be submitted */
- usbduxsub[index].urbIn[i]->context = NULL;
- usbduxsub[index].urbIn[i]->pipe =
+ usbduxsub[index].urb_in[i]->context = NULL;
+ usbduxsub[index].urb_in[i]->pipe =
usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
- usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
- usbduxsub[index].urbIn[i]->transfer_buffer =
+ usbduxsub[index].urb_in[i]->transfer_flags = URB_ISO_ASAP;
+ usbduxsub[index].urb_in[i]->transfer_buffer =
kzalloc(SIZEINBUF, GFP_KERNEL);
- if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
+ if (!(usbduxsub[index].urb_in[i]->transfer_buffer)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq;
- usbduxsub[index].urbIn[i]->number_of_packets = 1;
- usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF;
- usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0;
- usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = SIZEINBUF;
+ usbduxsub[index].urb_in[i]->complete = usbduxsub_ai_isoc_irq;
+ usbduxsub[index].urb_in[i]->number_of_packets = 1;
+ usbduxsub[index].urb_in[i]->transfer_buffer_length = SIZEINBUF;
+ usbduxsub[index].urb_in[i]->iso_frame_desc[0].offset = 0;
+ usbduxsub[index].urb_in[i]->iso_frame_desc[0].length = SIZEINBUF;
}
/* out */
if (usbduxsub[index].high_speed)
- usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH;
+ usbduxsub[index].num_out_buffers = NUMOFOUTBUFFERSHIGH;
else
- usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
+ usbduxsub[index].num_out_buffers = NUMOFOUTBUFFERSFULL;
- usbduxsub[index].urbOut =
- kcalloc(usbduxsub[index].numOfOutBuffers, sizeof(struct urb *),
+ usbduxsub[index].urb_out =
+ kcalloc(usbduxsub[index].num_out_buffers, sizeof(struct urb *),
GFP_KERNEL);
- if (!(usbduxsub[index].urbOut)) {
+ if (!(usbduxsub[index].urb_out)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) {
+ for (i = 0; i < usbduxsub[index].num_out_buffers; i++) {
/* one frame: 1ms */
- usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL);
- if (usbduxsub[index].urbOut[i] == NULL) {
+ usbduxsub[index].urb_out[i] = usb_alloc_urb(1, GFP_KERNEL);
+ if (usbduxsub[index].urb_out[i] == NULL) {
dev_err(dev, "comedi_: usbdux%d: "
"Could not alloc. urb(%d)\n", index, i);
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev;
+ usbduxsub[index].urb_out[i]->dev = usbduxsub[index].usbdev;
/* will be filled later with a pointer to the comedi-device */
/* and ONLY then the urb should be submitted */
- usbduxsub[index].urbOut[i]->context = NULL;
- usbduxsub[index].urbOut[i]->pipe =
+ usbduxsub[index].urb_out[i]->context = NULL;
+ usbduxsub[index].urb_out[i]->pipe =
usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
- usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
- usbduxsub[index].urbOut[i]->transfer_buffer =
+ usbduxsub[index].urb_out[i]->transfer_flags = URB_ISO_ASAP;
+ usbduxsub[index].urb_out[i]->transfer_buffer =
kzalloc(SIZEOUTBUF, GFP_KERNEL);
- if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
+ if (!(usbduxsub[index].urb_out[i]->transfer_buffer)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq;
- usbduxsub[index].urbOut[i]->number_of_packets = 1;
- usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF;
- usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
- usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
+ usbduxsub[index].urb_out[i]->complete = usbduxsub_ao_isoc_irq;
+ usbduxsub[index].urb_out[i]->number_of_packets = 1;
+ usbduxsub[index].urb_out[i]->transfer_buffer_length = SIZEOUTBUF;
+ usbduxsub[index].urb_out[i]->iso_frame_desc[0].offset = 0;
+ usbduxsub[index].urb_out[i]->iso_frame_desc[0].length =
SIZEOUTBUF;
if (usbduxsub[index].high_speed) {
/* uframes */
- usbduxsub[index].urbOut[i]->interval = 8;
+ usbduxsub[index].urb_out[i]->interval = 8;
} else {
/* frames */
- usbduxsub[index].urbOut[i]->interval = 1;
+ usbduxsub[index].urb_out[i]->interval = 1;
}
}
/* pwm */
if (usbduxsub[index].high_speed) {
/* max bulk ep size in high speed */
- usbduxsub[index].sizePwmBuf = 512;
- usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL);
- if (usbduxsub[index].urbPwm == NULL) {
+ usbduxsub[index].size_pwm_buf = 512;
+ usbduxsub[index].urb_pwm = usb_alloc_urb(0, GFP_KERNEL);
+ if (usbduxsub[index].urb_pwm == NULL) {
dev_err(dev, "comedi_: usbdux%d: "
"Could not alloc. pwm urb\n", index);
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- usbduxsub[index].urbPwm->transfer_buffer =
- kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
- if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
+ usbduxsub[index].urb_pwm->transfer_buffer =
+ kzalloc(usbduxsub[index].size_pwm_buf, GFP_KERNEL);
+ if (!(usbduxsub[index].urb_pwm->transfer_buffer)) {
tidy_up(&(usbduxsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
} else {
- usbduxsub[index].urbPwm = NULL;
- usbduxsub[index].sizePwmBuf = 0;
+ usbduxsub[index].urb_pwm = NULL;
+ usbduxsub[index].size_pwm_buf = 0;
}
usbduxsub[index].ai_cmd_running = 0;
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 4bf5dd094dc..7f95af33085 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -436,10 +436,14 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
{
int ret;
- unsigned char local_transfer_buffer[16];
+ unsigned char *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to zero */
- local_transfer_buffer[0] = 0;
+ *local_transfer_buffer = 0;
/* bRequest, "Firmware" */
ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
USBDUXFASTSUB_FIRMWARE,
@@ -450,22 +454,25 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
local_transfer_buffer,
1, /* Length */
EZTIMEOUT); /* Timeout */
- if (ret < 0) {
+ if (ret < 0)
dev_err(&udfs->interface->dev,
"control msg failed (start)\n");
- return ret;
- }
- return 0;
+ kfree(local_transfer_buffer);
+ return ret;
}
static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
{
int ret;
- unsigned char local_transfer_buffer[16];
+ unsigned char *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to one */
- local_transfer_buffer[0] = 1;
+ *local_transfer_buffer = 1;
/* bRequest, "Firmware" */
ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
USBDUXFASTSUB_FIRMWARE,
@@ -474,13 +481,12 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
0x0000, /* Index */
local_transfer_buffer, 1, /* Length */
EZTIMEOUT); /* Timeout */
- if (ret < 0) {
+ if (ret < 0)
dev_err(&udfs->interface->dev,
"control msg failed (stop)\n");
- return ret;
- }
- return 0;
+ kfree(local_transfer_buffer);
+ return ret;
}
static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
@@ -1381,7 +1387,7 @@ static int usbduxfast_attach_common(struct comedi_device *dev,
down(&udfs->sem);
/* pointer back to the corresponding comedi device */
udfs->comedidev = dev;
- dev->board_name = "usbduxfast";
+
ret = comedi_alloc_subdevices(dev, 1);
if (ret) {
up(&udfs->sem);
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index d066351a71b..d3bc1b9910a 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -176,12 +176,6 @@ static const struct comedi_lrange range_usbdux_ai_range = { 1, {
}
};
-static const struct comedi_lrange range_usbdux_ao_range = { 1, {
- UNI_RANGE
- (2.5),
- }
-};
-
/*
* private structure of one subdevice
*/
@@ -681,7 +675,11 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
static int usbduxsub_start(struct usbduxsub *usbduxsub)
{
int errcode = 0;
- uint8_t local_transfer_buffer[16];
+ uint8_t *local_transfer_buffer;
+
+ local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to zero */
local_transfer_buffer[0] = 0;
@@ -702,19 +700,22 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (start)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_stop(struct usbduxsub *usbduxsub)
{
int errcode = 0;
+ uint8_t *local_transfer_buffer;
- uint8_t local_transfer_buffer[16];
+ local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+ if (!local_transfer_buffer)
+ return -ENOMEM;
/* 7f92 to one */
local_transfer_buffer[0] = 1;
@@ -732,12 +733,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
1,
/* Timeout */
BULK_TIMEOUT);
- if (errcode < 0) {
+ if (errcode < 0)
dev_err(&usbduxsub->interface->dev,
"comedi_: control msg failed (stop)\n");
- return errcode;
- }
- return 0;
+
+ kfree(local_transfer_buffer);
+ return errcode;
}
static int usbduxsub_upload(struct usbduxsub *usbduxsub,
@@ -1369,7 +1370,7 @@ static int usbdux_getstatusinfo(struct comedi_device *dev, int chan)
/* 32 bits big endian from the A/D converter */
one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1)));
- /* mask out the staus byte */
+ /* mask out the status byte */
one = one & 0x00ffffff;
one = one ^ 0x00800000;
@@ -2204,7 +2205,7 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
down(&uds->sem);
/* pointer back to the corresponding comedi device */
uds->comedidev = dev;
- dev->board_name = "usbduxsigma";
+
/* set number of subdevices */
if (uds->high_speed)
n_subdevs = 4; /* with pwm */
@@ -2262,7 +2263,7 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
/* 8 bit resolution */
s->maxdata = 0x00ff;
/* unipolar range */
- s->range_table = (&range_usbdux_ao_range);
+ s->range_table = &range_unipolar2_5;
/* callback */
s->do_cmdtest = usbdux_ao_cmdtest;
s->do_cmd = usbdux_ao_cmd;
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 8932a510d96..3231a483f56 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -63,7 +63,7 @@ struct comedi_device *comedi_open(const char *filename)
return dev;
}
-EXPORT_SYMBOL(comedi_open);
+EXPORT_SYMBOL_GPL(comedi_open);
int comedi_close(struct comedi_device *d)
{
@@ -73,7 +73,7 @@ int comedi_close(struct comedi_device *d)
return 0;
}
-EXPORT_SYMBOL(comedi_close);
+EXPORT_SYMBOL_GPL(comedi_close);
static int comedi_do_insn(struct comedi_device *dev,
struct comedi_insn *insn,
@@ -143,7 +143,7 @@ int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
return comedi_do_insn(dev, &insn, &io);
}
-EXPORT_SYMBOL(comedi_dio_config);
+EXPORT_SYMBOL_GPL(comedi_dio_config);
int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev,
unsigned int mask, unsigned int *bits)
@@ -166,7 +166,7 @@ int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev,
return ret;
}
-EXPORT_SYMBOL(comedi_dio_bitfield);
+EXPORT_SYMBOL_GPL(comedi_dio_bitfield);
int comedi_find_subdevice_by_type(struct comedi_device *dev, int type,
unsigned int subd)
@@ -183,7 +183,7 @@ int comedi_find_subdevice_by_type(struct comedi_device *dev, int type,
}
return -1;
}
-EXPORT_SYMBOL(comedi_find_subdevice_by_type);
+EXPORT_SYMBOL_GPL(comedi_find_subdevice_by_type);
int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice)
{
@@ -191,4 +191,4 @@ int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice)
return s->n_chan;
}
-EXPORT_SYMBOL(comedi_get_n_channels);
+EXPORT_SYMBOL_GPL(comedi_get_n_channels);
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 59ff0cf7338..1dc391b7644 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -26,17 +26,25 @@
#include "comedi_internal.h"
const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
-EXPORT_SYMBOL(range_bipolar10);
+EXPORT_SYMBOL_GPL(range_bipolar10);
const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
-EXPORT_SYMBOL(range_bipolar5);
+EXPORT_SYMBOL_GPL(range_bipolar5);
const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
-EXPORT_SYMBOL(range_bipolar2_5);
+EXPORT_SYMBOL_GPL(range_bipolar2_5);
const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
-EXPORT_SYMBOL(range_unipolar10);
+EXPORT_SYMBOL_GPL(range_unipolar10);
const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
-EXPORT_SYMBOL(range_unipolar5);
+EXPORT_SYMBOL_GPL(range_unipolar5);
+const struct comedi_lrange range_unipolar2_5 = { 1, {UNI_RANGE(2.5)} };
+EXPORT_SYMBOL_GPL(range_unipolar2_5);
+const struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+EXPORT_SYMBOL_GPL(range_0_20mA);
+const struct comedi_lrange range_4_20mA = { 1, {RANGE_mA(4, 20)} };
+EXPORT_SYMBOL_GPL(range_4_20mA);
+const struct comedi_lrange range_0_32mA = { 1, {RANGE_mA(0, 32)} };
+EXPORT_SYMBOL_GPL(range_0_32mA);
const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } };
-EXPORT_SYMBOL(range_unknown);
+EXPORT_SYMBOL_GPL(range_unknown);
/*
COMEDI_RANGEINFO
@@ -165,4 +173,4 @@ int comedi_check_chanlist(struct comedi_subdevice *s, int n,
}
return 0;
}
-EXPORT_SYMBOL(comedi_check_chanlist);
+EXPORT_SYMBOL_GPL(comedi_check_chanlist);