aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--drivers/staging/comedi/drivers.c9
-rw-r--r--drivers/staging/comedi/drivers/8253.h6
-rw-r--r--drivers/staging/comedi/drivers/8255.c3
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c27
-rw-r--r--drivers/staging/comedi/drivers/Makefile4
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c10
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h20
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c9
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c7
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c321
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c61
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c228
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c391
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c11
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c8
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c2
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c84
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c101
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c161
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c148
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c22
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c5
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1724.c15
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c11
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c3
-rw-r--r--drivers/staging/comedi/drivers/amcc_s5933.h8
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c3
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.h13
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_common.c45
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200_pci.c45
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c591
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.h42
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236_common.c206
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c7
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c26
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c1310
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci236.c161
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci263.c11
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c24
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c154
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c3
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c6
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c4
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c87
-rw-r--r--drivers/staging/comedi/drivers/das08.c3
-rw-r--r--drivers/staging/comedi/drivers/das08_pci.c4
-rw-r--r--drivers/staging/comedi/drivers/das16.c16
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c13
-rw-r--r--drivers/staging/comedi/drivers/das1800.c120
-rw-r--r--drivers/staging/comedi/drivers/das800.c3
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c13
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c5
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c4
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c12
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c5
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c4
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1351
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c117
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c1
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c44
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c94
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c68
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c5
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c66
-rw-r--r--drivers/staging/comedi/drivers/me4000.c1
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c67
-rw-r--r--drivers/staging/comedi/drivers/mf6x4.c47
-rw-r--r--drivers/staging/comedi/drivers/mite.c46
-rw-r--r--drivers/staging/comedi/drivers/mite.h136
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c5
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c8
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c154
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c797
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c67
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c68
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c254
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c392
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c14
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c89
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c231
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h7
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_pci.c51
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c4866
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c107
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c374
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c775
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h187
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c1687
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h4
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h387
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c140
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c2
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c11
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c21
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c2
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c118
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c9
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c18
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c12
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c207
-rw-r--r--drivers/staging/comedi/drivers/rti800.c4
-rw-r--r--drivers/staging/comedi/drivers/s526.c6
-rw-r--r--drivers/staging/comedi/drivers/s626.c890
-rw-r--r--drivers/staging/comedi/drivers/s626.h28
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c112
-rw-r--r--drivers/staging/comedi/drivers/skel.c9
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c3
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c12
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c8
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c14
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c1
116 files changed, 8592 insertions, 10226 deletions
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 299726f39e26..9ada130f2a76 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -38,6 +38,7 @@
#include "comedi_internal.h"
struct comedi_driver *comedi_drivers;
+/* protects access to comedi_drivers */
DEFINE_MUTEX(comedi_drivers_list_lock);
int comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
@@ -120,6 +121,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev)
dev->driver = NULL;
dev->board_name = NULL;
dev->board_ptr = NULL;
+ dev->mmio = NULL;
dev->iobase = 0;
dev->iolen = 0;
dev->ioenabled = false;
@@ -319,7 +321,7 @@ static int __comedi_device_postconfig_async(struct comedi_device *dev,
return -ENOMEM;
}
if (s->buf_change) {
- ret = s->buf_change(dev, s, buf_size);
+ ret = s->buf_change(dev, s);
if (ret < 0)
return ret;
}
@@ -566,8 +568,9 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
dev->board_ptr = comedi_recognize(driv, it->board_name);
if (dev->board_ptr)
break;
- } else if (strcmp(driv->driver_name, it->board_name) == 0)
+ } else if (strcmp(driv->driver_name, it->board_name) == 0) {
break;
+ }
module_put(driv->module);
}
if (driv == NULL) {
@@ -591,8 +594,6 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = -ENOSYS;
goto out;
}
- /* 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;
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
index 5829b46b757b..f8e1ebad304d 100644
--- a/drivers/staging/comedi/drivers/8253.h
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -34,7 +34,7 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
unsigned int *d1,
unsigned int *d2,
unsigned int *nanosec,
- int round_mode)
+ unsigned int flags)
{
unsigned int divider;
unsigned int div1, div2;
@@ -90,8 +90,7 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
}
}
- round_mode &= TRIG_ROUND_MASK;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
ns_high = div1_lub * div2_lub * i8253_osc_base;
@@ -118,7 +117,6 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
/* masking is done since counter maps zero to 0x10000 */
*d1 = div1 & 0xffff;
*d2 = div2 & 0xffff;
- return;
}
#ifndef CMDTEST
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index 46113a374133..a33a19622745 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -102,9 +102,8 @@ static int subdev_8255_io(int dir, int port, int data, unsigned long iobase)
if (dir) {
outb(data, iobase + port);
return 0;
- } else {
- return inb(iobase + port);
}
+ return inb(iobase + port);
}
void subdev_8255_interrupt(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index 46a385c29ba8..f21e6567ac2f 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -56,7 +56,6 @@ Configuration Options: not applicable, uses PCI auto config
#include "../comedidev.h"
#include "8255.h"
-#include "mite.h"
enum pci_8255_boardid {
BOARD_ADLINK_PCI7224,
@@ -168,9 +167,9 @@ static const struct pci_8255_boardinfo pci_8255_boards[] = {
},
};
-struct pci_8255_private {
- void __iomem *mmio_base;
-};
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
static int pci_8255_mite_init(struct pci_dev *pcidev)
{
@@ -198,9 +197,8 @@ static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase)
if (dir) {
writeb(data, mmio_base + port);
return 0;
- } else {
- return readb(mmio_base + port);
}
+ return readb(mmio_base + port);
}
static int pci_8255_auto_attach(struct comedi_device *dev,
@@ -208,7 +206,6 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct pci_8255_boardinfo *board = NULL;
- struct pci_8255_private *devpriv;
struct comedi_subdevice *s;
bool is_mmio;
int ret;
@@ -221,10 +218,6 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
dev->board_ptr = board;
dev->board_name = board->name;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
ret = comedi_pci_enable(dev);
if (ret)
return ret;
@@ -238,8 +231,8 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
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)
+ dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr);
+ if (!dev->mmio)
return -ENOMEM;
} else {
dev->iobase = pci_resource_start(pcidev, board->dio_badr);
@@ -259,7 +252,7 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[i];
if (is_mmio) {
- iobase = (unsigned long)(devpriv->mmio_base + (i * 4));
+ iobase = (unsigned long)(dev->mmio + (i * 4));
ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase);
} else {
iobase = dev->iobase + (i * 4);
@@ -274,10 +267,8 @@ static int pci_8255_auto_attach(struct comedi_device *dev,
static void pci_8255_detach(struct comedi_device *dev)
{
- struct pci_8255_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mmio_base)
- iounmap(devpriv->mmio_base);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 0757a82ddcfa..8873d4807a01 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_COMEDI_SKEL) += skel.o
# Comedi ISA drivers
obj-$(CONFIG_COMEDI_AMPLC_DIO200_ISA) += amplc_dio200.o
+obj-$(CONFIG_COMEDI_AMPLC_PC236_ISA) += amplc_pc236.o
obj-$(CONFIG_COMEDI_AMPLC_PC263_ISA) += amplc_pc263.o
obj-$(CONFIG_COMEDI_PCL711) += pcl711.o
obj-$(CONFIG_COMEDI_PCL724) += pcl724.o
@@ -80,7 +81,7 @@ 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_PCI) += amplc_dio200_pci.o
-obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236.o
+obj-$(CONFIG_COMEDI_AMPLC_PC236_PCI) += amplc_pci236.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
@@ -138,5 +139,6 @@ obj-$(CONFIG_COMEDI_NI_LABPC_ISADMA) += ni_labpc_isadma.o
obj-$(CONFIG_COMEDI_8255) += 8255.o
obj-$(CONFIG_COMEDI_AMPLC_DIO200) += amplc_dio200_common.o
+obj-$(CONFIG_COMEDI_AMPLC_PC236) += amplc_pc236_common.o
obj-$(CONFIG_COMEDI_DAS08) += das08.o
obj-$(CONFIG_COMEDI_FC) += comedi_fc.o
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
index dc87df032203..de5843ab01ae 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -157,14 +157,10 @@ static int addi_auto_attach(struct comedi_device *dev,
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND
| SDF_DIFF;
- if (devpriv->s_EeParameters.i_NbrAiChannel) {
- s->n_chan =
- devpriv->s_EeParameters.i_NbrAiChannel;
- devpriv->b_SingelDiff = 0;
- } else {
+ if (devpriv->s_EeParameters.i_NbrAiChannel)
+ s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel;
+ else
s->n_chan = this_board->i_NbrAiChannelDiff;
- devpriv->b_SingelDiff = 1;
- }
s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
s->len_chanlist = this_board->i_AiChannelList;
s->range_table = this_board->pr_AiRangelist;
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
index 5c6a11c35ded..a7400a25f620 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_common.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -18,25 +18,6 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#define LOWORD(W) (unsigned short)((W) & 0xFFFF)
-#define HIWORD(W) (unsigned short)(((W) >> 16) & 0xFFFF)
-
-#define ADDI_ENABLE 1
-#define ADDI_DISABLE 0
-#define APCI1710_SAVE_INTERRUPT 1
-
-#define ADDIDATA_EEPROM 1
-#define ADDIDATA_NO_EEPROM 0
-#define ADDIDATA_93C76 "93C76"
-#define ADDIDATA_S5920 "S5920"
-
-/* ADDIDATA Enable Disable */
-#define ADDIDATA_ENABLE 1
-#define ADDIDATA_DISABLE 0
-
-/* Structures */
-
-/* structure for the boardtype */
struct addi_board {
const char *pc_DriverName; /* driver name */
int i_IorangeBase1;
@@ -141,7 +122,6 @@ struct addi_private {
unsigned char b_InterruptMode; /* eoc eos or dma */
unsigned char b_EocEosInterrupt; /* Enable disable eoc eos interrupt */
unsigned int ui_EocEosConversionTime;
- unsigned char b_SingelDiff;
unsigned char b_ExttrigEnable; /* To enable or disable external trigger */
/* Pointer to the current process */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
index 28450f65a134..cad33f1a04fe 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -177,8 +177,7 @@ static int apci035_timer_config(struct comedi_device *dev,
/* Disable the hardware trigger */
ui_Command = ui_Command & 0xFFFFF89FUL;
- if (data[4] == ADDIDATA_ENABLE) {
-
+ if (data[4] == 1) {
/* Set the hardware trigger level */
ui_Command = ui_Command | (data[5] << 5);
}
@@ -188,8 +187,7 @@ static int apci035_timer_config(struct comedi_device *dev,
/* Disable the hardware gate */
ui_Command = ui_Command & 0xFFFFF87FUL;
- if (data[6] == ADDIDATA_ENABLE) {
-
+ if (data[6] == 1) {
/* Set the hardware gate level */
ui_Command = ui_Command | (data[7] << 7);
}
@@ -203,8 +201,7 @@ static int apci035_timer_config(struct comedi_device *dev,
/* Set the hardware output level */
ui_Command = ui_Command | (data[8] << 2);
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
- if (data[9] == ADDIDATA_ENABLE) {
-
+ if (data[9] == 1) {
/* Set the reload value */
outl(data[11],
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
index a633957890d7..1e2fe66818e4 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -872,7 +872,8 @@ static int apci1500_do_write(struct comedi_device *dev,
break;
default:
- comedi_error(dev, " chan spec wrong");
+ dev_err(dev->class_dev,
+ "chan spec wrong\n");
return -EINVAL; /* "sorry channel spec wrong " */
} /* switch(ui_NoOfChannels) */
@@ -950,8 +951,8 @@ static int apci1500_do_write(struct comedi_device *dev,
break;
default:
- comedi_error(dev,
- " chan spec wrong");
+ dev_err(dev->class_dev,
+ "chan spec wrong\n");
return -EINVAL; /* "sorry channel spec wrong " */
} /* switch(ui_NoOfChannels) */
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index 0ba5385226ae..8a613ae0acba 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -21,17 +21,15 @@
*
*/
-#include "../addi_watchdog.h"
-
#define APCI1564_ADDRESS_RANGE 128
/* Digital Input IRQ Function Selection */
-#define ADDIDATA_OR 0
-#define ADDIDATA_AND 1
+#define APCI1564_DI_INT_OR (0 << 1)
+#define APCI1564_DI_INT_AND (1 << 1)
/* Digital Input Interrupt Enable Disable. */
-#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
-#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb
+#define APCI1564_DI_INT_ENABLE 0x4
+#define APCI1564_DI_INT_DISABLE 0xfffffffb
/* Digital Output Interrupt Enable Disable. */
#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
@@ -49,7 +47,7 @@
#define APCI1564_COUNTER4 3
/*
- * devpriv->i_IobaseAmcc Register Map
+ * devpriv->amcc_iobase Register Map
*/
#define APCI1564_DI_REG 0x04
#define APCI1564_DI_INT_MODE1_REG 0x08
@@ -89,46 +87,6 @@
#define APCI1564_TCW_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20))
#define APCI1564_TCW_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20))
-/* Global variables */
-static unsigned int ui_InterruptStatus_1564;
-static unsigned int ui_InterruptData, ui_Type;
-
-/*
- * Configures the digital input Subdevice
- *
- * data[0] 1 = Enable interrupt, 0 = Disable interrupt
- * data[1] 0 = ADDIDATA Interrupt OR LOGIC, 1 = ADDIDATA Interrupt AND LOGIC
- * data[2] Interrupt mask for the mode 1
- * data[3] Interrupt mask for the mode 2
- */
-static int apci1564_di_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct addi_private *devpriv = dev->private;
-
- devpriv->tsk_Current = current;
-
- /* Set the digital input logic */
- if (data[0] == ADDIDATA_ENABLE) {
- data[2] = data[2] << 4;
- data[3] = data[3] << 4;
- outl(data[2], devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
- outl(data[3], devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
- if (data[1] == ADDIDATA_OR)
- outl(0x4, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- else
- outl(0x6, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- } else {
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- }
-
- return insn->n;
-}
-
/*
* Configures The Digital Output Subdevice.
*
@@ -140,33 +98,26 @@ static int apci1564_do_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command = 0;
if ((data[0] != 0) && (data[0] != 1)) {
- comedi_error(dev,
- "Not a valid Data !!! ,Data should be 1 or 0\n");
+ dev_err(dev->class_dev, "Data should be 1 or 0\n");
return -EINVAL;
}
- if (data[0])
- devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
- else
- devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
-
- if (data[1] == ADDIDATA_ENABLE)
+ if (data[1] == 1)
ul_Command = ul_Command | 0x1;
else
ul_Command = ul_Command & 0xFFFFFFFE;
- if (data[2] == ADDIDATA_ENABLE)
+ if (data[2] == 1)
ul_Command = ul_Command | 0x2;
else
ul_Command = ul_Command & 0xFFFFFFFD;
- outl(ul_Command, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
- ui_InterruptData = inl(devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
- devpriv->tsk_Current = current;
+ outl(ul_Command, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
+ devpriv->tsk_current = current;
return insn->n;
}
@@ -186,31 +137,31 @@ static int apci1564_timer_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
- devpriv->tsk_Current = current;
+ devpriv->tsk_current = current;
if (data[0] == ADDIDATA_WATCHDOG) {
- devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+ devpriv->timer_select_mode = ADDIDATA_WATCHDOG;
/* Disable the watchdog */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
/* Loading the Reload value */
- outl(data[3], devpriv->i_IobaseAmcc + APCI1564_WDOG_RELOAD_REG);
+ outl(data[3], devpriv->amcc_iobase + APCI1564_WDOG_RELOAD_REG);
} else if (data[0] == ADDIDATA_TIMER) {
/* First Stop The Timer */
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
/* Stop The Timer */
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
- devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+ devpriv->timer_select_mode = ADDIDATA_TIMER;
if (data[1] == 1) {
/* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */
- outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_IRQ_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_IRQ_REG);
+ outl(0x02, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG);
outl(0x0,
dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1));
outl(0x0,
@@ -221,22 +172,22 @@ static int apci1564_timer_config(struct comedi_device *dev,
dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4));
} else {
/* disable Timer interrupt */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
}
/* Loading Timebase */
- outl(data[2], devpriv->i_IobaseAmcc + APCI1564_TIMER_TIMEBASE_REG);
+ outl(data[2], devpriv->amcc_iobase + APCI1564_TIMER_TIMEBASE_REG);
/* Loading the Reload value */
- outl(data[3], devpriv->i_IobaseAmcc + APCI1564_TIMER_RELOAD_REG);
+ outl(data[3], devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG);
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
/* mode 2 */
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
} else if (data[0] == ADDIDATA_COUNTER) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- devpriv->b_ModeSelectRegister = data[5];
+ devpriv->timer_select_mode = ADDIDATA_COUNTER;
+ devpriv->mode_select_register = data[5];
/* First Stop The Counter */
ul_Command1 = inl(dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1));
@@ -285,45 +236,45 @@ static int apci1564_timer_write(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
- if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) {
switch (data[1]) {
case 0: /* stop the watchdog */
/* disable the watchdog */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
break;
case 1: /* start the watchdog */
- outl(0x0001, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0001, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
break;
case 2: /* Software trigger */
- outl(0x0201, devpriv->i_IobaseAmcc + APCI1564_WDOG_CTRL_REG);
+ outl(0x0201, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG);
break;
default:
dev_err(dev->class_dev, "Specified functionality does not exist.\n");
return -EINVAL;
}
}
- if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ if (devpriv->timer_select_mode == ADDIDATA_TIMER) {
if (data[1] == 1) {
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
/* Enable the Timer */
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
} else if (data[1] == 0) {
/* Stop The Timer */
- ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
- outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
+ outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
}
}
- if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
ul_Command1 =
inl(dev->iobase +
- APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1));
if (data[1] == 1) {
/* Start the Counter subdevice */
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
@@ -336,7 +287,7 @@ static int apci1564_timer_write(struct comedi_device *dev,
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
}
outl(ul_Command1, dev->iobase +
- APCI1564_TCW_CTRL_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1));
}
return insn->n;
}
@@ -349,27 +300,27 @@ static int apci1564_timer_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
unsigned int ul_Command1 = 0;
- if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) {
/* Stores the status of the Watchdog */
- data[0] = inl(devpriv->i_IobaseAmcc + APCI1564_WDOG_STATUS_REG) & 0x1;
- data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_WDOG_REG);
- } else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ data[0] = inl(devpriv->amcc_iobase + APCI1564_WDOG_STATUS_REG) & 0x1;
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_WDOG_REG);
+ } else if (devpriv->timer_select_mode == ADDIDATA_TIMER) {
/* Stores the status of the Timer */
- data[0] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_STATUS_REG) & 0x1;
+ data[0] = inl(devpriv->amcc_iobase + APCI1564_TIMER_STATUS_REG) & 0x1;
/* Stores the Actual value of the Timer */
- data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_REG);
- } else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_TIMER_REG);
+ } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) {
/* Read the Counter Actual Value. */
data[0] =
inl(dev->iobase +
- APCI1564_TCW_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_REG(devpriv->mode_select_register - 1));
ul_Command1 =
inl(dev->iobase +
- APCI1564_TCW_STATUS_REG(devpriv->b_ModeSelectRegister - 1));
+ APCI1564_TCW_STATUS_REG(devpriv->mode_select_register - 1));
/* Get the software trigger status */
data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
@@ -382,170 +333,10 @@ static int apci1564_timer_read(struct comedi_device *dev,
/* Get the overflow status */
data[4] = (unsigned char) ((ul_Command1 >> 0) & 1);
- } else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
- && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
- && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
+ } else if ((devpriv->timer_select_mode != ADDIDATA_TIMER)
+ && (devpriv->timer_select_mode != ADDIDATA_WATCHDOG)
+ && (devpriv->timer_select_mode != ADDIDATA_COUNTER)) {
dev_err(dev->class_dev, "Invalid Subdevice!\n");
}
return insn->n;
}
-
-/*
- * Reads the interrupt status register
- */
-static int apci1564_do_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- *data = ui_Type;
- return insn->n;
-}
-
-/*
- * Interrupt handler for the interruptible digital inputs
- */
-static void apci1564_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct addi_private *devpriv = dev->private;
- unsigned int ui_DO, ui_DI;
- unsigned int ui_Timer;
- unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
- unsigned int ul_Command2 = 0;
-
- ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG) & 0x01;
- ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DO_IRQ_REG) & 0x01;
- ui_Timer = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_IRQ_REG) & 0x01;
- ui_C1 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
- ui_C2 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
- ui_C3 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
- ui_C4 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
- if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
- && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
- dev_err(dev->class_dev, "Interrupt from unknown source.\n");
- }
-
- if (ui_DI == 1) {
- ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- ui_InterruptStatus_1564 =
- inl(devpriv->i_IobaseAmcc + APCI1564_DI_INT_STATUS_REG);
- ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
- /* send signal to the sample */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- /* enable the interrupt */
- outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- return;
- }
-
- if (ui_DO == 1) {
- /* Check for Digital Output interrupt Type */
- /* 1: VCC interrupt */
- /* 2: CC interrupt */
- ui_Type = inl(devpriv->i_IobaseAmcc + APCI1564_DO_INT_STATUS_REG) & 0x3;
- /* Disable the Interrupt */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
-
- /* Sends signal to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
- }
-
- if (ui_Timer == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Timer Interrupt */
- ul_Command2 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Timer Interrupt */
-
- outl(ul_Command2, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- }
- }
-
- if (ui_C1 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- }
- }
-
- if (ui_C2 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- }
- }
-
- if (ui_C3 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- }
- }
-
- if (ui_C4 == 1) {
- devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
- if (devpriv->b_TimerSelectMode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_Current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- }
- }
- return;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
index 764c8f17f8fa..77cee876a374 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -270,7 +270,7 @@ static int apci3120_ai_insn_config(struct comedi_device *dev,
if (CR_CHAN(data[4 + i]) >=
this_board->i_NbrAiChannel) {
- printk("bad channel list\n");
+ dev_err(dev->class_dev, "bad channel list\n");
return -2;
}
}
@@ -318,7 +318,8 @@ static int apci3120_setup_chan_list(struct comedi_device *dev,
/* correct channel and range number check itself comedi/range.c */
if (n_chan < 1) {
if (!check)
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev,
+ "range/channel list is empty!\n");
return 0;
}
/* All is ok, so we can setup channel/range list */
@@ -344,11 +345,6 @@ static int apci3120_setup_chan_list(struct comedi_device *dev,
us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */
us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */
outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
-
- printk("\n Gain = %i",
- (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
- printk("\n Channel = %i", CR_CHAN(chanlist[i]));
- printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
}
return 1; /* we can serve this with scan logic */
}
@@ -369,10 +365,9 @@ static int apci3120_ai_insn_read(struct comedi_device *dev,
unsigned char b_Tmp;
/* fix conversion time to 10 us */
- if (!devpriv->ui_EocEosConversionTime) {
- printk("No timer0 Value using 10 us\n");
+ if (!devpriv->ui_EocEosConversionTime)
us_ConvertTiming = 10;
- } else
+ else
us_ConvertTiming = (unsigned short) (devpriv->ui_EocEosConversionTime / 1000); /* nano to useconds */
/* this_board->ai_read(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]); */
@@ -593,7 +588,7 @@ static int apci3120_ai_insn_read(struct comedi_device *dev,
break;
default:
- printk("inputs wrong\n");
+ dev_err(dev->class_dev, "inputs wrong\n");
}
devpriv->ui_EocEosConversionTime = 0; /* re initializing the variable; */
@@ -1051,7 +1046,7 @@ static int apci3120_cyclic_ai(int mode,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_TimerValue2),
+ outw(ui_TimerValue2 & 0xffff,
dev->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -1059,7 +1054,7 @@ static int apci3120_cyclic_ai(int mode,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_TimerValue2),
+ outw((ui_TimerValue2 >> 16) & 0xffff,
dev->iobase + APCI3120_TIMER_VALUE);
/* (2) Reset FC_TIMER BIT Clearing timer status register */
@@ -1373,10 +1368,10 @@ static void apci3120_interrupt_dma(int irq, void *d)
if (samplesinbuf <
devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
- comedi_error(dev, "Interrupted DMA transfer!");
+ dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
}
if (samplesinbuf & 1) {
- comedi_error(dev, "Odd count of bytes in DMA ring!");
+ dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
apci3120_cancel(dev, s);
return;
}
@@ -1548,7 +1543,7 @@ static void apci3120_interrupt(int irq, void *d)
int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); /* get AMCC int register */
if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) {
- comedi_error(dev, "IRQ from unknown source");
+ dev_err(dev->class_dev, "IRQ from unknown source\n");
return;
}
@@ -1565,9 +1560,9 @@ static void apci3120_interrupt(int irq, void *d)
inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER);
if (int_amcc & MASTER_ABORT_INT)
- comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
if (int_amcc & TARGET_ABORT_INT)
- comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
/* Ckeck if EOC interrupt */
if (((int_daq & 0x8) == 0)
@@ -1740,7 +1735,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
unsigned char b_Tmp;
if (!data[1])
- comedi_error(dev, "config:No timer constant !");
+ dev_err(dev->class_dev, "No timer constant!\n");
devpriv->b_Timer2Interrupt = (unsigned char) data[2]; /* save info whether to enable or disable interrupt */
@@ -1805,7 +1800,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_Timervalue2),
+ outw(ui_Timervalue2 & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -1813,7 +1808,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_Timervalue2),
+ outw((ui_Timervalue2 >> 16) & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* timer2 in Timer mode enabled */
devpriv->b_Timer2Mode = APCI3120_TIMER;
@@ -1841,7 +1836,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
b_DigitalOutputRegister) & 0xF0) |
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_Timervalue2),
+ outw(ui_Timervalue2 & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -1850,7 +1845,7 @@ static int apci3120_config_insn_timer(struct comedi_device *dev,
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_Timervalue2),
+ outw((ui_Timervalue2 >> 16) & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* watchdog enabled */
devpriv->b_Timer2Mode = APCI3120_WATCHDOG;
@@ -1886,14 +1881,14 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
&& (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
- comedi_error(dev, "\nwrite:timer2 not configured ");
+ dev_err(dev->class_dev, "timer2 not configured\n");
return -EINVAL;
}
if (data[0] == 2) { /* write new value */
if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
- comedi_error(dev,
- "write :timer2 not configured in TIMER MODE");
+ dev_err(dev->class_dev,
+ "timer2 not configured in TIMER MODE\n");
return -EINVAL;
}
@@ -1991,8 +1986,8 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
case 2: /* write new value to Timer */
if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
- comedi_error(dev,
- "write :timer2 not configured in TIMER MODE");
+ dev_err(dev->class_dev,
+ "timer2 not configured in TIMER MODE\n");
return -EINVAL;
}
/* ui_Timervalue2=data[1]; // passed as argument */
@@ -2017,7 +2012,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
APCI3120_SELECT_TIMER_2_LOW_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(LOWORD(ui_Timervalue2),
+ outw(ui_Timervalue2 & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
/* Writing HIGH unsigned short */
@@ -2026,7 +2021,7 @@ static int apci3120_write_insn_timer(struct comedi_device *dev,
APCI3120_SELECT_TIMER_2_HIGH_WORD;
outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
- outw(HIWORD(ui_Timervalue2),
+ outw((ui_Timervalue2 >> 16) & 0xffff,
devpriv->iobase + APCI3120_TIMER_VALUE);
break;
@@ -2056,7 +2051,7 @@ static int apci3120_read_insn_timer(struct comedi_device *dev,
if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
&& (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
- comedi_error(dev, "\nread:timer2 not configured ");
+ dev_err(dev->class_dev, "timer2 not configured\n");
}
/* this_board->timer_read(dev,data); */
@@ -2161,10 +2156,6 @@ static int apci3120_ao_insn_write(struct comedi_device *dev,
}
-/*
- * out put n values at the given channel. printk("\nwaiting for
- * DA_READY BIT");
- */
do { /* Waiting of DA_READY BIT */
us_TmpValue =
((unsigned short) inw(devpriv->iobase +
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index f540394d17b0..5e321f91172f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -47,8 +47,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
+----------+-----------+------------------------------------------------+
*/
-/* #define PRINT_INFO */
-
/* Card Specific information */
/* #define APCI3200_ADDRESS_RANGE 264 */
@@ -455,12 +453,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
BoardInformations->s_Module[w_ModulCounter].
w_GainValue[w_GainIndex] = w_GainValue;
-# ifdef PRINT_INFO
- printk("\n Gain value = %d",
- BoardInformations->s_Module[w_ModulCounter].
- w_GainValue[w_GainIndex]);
-# endif
-
/*************************************/
/** Read gain factor for the module **/
/*************************************/
@@ -472,12 +464,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
ul_GainFactor[w_GainIndex] =
(w_GainFactorValue[1] << 16) +
w_GainFactorValue[0];
-
-# ifdef PRINT_INFO
- printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
- BoardInformations->s_Module[w_ModulCounter].
- ul_GainFactor[w_GainIndex]);
-# endif
}
/***************************************************************/
@@ -499,12 +485,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
ul_CurrentSource[w_Input] =
(w_CurrentSources[0] +
((w_CurrentSources[1] & 0xFFF) << 16));
-
-# ifdef PRINT_INFO
- printk("\n Current sources [%d] = %lu", w_Input,
- BoardInformations->s_Module[w_ModulCounter].
- ul_CurrentSource[w_Input]);
-# endif
}
/***************************************/
@@ -522,12 +502,6 @@ static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAd
ul_CurrentSourceCJC =
(w_CurrentSources[0] +
((w_CurrentSources[1] & 0xFFF) << 16));
-
-# ifdef PRINT_INFO
- printk("\n Current sources CJC = %lu",
- BoardInformations->s_Module[w_ModulCounter].
- ul_CurrentSourceCJC);
-# endif
}
}
@@ -540,10 +514,6 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
int i_DiffChannel = 0;
int i_Module = 0;
-#ifdef PRINT_INFO
- printk("\n Channel = %u", ui_Channel_num);
-#endif
-
/* Test if single or differential mode */
if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
/* if diff */
@@ -580,16 +550,10 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
/* Test if thermocouple or RTD mode */
*CJCCurrentSource =
s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
-#ifdef PRINT_INFO
- printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
-#endif
*ChannelCurrentSource =
s_BoardInfos[dev->minor].s_Module[i_Module].
ul_CurrentSource[i_DiffChannel];
-#ifdef PRINT_INFO
- printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
-#endif
/* } */
/* } */
@@ -597,9 +561,6 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
*ChannelGainFactor =
s_BoardInfos[dev->minor].s_Module[i_Module].
ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
-#ifdef PRINT_INFO
- printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
-#endif
/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
return 0;
@@ -689,17 +650,11 @@ static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /************************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/* Enable the interrupt */
- /************************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
- } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
+ }
/******************************/
/* Write the command register */
@@ -712,11 +667,8 @@ static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*************************/
/*Read the EOC Status bit */
@@ -738,7 +690,7 @@ static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
s_BoardInfos[dev->minor].i_Offset + 28);
/* END JK 06.07.04: Management of sevrals boards */
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -800,20 +752,11 @@ static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
-
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
-
ui_CommandRegister = ui_CommandRegister | 0x00100000;
-
- } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
+ }
/**********************/
/*Start the conversion */
@@ -830,13 +773,8 @@ static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
-
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
-
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
/*Read the EOC flag */
@@ -856,7 +794,7 @@ static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -915,20 +853,11 @@ static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
-
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
-
ui_CommandRegister = ui_CommandRegister | 0x00100000;
-
- } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
+ }
/**********************/
/*Start the conversion */
@@ -945,13 +874,8 @@ static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
-
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
-
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
@@ -973,7 +897,7 @@ static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1020,14 +944,9 @@ static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
/*Initialise dw_CommandRegister */
/*******************************/
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
}
@@ -1047,12 +966,8 @@ static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /*****************************/
/*Test if interrupt is enable */
- /*****************************/
-
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
@@ -1073,8 +988,7 @@ static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
-
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1128,17 +1042,10 @@ static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
/*Initialise ui_CommandRegister */
/*******************************/
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
-
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
-
}
/**********************/
@@ -1154,8 +1061,7 @@ static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
/* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
/*Read the EOC flag */
@@ -1172,7 +1078,7 @@ static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1224,14 +1130,9 @@ static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
/*Initialise dw_CommandRegister */
/*******************************/
ui_CommandRegister = 0;
- /*********************************/
/*Test if the interrupt is enable */
- /*********************************/
- /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
- /**********************/
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
/*Enable the interrupt */
- /**********************/
ui_CommandRegister = ui_CommandRegister | 0x00100000;
}
/**********************/
@@ -1247,8 +1148,7 @@ static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
/* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */
outl(ui_CommandRegister,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
- /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
- if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
do {
/*******************/
/*Read the EOC flag */
@@ -1264,7 +1164,7 @@ static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
data[0] =
inl(devpriv->iobase +
s_BoardInfos[dev->minor].i_Offset + 28);
- } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
+ }
return 0;
}
@@ -1340,10 +1240,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
return -EINVAL;
} /* if(i_Initialised==0); */
-#ifdef PRINT_INFO
- printk("\n insn->unused[0] = %i", insn->unused[0]);
-#endif
-
switch (insn->unused[0]) {
case 0:
@@ -1368,15 +1264,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
&s_BoardInfos[dev->minor].
ui_InterruptChannelValue[s_BoardInfos[dev->minor].
i_Count + 8]);
-
-#ifdef PRINT_INFO
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
-
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
-
- printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
-#endif
-
/* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
/* BEGIN JK 06.07.04: Management of sevrals boards */
@@ -1532,9 +1419,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
data[4]= ui_InterruptChannelValue[4];
data[5]= ui_InterruptChannelValue[5];
*/
-#ifdef PRINT_INFO
- printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
-#endif
data[0] =
s_BoardInfos[dev->minor].
ui_InterruptChannelValue[0];
@@ -1555,7 +1439,6 @@ static int apci3200_ai_read(struct comedi_device *dev,
ui_InterruptChannelValue[5];
/* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
- /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */
i_APCI3200_GetChannelCalibrationValue(dev,
s_BoardInfos[dev->minor].ui_Channel_num,
&data[6], &data[7], &data[8]);
@@ -1637,13 +1520,6 @@ static int apci3200_ai_config(struct comedi_device *dev,
unsigned int ui_Dummy = 0;
int i_err = 0;
- /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
-#ifdef PRINT_INFO
- int i = 0, i2 = 0;
-#endif
- /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
-
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* Initialize the structure */
if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
@@ -1669,29 +1545,6 @@ static int apci3200_ai_config(struct comedi_device *dev,
v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
&s_BoardInfos[dev->minor]);
-
-#ifdef PRINT_INFO
- for (i = 0; i < MAX_MODULE; i++) {
- printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
- s_BoardInfos[dev->minor].s_Module[i].
- ul_CurrentSourceCJC);
-
- for (i2 = 0; i2 < 5; i2++) {
- printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
- }
-
- for (i2 = 0; i2 < 8; i2++) {
- printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
- }
-
- for (i2 = 0; i2 < 8; i2++) {
- printk("\n s_Module[%i].w_GainValue [%i] = %u",
- i, i2,
- s_BoardInfos[dev->minor].s_Module[i].
- w_GainValue[i2]);
- }
- }
-#endif
/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
}
@@ -1811,34 +1664,34 @@ static int apci3200_ai_config(struct comedi_device *dev,
/* END JK 06.07.04: Management of sevrals boards */
if (data[5] == 0) {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+ if (ui_ChannelNo > 15) {
printk("\nThe Selection of the channel is in error\n");
i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */
+ } /* if(ui_ChannelNo>15) */
} /* if(data[5]==0) */
else {
if (data[14] == 2) {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+ if (ui_ChannelNo > 3) {
printk("\nThe Selection of the channel is in error\n");
i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */
+ } /* if(ui_ChannelNo>3) */
} /* if(data[14]==2) */
else {
- if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+ if (ui_ChannelNo > 7) {
printk("\nThe Selection of the channel is in error\n");
i_err++;
- } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */
+ } /* if(ui_ChannelNo>7) */
} /* elseif(data[14]==2) */
} /* elseif(data[5]==0) */
if (data[12] == 0 || data[12] == 1) {
switch (data[5]) {
case 0:
- if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+ if (ui_ChannelNo <= 3) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_Offset=0; */
s_BoardInfos[dev->minor].i_Offset = 0;
/* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */
+ } /* if(ui_ChannelNo <=3) */
if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_Offset=64; */
@@ -1892,12 +1745,12 @@ static int apci3200_ai_config(struct comedi_device *dev,
ui_ChannelNo = 0;
break;
} /* if(data[14]==2) */
- if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+ if (ui_ChannelNo <= 1) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_Offset=0; */
s_BoardInfos[dev->minor].i_Offset = 0;
/* END JK 06.07.04: Management of sevrals boards */
- } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */
+ } /* if(ui_ChannelNo <=1) */
if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
/* BEGIN JK 06.07.04: Management of sevrals boards */
/* i_ChannelNo=i_ChannelNo-2; */
@@ -2136,8 +1989,7 @@ static int apci3200_ai_bits_test(struct comedi_device *dev,
i_ADDIDATAConversionTimeUnit= 1; */
/* i_Temp= i_InterruptFlag ; */
i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
- /* i_InterruptFlag = ADDIDATA_DISABLE; */
- s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
/* if(i_AutoCalibration == FALSE) */
if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
@@ -2176,8 +2028,7 @@ static int apci3200_ai_bits_test(struct comedi_device *dev,
i_ADDIDATAConversionTimeUnit= 1; */
/* i_Temp= i_InterruptFlag ; */
i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
- /* i_InterruptFlag = ADDIDATA_DISABLE; */
- s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
/* if(i_AutoCalibration == FALSE) */
if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
@@ -2198,7 +2049,6 @@ static int apci3200_ai_bits_test(struct comedi_device *dev,
}
/* i_InterruptFlag=i_Temp ; */
s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
- /* printk("\ni_InterruptFlag=%d\n",i_InterruptFlag); */
return insn->n;
}
@@ -2470,8 +2320,6 @@ static int apci3200_ai_cmd(struct comedi_device *dev,
ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
ui_DelayMode = 1;
} /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */
- /* printk("\nui_DelayTime=%u\n",ui_DelayTime); */
- /* printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase); */
if (cmd->convert_src == TRIG_TIMER) {
ui_ConvertTime = cmd->convert_arg & 0xFFFF;
ui_ConvertTimeBase = cmd->convert_arg >> 16;
@@ -2499,13 +2347,6 @@ static int apci3200_ai_cmd(struct comedi_device *dev,
devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
/* } */
ui_Configuration = 0;
- /* printk("\nfirstchannel=%u\n",i_FirstChannel); */
- /* printk("\nlastchannel=%u\n",i_LastChannel); */
- /* printk("\nui_Trigger=%u\n",ui_Trigger); */
- /* printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge); */
- /* printk("\nui_Triggermode=%u\n",ui_Triggermode); */
- /* printk("\nui_DelayMode=%u\n",ui_DelayMode); */
- /* printk("\nui_ScanMode=%u\n",ui_ScanMode); */
/* ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 | */
ui_Configuration =
@@ -2757,8 +2598,6 @@ static void apci3200_interrupt(int irq, void *d)
int i_ReturnValue = 0;
/* END JK TEST */
- /* printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType); */
-
/* switch(i_ScanType) */
switch (s_BoardInfos[dev->minor].i_ScanType) {
case 0:
@@ -2809,7 +2648,6 @@ static void apci3200_interrupt(int irq, void *d)
/* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
/*
- printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
&s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
&s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
index 4da9db35b8e2..af70c8401880 100644
--- a/drivers/staging/comedi/drivers/addi_apci_035.c
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -18,7 +18,7 @@ static const struct addi_board apci035_boardtypes[] = {
.pc_DriverName = "apci035",
.i_IorangeBase1 = APCI035_ADDRESS_RANGE,
.i_PCIEeprom = 1,
- .pc_EepromChip = ADDIDATA_S5920,
+ .pc_EepromChip = "S5920",
.i_NbrAiChannel = 16,
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 16,
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index eab75eb26478..b7a284ac6649 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -15,7 +15,7 @@ static const struct addi_board apci1500_boardtypes[] = {
{
.pc_DriverName = "apci1500",
.i_IorangeBase1 = APCI1500_ADDRESS_RANGE,
- .i_PCIEeprom = ADDIDATA_NO_EEPROM,
+ .i_PCIEeprom = 0,
.i_NbrDiChannel = 16,
.i_NbrDoChannel = 16,
.i_DoMaxdata = 0xffff,
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
index 13d9962b47ec..543cb074213a 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1564.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -1,17 +1,114 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include "../comedidev.h"
#include "comedi_fc.h"
-
-#include "addi-data/addi_common.h"
+#include "amcc_s5933.h"
+#include "addi_watchdog.h"
+
+struct apci1564_private {
+ unsigned int amcc_iobase; /* base of AMCC I/O registers */
+ unsigned int mode1; /* riding-edge/high level channels */
+ unsigned int mode2; /* falling-edge/low level channels */
+ unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */
+ unsigned char timer_select_mode;
+ unsigned char mode_select_register;
+ struct task_struct *tsk_current;
+};
#include "addi-data/hwdrv_apci1564.c"
-static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+static int apci1564_reset(struct comedi_device *dev)
{
- apci1564_interrupt(irq, d);
- return IRQ_RETVAL(1);
+ struct apci1564_private *devpriv = dev->private;
+
+ /* Disable the input interrupts and reset status register */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
+
+ /* Reset the output channels and disable interrupts */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
+
+ /* Reset the watchdog registers */
+ addi_watchdog_reset(devpriv->amcc_iobase + APCI1564_WDOG_REG);
+
+ /* Reset the timer registers */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_RELOAD_REG);
+
+ /* Reset the counter registers */
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+
+ return 0;
+}
+
+static irqreturn_t apci1564_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct apci1564_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
+ unsigned int status;
+ unsigned int ctrl;
+ unsigned int chan;
+
+ /* check interrupt is from this device */
+ if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
+ INTCSR_INTR_ASSERTED) == 0)
+ return IRQ_NONE;
+
+ status = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ if (status & APCI1564_DI_INT_ENABLE) {
+ /* disable the interrupt */
+ outl(status & APCI1564_DI_INT_DISABLE,
+ devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+
+ s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG)
+ & 0xffff;
+ comedi_buf_put(s, s->state);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+
+ /* enable the interrupt */
+ outl(status, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ }
+
+ status = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG);
+ if (status & 0x01) {
+ /* Disable Timer Interrupt */
+ ctrl = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Timer Interrupt */
+ outl(ctrl, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ }
+
+ for (chan = 0; chan < 4; chan++) {
+ status = inl(dev->iobase + APCI1564_TCW_IRQ_REG(chan));
+ if (status & 0x01) {
+ /* Disable Counter Interrupt */
+ ctrl = inl(dev->iobase + APCI1564_TCW_CTRL_REG(chan));
+ outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(chan));
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Counter Interrupt */
+ outl(ctrl, dev->iobase + APCI1564_TCW_CTRL_REG(chan));
+ }
+ }
+
+ return IRQ_HANDLED;
}
static int apci1564_di_insn_bits(struct comedi_device *dev,
@@ -19,9 +116,9 @@ static int apci1564_di_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
- data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DI_REG);
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_DI_REG);
return insn->n;
}
@@ -31,46 +128,214 @@ static int apci1564_do_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
- s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DO_REG);
+ s->state = inl(devpriv->amcc_iobase + APCI1564_DO_REG);
if (comedi_dio_update_state(s, data))
- outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
+ outl(s->state, devpriv->amcc_iobase + APCI1564_DO_REG);
data[1] = s->state;
return insn->n;
}
-static int apci1564_reset(struct comedi_device *dev)
+static int apci1564_diag_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct addi_private *devpriv = dev->private;
+ struct apci1564_private *devpriv = dev->private;
- ui_Type = 0;
+ data[1] = inl(devpriv->amcc_iobase + APCI1564_DO_INT_STATUS_REG) & 3;
- /* Disable the input interrupts and reset status register */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_IRQ_REG);
- inl(devpriv->i_IobaseAmcc + APCI1564_DI_INT_STATUS_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE1_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DI_INT_MODE2_REG);
+ return insn->n;
+}
- /* Reset the output channels and disable interrupts */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DO_INT_CTRL_REG);
+/*
+ * Change-Of-State (COS) interrupt configuration
+ *
+ * Channels 0 to 15 are interruptible. These channels can be configured
+ * to generate interrupts based on AND/OR logic for the desired channels.
+ *
+ * OR logic
+ * - reacts to rising or falling edges
+ * - interrupt is generated when any enabled channel
+ * meet the desired interrupt condition
+ *
+ * AND logic
+ * - reacts to changes in level of the selected inputs
+ * - interrupt is generated when all enabled channels
+ * meet the desired interrupt condition
+ * - after an interrupt, a change in level must occur on
+ * the selected inputs to release the IRQ logic
+ *
+ * The COS interrupt must be configured before it can be enabled.
+ *
+ * data[0] : INSN_CONFIG_DIGITAL_TRIG
+ * data[1] : trigger number (= 0)
+ * data[2] : configuration operation:
+ * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
+ * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
+ * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
+ * data[3] : left-shift for data[4] and data[5]
+ * data[4] : rising-edge/high level channels
+ * data[5] : falling-edge/low level channels
+ */
+static int apci1564_cos_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct apci1564_private *devpriv = dev->private;
+ unsigned int shift, oldmask;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIGITAL_TRIG:
+ if (data[1] != 0)
+ return -EINVAL;
+ shift = data[3];
+ oldmask = (1U << shift) - 1;
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ devpriv->ctrl = 0;
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_OR)) {
+ /* switching to 'OR' mode */
+ devpriv->ctrl = APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_OR;
+ /* wipe old channels */
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ } else {
+ /* preserve unspecified channels */
+ devpriv->mode1 &= oldmask;
+ devpriv->mode2 &= oldmask;
+ }
+ /* configure specified channels */
+ devpriv->mode1 |= data[4] << shift;
+ devpriv->mode2 |= data[5] << shift;
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
+ if (devpriv->ctrl != (APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_AND)) {
+ /* switching to 'AND' mode */
+ devpriv->ctrl = APCI1564_DI_INT_ENABLE |
+ APCI1564_DI_INT_AND;
+ /* wipe old channels */
+ devpriv->mode1 = 0;
+ devpriv->mode2 = 0;
+ } else {
+ /* preserve unspecified channels */
+ devpriv->mode1 &= oldmask;
+ devpriv->mode2 &= oldmask;
+ }
+ /* configure specified channels */
+ devpriv->mode1 |= data[4] << shift;
+ devpriv->mode2 |= data[5] << shift;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return insn->n;
+}
- /* Reset the watchdog registers */
- addi_watchdog_reset(devpriv->i_IobaseAmcc + APCI1564_WDOG_REG);
+static int apci1564_cos_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = s->state;
- /* Reset the timer registers */
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER_RELOAD_REG);
+ return 0;
+}
- /* Reset the counter registers */
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+static int apci1564_cos_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);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+ if (err)
+ return 1;
+
+ /* Step 2a : make sure trigger sources are unique */
+ /* 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);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+ if (err)
+ return 3;
+
+ /* step 4: ignored */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/*
+ * Change-Of-State (COS) 'do_cmd' operation
+ *
+ * Enable the COS interrupt as configured by apci1564_cos_insn_config().
+ */
+static int apci1564_cos_cmd(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct apci1564_private *devpriv = dev->private;
+
+ if (!devpriv->ctrl) {
+ dev_warn(dev->class_dev,
+ "Interrupts disabled due to mode configuration!\n");
+ return -EINVAL;
+ }
+
+ outl(devpriv->mode1, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(devpriv->mode2, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
+ outl(devpriv->ctrl, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+
+ return 0;
+}
+
+static int apci1564_cos_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct apci1564_private *devpriv = dev->private;
+
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ inl(devpriv->amcc_iobase + APCI1564_DI_INT_STATUS_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE1_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DI_INT_MODE2_REG);
return 0;
}
@@ -79,12 +344,10 @@ static int apci1564_auto_attach(struct comedi_device *dev,
unsigned long context_unused)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- struct addi_private *devpriv;
+ struct apci1564_private *devpriv;
struct comedi_subdevice *s;
int ret;
- dev->board_name = dev->driver->driver_name;
-
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
@@ -94,18 +357,18 @@ static int apci1564_auto_attach(struct comedi_device *dev,
return ret;
dev->iobase = pci_resource_start(pcidev, 1);
- devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
+ devpriv->amcc_iobase = pci_resource_start(pcidev, 0);
apci1564_reset(dev);
if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ ret = request_irq(pcidev->irq, apci1564_interrupt, IRQF_SHARED,
dev->board_name, dev);
if (ret == 0)
dev->irq = pcidev->irq;
}
- ret = comedi_alloc_subdevices(dev, 3);
+ ret = comedi_alloc_subdevices(dev, 6);
if (ret)
return ret;
@@ -115,9 +378,7 @@ static int apci1564_auto_attach(struct comedi_device *dev,
s->subdev_flags = SDF_READABLE;
s->n_chan = 32;
s->maxdata = 1;
- s->len_chanlist = 32;
s->range_table = &range_digital;
- s->insn_config = apci1564_di_config;
s->insn_bits = apci1564_di_insn_bits;
/* Allocate and Initialise DO Subdevice Structures */
@@ -125,15 +386,32 @@ static int apci1564_auto_attach(struct comedi_device *dev,
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITEABLE;
s->n_chan = 32;
- s->maxdata = 0xffffffff;
- s->len_chanlist = 32;
+ s->maxdata = 1;
s->range_table = &range_digital;
s->insn_config = apci1564_do_config;
s->insn_bits = apci1564_do_insn_bits;
- s->insn_read = apci1564_do_read;
- /* Allocate and Initialise Timer Subdevice Structures */
+ /* Change-Of-State (COS) interrupt subdevice */
s = &dev->subdevices[2];
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->len_chanlist = 1;
+ s->insn_config = apci1564_cos_insn_config;
+ s->insn_bits = apci1564_cos_insn_bits;
+ s->do_cmdtest = apci1564_cos_cmdtest;
+ s->do_cmd = apci1564_cos_cmd;
+ s->cancel = apci1564_cos_cancel;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Allocate and Initialise Timer Subdevice Structures */
+ s = &dev->subdevices[3];
s->type = COMEDI_SUBD_TIMER;
s->subdev_flags = SDF_WRITEABLE;
s->n_chan = 1;
@@ -144,19 +422,30 @@ static int apci1564_auto_attach(struct comedi_device *dev,
s->insn_read = apci1564_timer_read;
s->insn_config = apci1564_timer_config;
+ /* Initialize the watchdog subdevice */
+ s = &dev->subdevices[4];
+ ret = addi_watchdog_init(s, devpriv->amcc_iobase + APCI1564_WDOG_REG);
+ if (ret)
+ return ret;
+
+ /* Initialize the diagnostic status subdevice */
+ s = &dev->subdevices[5];
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 2;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = apci1564_diag_insn_bits;
+
return 0;
}
static void apci1564_detach(struct comedi_device *dev)
{
- struct addi_private *devpriv = dev->private;
-
- if (devpriv) {
- if (dev->iobase)
- apci1564_reset(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- }
+ if (dev->iobase)
+ apci1564_reset(dev);
+ if (dev->irq)
+ free_irq(dev->irq, dev);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
index 0cfb12fa1cbc..0b77f1012d47 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3120.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -88,7 +88,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
dev->irq = pcidev->irq;
}
- devpriv->us_UseDma = ADDI_ENABLE;
+ devpriv->us_UseDma = 1;
/* Allocate DMA buffers */
devpriv->b_DmaDoubleBuffer = 0;
@@ -109,7 +109,7 @@ static int apci3120_auto_attach(struct comedi_device *dev,
}
}
if (!devpriv->ul_DmaBufferVirtual[0])
- devpriv->us_UseDma = ADDI_DISABLE;
+ devpriv->us_UseDma = 0;
if (devpriv->ul_DmaBufferVirtual[1])
devpriv->b_DmaDoubleBuffer = 1;
@@ -125,13 +125,10 @@ static int apci3120_auto_attach(struct comedi_device *dev,
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND
| SDF_DIFF;
- if (this_board->i_NbrAiChannel) {
+ if (this_board->i_NbrAiChannel)
s->n_chan = this_board->i_NbrAiChannel;
- devpriv->b_SingelDiff = 0;
- } else {
+ else
s->n_chan = this_board->i_NbrAiChannelDiff;
- devpriv->b_SingelDiff = 1;
- }
s->maxdata = this_board->i_AiMaxdata;
s->len_chanlist = this_board->i_AiChannelList;
s->range_table = &range_apci3120_ai;
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
index f0f891a482a3..fe6897eff3db 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -32,8 +32,8 @@ static const struct addi_board apci3200_boardtypes[] = {
[BOARD_APCI3200] = {
.pc_DriverName = "apci3200",
.i_IorangeBase1 = 256,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
+ .i_PCIEeprom = 1,
+ .pc_EepromChip = "S5920",
.i_NbrAiChannel = 16,
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 16,
@@ -58,8 +58,8 @@ static const struct addi_board apci3200_boardtypes[] = {
[BOARD_APCI3300] = {
.pc_DriverName = "apci3300",
.i_IorangeBase1 = 256,
- .i_PCIEeprom = ADDIDATA_EEPROM,
- .pc_EepromChip = ADDIDATA_S5920,
+ .i_PCIEeprom = 1,
+ .pc_EepromChip = "S5920",
.i_NbrAiChannelDiff = 8,
.i_AiChannelList = 8,
.i_AiMaxdata = 0x3ffff,
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index 49bf1fb840f6..d9594f48d00f 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -274,7 +274,7 @@ static irqreturn_t apci3501_interrupt(int irq, void *d)
ui_Timer_AOWatchdog = inl(dev->iobase + APCI3501_TIMER_IRQ_REG) & 0x1;
if ((!ui_Timer_AOWatchdog)) {
- comedi_error(dev, "IRQ from unknown source");
+ dev_err(dev->class_dev, "IRQ from unknown source\n");
return IRQ_NONE;
}
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index 0532b6cc40e3..0f0c7fa5daa3 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -353,7 +353,6 @@ static const struct apci3xxx_boardinfo apci3xxx_boardtypes[] = {
};
struct apci3xxx_private {
- void __iomem *mmio;
unsigned int ai_timer;
unsigned char ai_time_base;
};
@@ -361,18 +360,17 @@ struct apci3xxx_private {
static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
{
struct comedi_device *dev = d;
- struct apci3xxx_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
unsigned int val;
/* Test if interrupt occur */
- status = readl(devpriv->mmio + 16);
+ status = readl(dev->mmio + 16);
if ((status & 0x2) == 0x2) {
/* Reset the interrupt */
- writel(status, devpriv->mmio + 16);
+ writel(status, dev->mmio + 16);
- val = readl(devpriv->mmio + 28);
+ val = readl(dev->mmio + 28);
comedi_buf_put(s, val);
s->async->events |= COMEDI_CB_EOA;
@@ -385,18 +383,14 @@ static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
static int apci3xxx_ai_started(struct comedi_device *dev)
{
- struct apci3xxx_private *devpriv = dev->private;
-
- if ((readl(devpriv->mmio + 8) & 0x80000) == 0x80000)
+ if ((readl(dev->mmio + 8) & 0x80000) == 0x80000)
return 1;
- else
- return 0;
+ return 0;
}
static int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(chanspec);
unsigned int range = CR_RANGE(chanspec);
unsigned int aref = CR_AREF(chanspec);
@@ -407,29 +401,29 @@ static int apci3xxx_ai_setup(struct comedi_device *dev, unsigned int chanspec)
return -EBUSY;
/* Clear the FIFO */
- writel(0x10000, devpriv->mmio + 12);
+ writel(0x10000, dev->mmio + 12);
/* Get and save the delay mode */
- delay_mode = readl(devpriv->mmio + 4);
+ delay_mode = readl(dev->mmio + 4);
delay_mode &= 0xfffffef0;
/* Channel configuration selection */
- writel(delay_mode, devpriv->mmio + 4);
+ writel(delay_mode, dev->mmio + 4);
/* Make the configuration */
val = (range & 3) | ((range >> 2) << 6) |
((aref == AREF_DIFF) << 7);
- writel(val, devpriv->mmio + 0);
+ writel(val, dev->mmio + 0);
/* Channel selection */
- writel(delay_mode | 0x100, devpriv->mmio + 4);
- writel(chan, devpriv->mmio + 0);
+ writel(delay_mode | 0x100, dev->mmio + 4);
+ writel(chan, dev->mmio + 0);
/* Restore delay mode */
- writel(delay_mode, devpriv->mmio + 4);
+ writel(delay_mode, dev->mmio + 4);
/* Set the number of sequence to 1 */
- writel(1, devpriv->mmio + 48);
+ writel(1, dev->mmio + 48);
return 0;
}
@@ -439,10 +433,9 @@ static int apci3xxx_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->mmio + 20);
+ status = readl(dev->mmio + 20);
if (status & 0x1)
return 0;
return -EBUSY;
@@ -453,7 +446,6 @@ static int apci3xxx_ai_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct apci3xxx_private *devpriv = dev->private;
int ret;
int i;
@@ -463,7 +455,7 @@ static int apci3xxx_ai_insn_read(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
/* Start the conversion */
- writel(0x80000, devpriv->mmio + 8);
+ writel(0x80000, dev->mmio + 8);
/* Wait the EOS */
ret = comedi_timeout(dev, s, insn, apci3xxx_ai_eoc, 0);
@@ -471,14 +463,14 @@ static int apci3xxx_ai_insn_read(struct comedi_device *dev,
return ret;
/* Read the analog value */
- data[i] = readl(devpriv->mmio + 28);
+ data[i] = readl(dev->mmio + 28);
}
return insn->n;
}
static int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
- unsigned int *ns, int round_mode)
+ unsigned int *ns, unsigned int flags)
{
const struct apci3xxx_boardinfo *board = comedi_board(dev);
struct apci3xxx_private *devpriv = dev->private;
@@ -504,7 +496,7 @@ static int apci3xxx_ai_ns_to_timer(struct comedi_device *dev,
break;
}
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
timer = (*ns + base / 2) / base;
@@ -574,7 +566,7 @@ static int apci3xxx_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->convert_arg;
- err |= apci3xxx_ai_ns_to_timer(dev, &arg, cmd->flags & TRIG_ROUND_MASK);
+ err |= apci3xxx_ai_ns_to_timer(dev, &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (err)
@@ -595,13 +587,13 @@ static int apci3xxx_ai_cmd(struct comedi_device *dev,
return ret;
/* Set the convert timing unit */
- writel(devpriv->ai_time_base, devpriv->mmio + 36);
+ writel(devpriv->ai_time_base, dev->mmio + 36);
/* Set the convert timing */
- writel(devpriv->ai_timer, devpriv->mmio + 32);
+ writel(devpriv->ai_timer, dev->mmio + 32);
/* Start the conversion */
- writel(0x180000, devpriv->mmio + 8);
+ writel(0x180000, dev->mmio + 8);
return 0;
}
@@ -617,10 +609,9 @@ static int apci3xxx_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->mmio + 96);
+ status = readl(dev->mmio + 96);
if (status & 0x100)
return 0;
return -EBUSY;
@@ -631,7 +622,6 @@ static int apci3xxx_ao_insn_write(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int range = CR_RANGE(insn->chanspec);
int ret;
@@ -639,10 +629,10 @@ static int apci3xxx_ao_insn_write(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
/* Set the range selection */
- writel(range, devpriv->mmio + 96);
+ writel(range, dev->mmio + 96);
/* Write the analog value to the selected channel */
- writel((data[i] << 8) | chan, devpriv->mmio + 100);
+ writel((data[i] << 8) | chan, dev->mmio + 100);
/* Wait the end of transfer */
ret = comedi_timeout(dev, s, insn, apci3xxx_ao_eoc, 0);
@@ -696,10 +686,9 @@ static int apci3xxx_dio_insn_config(struct comedi_device *dev,
/* ignore all other instructions for ports 0 and 1 */
if (chan < 16)
return -EINVAL;
- else
- /* changing any channel in port 2 */
- /* changes the entire port */
- mask = 0xff0000;
+
+ /* changing any channel in port 2 changes the entire port */
+ mask = 0xff0000;
}
ret = comedi_dio_insn_config(dev, s, insn, data, mask);
@@ -742,7 +731,6 @@ static int apci3xxx_dio_insn_bits(struct comedi_device *dev,
static int apci3xxx_reset(struct comedi_device *dev)
{
- struct apci3xxx_private *devpriv = dev->private;
unsigned int val;
int i;
@@ -750,18 +738,18 @@ static int apci3xxx_reset(struct comedi_device *dev)
disable_irq(dev->irq);
/* Clear the start command */
- writel(0, devpriv->mmio + 8);
+ writel(0, dev->mmio + 8);
/* Reset the interrupt flags */
- val = readl(devpriv->mmio + 16);
- writel(val, devpriv->mmio + 16);
+ val = readl(dev->mmio + 16);
+ writel(val, dev->mmio + 16);
/* clear the EOS */
- readl(devpriv->mmio + 20);
+ readl(dev->mmio + 20);
/* Clear the FIFO */
for (i = 0; i < 16; i++)
- val = readl(devpriv->mmio + 28);
+ val = readl(dev->mmio + 28);
/* Enable the interrupt */
enable_irq(dev->irq);
@@ -796,7 +784,7 @@ static int apci3xxx_auto_attach(struct comedi_device *dev,
return ret;
dev->iobase = pci_resource_start(pcidev, 2);
- devpriv->mmio = pci_ioremap_bar(pcidev, 3);
+ dev->mmio = pci_ioremap_bar(pcidev, 3);
if (pcidev->irq > 0) {
ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
@@ -920,8 +908,8 @@ static void apci3xxx_detach(struct comedi_device *dev)
apci3xxx_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv->mmio)
- iounmap(devpriv->mmio);
+ if (dev->mmio)
+ iounmap(dev->mmio);
}
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 584fd57ecb70..51edfebb952a 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -75,9 +75,6 @@ TODO:
#include "plx9052.h"
#include "comedi_fc.h"
-#define PCI9111_DRIVER_NAME "adl_pci9111"
-#define PCI9111_HR_DEVICE_ID 0x9111
-
#define PCI9111_FIFO_HALF_SIZE 512
#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000
@@ -189,68 +186,6 @@ static void pci9111_timer_set(struct comedi_device *dev)
i8254_write(timer_base, 1, 1, dev_private->div1);
}
-enum pci9111_trigger_sources {
- software,
- timer_pacer,
- external
-};
-
-static void pci9111_trigger_source_set(struct comedi_device *dev,
- enum pci9111_trigger_sources source)
-{
- int flags;
-
- /* Read the current trigger mode control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Mask off the EITS and TPST bits */
- flags &= 0x9;
-
- switch (source) {
- case software:
- break;
-
- case timer_pacer:
- flags |= PCI9111_AI_TRIG_CTRL_TPST;
- break;
-
- case external:
- flags |= PCI9111_AI_TRIG_CTRL_ETIS;
- break;
- }
-
- outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-}
-
-static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger)
-{
- int flags;
-
- /* Read the current trigger mode control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Mask off the PTRG bit */
- flags &= 0x7;
-
- if (pretrigger)
- flags |= PCI9111_AI_TRIG_CTRL_PTRG;
-
- outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-}
-
-static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan)
-{
- int flags;
-
- /* Read the current trigger mode control bits */
- flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
- /* Mask off the ASCAN bit */
- flags &= 0xe;
-
- if (autoscan)
- flags |= PCI9111_AI_TRIG_CTRL_ASCAN;
-
- outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
-}
-
enum pci9111_ISC0_sources {
irq_on_eoc,
irq_on_fifo_half_full
@@ -303,9 +238,8 @@ static int pci9111_ai_cancel(struct comedi_device *dev,
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
true, false);
- pci9111_trigger_source_set(dev, software);
-
- pci9111_autoscan_set(dev, false);
+ /* disable A/D triggers (software trigger mode) and auto scan off */
+ outb(0, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
pci9111_fifo_reset(dev);
@@ -454,20 +388,17 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
{
struct pci9111_private_data *dev_private = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int last_chan = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+ unsigned int trig = 0;
/* Set channel scan limit */
/* PCI9111 allows only scanning from channel 0 to channel n */
/* TODO: handle the case of an external multiplexer */
- if (cmd->chanlist_len > 1) {
- outb(cmd->chanlist_len - 1,
- dev->iobase + PCI9111_AI_CHANNEL_REG);
- pci9111_autoscan_set(dev, true);
- } else {
- outb(CR_CHAN(cmd->chanlist[0]),
- dev->iobase + PCI9111_AI_CHANNEL_REG);
- pci9111_autoscan_set(dev, false);
- }
+ if (cmd->chanlist_len > 1)
+ trig |= PCI9111_AI_TRIG_CTRL_ASCAN;
+
+ outb(last_chan, dev->iobase + PCI9111_AI_CHANNEL_REG);
/* Set gain */
/* This is the same gain on every channel */
@@ -484,12 +415,11 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
/* Set timer pacer */
dev_private->scan_delay = 0;
if (cmd->convert_src == TRIG_TIMER) {
- pci9111_trigger_source_set(dev, software);
+ trig |= PCI9111_AI_TRIG_CTRL_TPST;
pci9111_timer_set(dev);
pci9111_fifo_reset(dev);
pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
irq_on_timer_tick);
- pci9111_trigger_source_set(dev, timer_pacer);
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
false, true, true);
@@ -498,14 +428,14 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
(cmd->convert_arg * cmd->chanlist_len)) - 1;
}
} else { /* TRIG_EXT */
- pci9111_trigger_source_set(dev, external);
+ trig |= PCI9111_AI_TRIG_CTRL_ETIS;
pci9111_fifo_reset(dev);
pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
irq_on_timer_tick);
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
false, true, true);
-
}
+ outb(trig, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
dev_private->stop_counter *= (1 + dev_private->scan_delay);
dev_private->chunk_counter = 0;
@@ -630,7 +560,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
/* '0' means FIFO is full, data may have been lost */
if (!(status & PCI9111_AI_STAT_FF_FF)) {
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
- comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
+ dev_dbg(dev->class_dev, "fifo overflow\n");
outb(0, dev->iobase + PCI9111_INT_CLR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
@@ -771,9 +701,8 @@ static int pci9111_reset(struct comedi_device *dev)
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
true, false);
- pci9111_trigger_source_set(dev, software);
- pci9111_pretrigger_set(dev, false);
- pci9111_autoscan_set(dev, false);
+ /* disable A/D triggers (software trigger mode) and auto scan off */
+ outb(0, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
/* Reset 8254 chip */
dev_private->div1 = 0;
@@ -884,7 +813,7 @@ static int pci9111_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id pci9111_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x9111) },
/* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */
{ 0 }
};
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 59a65cbc6db9..f30b84e1987b 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -7,61 +7,62 @@
*
* Author: Michal Dobes <dobes@tesnet.cz>
*
-*/
+ */
+
/*
-Driver: adl_pci9118
-Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
-Author: Michal Dobes <dobes@tesnet.cz>
-Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
- PCI-9118HR (pci9118hr)
-Status: works
-
-This driver supports AI, AO, DI and DO subdevices.
-AI subdevice supports cmd and insn interface,
-other subdevices support only insn interface.
-For AI:
-- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
-- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
-- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
-- It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
- cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
-- If return value of cmdtest is 5 then you've bad channel list
- (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
- ranges).
-
-There are some hardware limitations:
-a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
- ended inputs.
-b) DMA transfers must have the length aligned to two samples (32 bit),
- so there is some problems if cmd->chanlist_len is odd. This driver tries
- bypass this with adding one sample to the end of the every scan and discard
- it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
- and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
- with interrupt after every sample.
-c) If isn't used DMA then you can use only mode where
- cmd->scan_begin_src=TRIG_FOLLOW.
-
-Configuration options:
- [0] - PCI bus of device (optional)
- [1] - PCI slot of device (optional)
- If bus/slot is not specified, then first available PCI
- card will be used.
- [2] - 0= standard 8 DIFF/16 SE channels configuration
- n = external multiplexer connected, 1 <= n <= 256
- [3] - 0=autoselect DMA or EOC interrupts operation
- 1 = disable DMA mode
- 3 = disable DMA and INT, only insn interface will work
- [4] - sample&hold signal - card can generate signal for external S&H board
- 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
- 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
- long delay is requested in ns and sign polarity of the hold
- (in this case external multiplexor can serve only 128 channels)
- [5] - 0=stop measure on all hardware errors
- 2 | = ignore ADOR - A/D Overrun status
- 8|=ignore Bover - A/D Burst Mode Overrun status
- 256|=ignore nFull - A/D FIFO Full status
-
-*/
+ * Driver: adl_pci9118
+ * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
+ * PCI-9118HR (pci9118hr)
+ * Status: works
+ *
+ * This driver supports AI, AO, DI and DO subdevices.
+ * AI subdevice supports cmd and insn interface,
+ * other subdevices support only insn interface.
+ * For AI:
+ * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
+ * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
+ * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
+ * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
+ * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
+ * - If return value of cmdtest is 5 then you've bad channel list
+ * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
+ * ranges).
+ *
+ * There are some hardware limitations:
+ * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
+ * ended inputs.
+ * b) DMA transfers must have the length aligned to two samples (32 bit),
+ * so there is some problems if cmd->chanlist_len is odd. This driver tries
+ * bypass this with adding one sample to the end of the every scan and discard
+ * it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
+ * and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
+ * with interrupt after every sample.
+ * c) If isn't used DMA then you can use only mode where
+ * cmd->scan_begin_src=TRIG_FOLLOW.
+ *
+ * Configuration options:
+ * [0] - PCI bus of device (optional)
+ * [1] - PCI slot of device (optional)
+ * If bus/slot is not specified, then first available PCI
+ * card will be used.
+ * [2] - 0= standard 8 DIFF/16 SE channels configuration
+ * n = external multiplexer connected, 1 <= n <= 256
+ * [3] - 0=autoselect DMA or EOC interrupts operation
+ * 1 = disable DMA mode
+ * 3 = disable DMA and INT, only insn interface will work
+ * [4] - sample&hold signal - card can generate signal for external S&H board
+ * 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
+ * 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
+ * long delay is requested in ns and sign polarity of the hold
+ * (in this case external multiplexor can serve only 128 channels)
+ * [5] - 0=stop measure on all hardware errors
+ * 2 | = ignore ADOR - A/D Overrun status
+ * 8|=ignore Bover - A/D Burst Mode Overrun status
+ * 256|=ignore nFull - A/D FIFO Full status
+ *
+ */
/*
* FIXME
@@ -346,7 +347,7 @@ struct pci9118_private {
* on external start
*/
unsigned short ao_data[2]; /* data output buffer */
- char dma_doublebuf; /* we can use double buffering */
+ char dma_doublebuf; /* use double buffering */
unsigned int dma_actbuf; /* which buffer is used now */
unsigned short *dmabuf_virt[2]; /*
* pointers to begin of
@@ -394,12 +395,12 @@ static int check_channel_list(struct comedi_device *dev,
/* correct channel and range number check itself comedi/range.c */
if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
return 0;
}
if ((frontadd + n_chan + backadd) > s->len_chanlist) {
- comedi_error(dev,
- "range/channel list is too long for actual configuration!\n");
+ dev_err(dev->class_dev,
+ "range/channel list is too long for actual configuration!\n");
return 0;
}
@@ -411,23 +412,20 @@ static int check_channel_list(struct comedi_device *dev,
for (i = 1; i < n_chan; i++) { /* check S.E/diff */
if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
(differencial)) {
- comedi_error(dev,
- "Differencial and single ended "
- "inputs can't be mixtured!");
+ dev_err(dev->class_dev,
+ "Differential and single ended inputs can't be mixed!\n");
return 0;
}
if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
(bipolar)) {
- comedi_error(dev,
- "Bipolar and unipolar ranges "
- "can't be mixtured!");
+ dev_err(dev->class_dev,
+ "Bipolar and unipolar ranges can't be mixed!\n");
return 0;
}
if (!devpriv->usemux && differencial &&
(CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
- comedi_error(dev,
- "If AREF_DIFF is used then is "
- "available only first 8 channels!");
+ dev_err(dev->class_dev,
+ "AREF_DIFF is only available for the first 8 channels!\n");
return 0;
}
}
@@ -864,20 +862,21 @@ static char pci9118_decode_error_status(struct comedi_device *dev,
struct pci9118_private *devpriv = dev->private;
if (m & 0x100) {
- comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
+ dev_err(dev->class_dev,
+ "A/D FIFO Full status (Fatal Error!)\n");
devpriv->ai_maskerr &= ~0x100L;
}
if (m & 0x008) {
- comedi_error(dev,
- "A/D Burst Mode Overrun Status (Fatal Error!)");
+ dev_err(dev->class_dev,
+ "A/D Burst Mode Overrun Status (Fatal Error!)\n");
devpriv->ai_maskerr &= ~0x008L;
}
if (m & 0x004) {
- comedi_error(dev, "A/D Over Speed Status (Warning!)");
+ dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
devpriv->ai_maskerr &= ~0x004L;
}
if (m & 0x002) {
- comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
+ dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
devpriv->ai_maskerr &= ~0x002L;
}
if (m & devpriv->ai_maskharderr) {
@@ -966,14 +965,14 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
unsigned int next_dma_buf, samplesinbuf, sampls, m;
if (int_amcc & MASTER_ABORT_INT) {
- comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return;
}
if (int_amcc & TARGET_ABORT_INT) {
- comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+ dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return;
@@ -1427,17 +1426,16 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
devpriv->AdControlReg |= AdControl_TmrTr;
break;
case 2:
- comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
+ dev_err(dev->class_dev, "%s mode 2 bug!\n", __func__);
return -EIO;
case 3:
devpriv->AdControlReg |= AdControl_ExtM;
break;
case 4:
- comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
+ dev_err(dev->class_dev, "%s mode 4 bug!\n", __func__);
return -EIO;
default:
- comedi_error(dev,
- "pci9118_ai_docmd_sampl() mode number bug!\n");
+ dev_err(dev->class_dev, "%s mode number bug!\n", __func__);
return -EIO;
}
@@ -1509,7 +1507,7 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev,
devpriv->AdFunctionReg |= AdFunction_Start;
break;
default:
- comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
+ dev_err(dev->class_dev, "%s mode number bug!\n", __func__);
return -EIO;
}
@@ -1677,9 +1675,8 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
(cmd->convert_src == TRIG_NOW))) {
/* double timed action */
if (!devpriv->usedma) {
- comedi_error(dev,
- "cmd->scan_begin_src=TRIG_TIMER works "
- "only with bus mastering!");
+ dev_err(dev->class_dev,
+ "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
return -EIO;
}
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index b4ea37704eaf..8b15cbec9891 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -79,20 +79,20 @@ If you do not specify any options, they will default to
#include "../comedidev.h"
/* address scheme (page 2.17 of the manual) */
-#define ADQ12B_SIZE 16
-
-#define ADQ12B_CTREG 0x00
-#define ADQ12B_STINR 0x00
-#define ADQ12B_OUTBR 0x04
-#define ADQ12B_ADLOW 0x08
-#define ADQ12B_ADHIG 0x09
-#define ADQ12B_CONT0 0x0c
-#define ADQ12B_CONT1 0x0d
-#define ADQ12B_CONT2 0x0e
-#define ADQ12B_COWORD 0x0f
-
-/* mask of the bit at STINR to check end of conversion */
-#define ADQ12B_EOC 0x20
+#define ADQ12B_CTREG 0x00
+#define ADQ12B_CTREG_MSKP (1 << 7) /* enable pacer interrupt */
+#define ADQ12B_CTREG_GTP (1 << 6) /* enable pacer */
+#define ADQ12B_CTREG_RANGE(x) ((x) << 4)
+#define ADQ12B_CTREG_CHAN(x) ((x) << 0)
+#define ADQ12B_STINR 0x00
+#define ADQ12B_STINR_OUT2 (1 << 7) /* timer 2 output state */
+#define ADQ12B_STINR_OUTP (1 << 6) /* pacer output state */
+#define ADQ12B_STINR_EOC (1 << 5) /* A/D end-of-conversion */
+#define ADQ12B_STINR_IN_MASK (0x1f << 0)
+#define ADQ12B_OUTBR 0x04
+#define ADQ12B_ADLOW 0x08
+#define ADQ12B_ADHIG 0x09
+#define ADQ12B_TIMER_BASE 0x0c
/* available ranges through the PGA gains */
static const struct comedi_lrange range_adq12b_ai_bipolar = {
@@ -114,10 +114,7 @@ static const struct comedi_lrange range_adq12b_ai_unipolar = {
};
struct adq12b_private {
- int unipolar; /* option 2 of comedi_config (1 is iobase) */
- int differential; /* option 3 of comedi_config */
- int last_channel;
- int last_range;
+ unsigned int last_ctreg;
};
static int adq12b_ai_eoc(struct comedi_device *dev,
@@ -128,50 +125,45 @@ static int adq12b_ai_eoc(struct comedi_device *dev,
unsigned char status;
status = inb(dev->iobase + ADQ12B_STINR);
- if (status & ADQ12B_EOC)
+ if (status & ADQ12B_STINR_EOC)
return 0;
return -EBUSY;
}
-static int adq12b_ai_rinsn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
+static int adq12b_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct adq12b_private *devpriv = dev->private;
- int n;
- int range, channel;
- unsigned char hi, lo, status;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int val;
int ret;
+ int i;
/* change channel and range only if it is different from the previous */
- range = CR_RANGE(insn->chanspec);
- channel = CR_CHAN(insn->chanspec);
- if (channel != devpriv->last_channel || range != devpriv->last_range) {
- outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
+ val = ADQ12B_CTREG_RANGE(range) | ADQ12B_CTREG_CHAN(chan);
+ if (val != devpriv->last_ctreg) {
+ outb(val, dev->iobase + ADQ12B_CTREG);
+ devpriv->last_ctreg = val;
udelay(50); /* wait for the mux to settle */
}
- /* trigger conversion */
- status = inb(dev->iobase + ADQ12B_ADLOW);
-
- /* convert n samples */
- for (n = 0; n < insn->n; n++) {
+ val = inb(dev->iobase + ADQ12B_ADLOW); /* trigger A/D */
- /* wait for end of conversion */
+ for (i = 0; i < insn->n; i++) {
ret = comedi_timeout(dev, s, insn, adq12b_ai_eoc, 0);
if (ret)
return ret;
- /* read data */
- hi = inb(dev->iobase + ADQ12B_ADHIG);
- lo = inb(dev->iobase + ADQ12B_ADLOW);
-
- data[n] = (hi << 8) | lo;
+ val = inb(dev->iobase + ADQ12B_ADHIG) << 8;
+ val |= inb(dev->iobase + ADQ12B_ADLOW); /* retriggers A/D */
+ data[i] = val;
}
- /* return the number of samples read/written */
- return n;
+ return insn->n;
}
static int adq12b_di_insn_bits(struct comedi_device *dev,
@@ -180,7 +172,7 @@ static int adq12b_di_insn_bits(struct comedi_device *dev,
{
/* only bits 0-4 have information about digital inputs */
- data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f));
+ data[1] = (inb(dev->iobase + ADQ12B_STINR) & ADQ12B_STINR_IN_MASK);
return insn->n;
}
@@ -216,7 +208,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], ADQ12B_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
@@ -224,58 +216,44 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- devpriv->unipolar = it->options[1];
- devpriv->differential = it->options[2];
- /*
- * initialize channel and range to -1 so we make sure we
- * always write at least once to the CTREG in the instruction
- */
- devpriv->last_channel = -1;
- devpriv->last_range = -1;
+ devpriv->last_ctreg = -1; /* force ctreg update */
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
return ret;
+ /* Analog Input subdevice */
s = &dev->subdevices[0];
- /* analog input subdevice */
- s->type = COMEDI_SUBD_AI;
- if (devpriv->differential) {
- s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
- s->n_chan = 8;
+ s->type = COMEDI_SUBD_AI;
+ if (it->options[2]) {
+ s->subdev_flags = SDF_READABLE | SDF_DIFF;
+ s->n_chan = 8;
} else {
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
- s->n_chan = 16;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 16;
}
+ s->maxdata = 0xfff;
+ s->range_table = it->options[1] ? &range_adq12b_ai_unipolar
+ : &range_adq12b_ai_bipolar;
+ s->insn_read = adq12b_ai_insn_read;
- if (devpriv->unipolar)
- s->range_table = &range_adq12b_ai_unipolar;
- else
- s->range_table = &range_adq12b_ai_bipolar;
-
- s->maxdata = 0xfff;
-
- s->len_chanlist = 4; /* This is the maximum chanlist length that
- the board can handle */
- s->insn_read = adq12b_ai_rinsn;
-
+ /* Digital Input subdevice */
s = &dev->subdevices[1];
- /* digital input subdevice */
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan = 5;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = adq12b_di_insn_bits;
-
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 5;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_di_insn_bits;
+
+ /* Digital Output subdevice */
s = &dev->subdevices[2];
- /* digital output subdevice */
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 8;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = adq12b_do_insn_bits;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_do_insn_bits;
return 0;
}
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 602b7a1e40e6..e19ab958791b 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -722,8 +722,8 @@ static int pci171x_ai_cancel(struct comedi_device *dev,
default:
devpriv->CntrlReg &= Control_CNT0;
devpriv->CntrlReg |= Control_SW;
-
- outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */
+ /* reset any operations */
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
pci171x_start_pacer(dev, false);
outb(0, dev->iobase + PCI171x_CLRFIFO);
outb(0, dev->iobase + PCI171x_CLRINT);
@@ -1049,15 +1049,18 @@ static int pci171x_reset(struct comedi_device *dev)
struct pci1710_private *devpriv = dev->private;
outw(0x30, dev->iobase + PCI171x_CNTCTRL);
- devpriv->CntrlReg = Control_SW | Control_CNT0; /* Software trigger, CNT0=external */
- outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); /* reset any operations */
+ /* Software trigger, CNT0=external */
+ devpriv->CntrlReg = Control_SW | Control_CNT0;
+ /* reset any operations */
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
outb(0, dev->iobase + PCI171x_CLRFIFO); /* clear FIFO */
outb(0, dev->iobase + PCI171x_CLRINT); /* clear INT request */
pci171x_start_pacer(dev, false);
devpriv->da_ranges = 0;
if (this_board->n_aochan) {
- outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); /* set DACs to 0..5V */
- outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */
+ /* set DACs to 0..5V */
+ outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+ outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */
devpriv->ao_data[0] = 0x0000;
if (this_board->n_aochan > 1) {
outw(0, dev->iobase + PCI171x_DA2);
@@ -1077,10 +1080,11 @@ static int pci171x_reset(struct comedi_device *dev)
static int pci1720_reset(struct comedi_device *dev)
{
struct pci1710_private *devpriv = dev->private;
-
- outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); /* set synchronous output mode */
+ /* set synchronous output mode */
+ outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT);
devpriv->da_ranges = 0xAA;
- outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); /* set all ranges to +/-5V */
+ /* set all ranges to +/-5V */
+ outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE);
outw(0x0800, dev->iobase + PCI1720_DA0); /* set outputs to 0V */
outw(0x0800, dev->iobase + PCI1720_DA1);
outw(0x0800, dev->iobase + PCI1720_DA2);
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index 07b107d1ab33..1881df459dae 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -161,11 +161,10 @@ static int pci1723_ao_write_winsn(struct comedi_device *dev,
struct comedi_insn *insn, unsigned int *data)
{
struct pci1723_private *devpriv = dev->private;
- int n, chan;
- chan = CR_CHAN(insn->chanspec);
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int n;
for (n = 0; n < insn->n; n++) {
-
devpriv->ao_data[chan] = data[n];
outw(data[n], dev->iobase + PCI1723_DA(chan));
}
diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c
index af670acb03d8..bc3c34916768 100644
--- a/drivers/staging/comedi/drivers/adv_pci1724.c
+++ b/drivers/staging/comedi/drivers/adv_pci1724.c
@@ -143,7 +143,8 @@ static int wait_for_dac_idle(struct comedi_device *dev)
udelay(1);
}
if (i == timeout) {
- comedi_error(dev, "Timed out waiting for dac to become idle.");
+ dev_err(dev->class_dev,
+ "Timed out waiting for dac to become idle\n");
return -EIO;
}
return 0;
@@ -195,8 +196,8 @@ static int ao_readback_insn(struct comedi_device *dev,
int i;
if (devpriv->ao_value[channel] < 0) {
- comedi_error(dev,
- "Cannot read back channels which have not yet been written to.");
+ dev_err(dev->class_dev,
+ "Cannot read back channels which have not yet been written to\n");
return -EIO;
}
for (i = 0; i < insn->n; i++)
@@ -236,8 +237,8 @@ static int offset_read_insn(struct comedi_device *dev,
int i;
if (devpriv->offset_value[channel] < 0) {
- comedi_error(dev,
- "Cannot read back channels which have not yet been written to.");
+ dev_err(dev->class_dev,
+ "Cannot read back channels which have not yet been written to\n");
return -EIO;
}
for (i = 0; i < insn->n; i++)
@@ -277,8 +278,8 @@ static int gain_read_insn(struct comedi_device *dev,
int i;
if (devpriv->gain_value[channel] < 0) {
- comedi_error(dev,
- "Cannot read back channels which have not yet been written to.");
+ dev_err(dev->class_dev,
+ "Cannot read back channels which have not yet been written to\n");
return -EIO;
}
for (i = 0; i < insn->n; i++)
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 2d966a87f2e8..b8c7d9145a54 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -592,7 +592,7 @@ static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
return 0;
}
- comedi_error(dev, "PCI-1760 mailbox request timeout!");
+ dev_err(dev->class_dev, "PCI-1760 mailbox request timeout!\n");
return -ETIME;
}
@@ -610,12 +610,13 @@ static int pci1760_mbxrequest(struct comedi_device *dev,
unsigned char *omb, unsigned char *imb)
{
if (omb[2] == CMD_ClearIMB2) {
- comedi_error(dev,
- "bug! this function should not be used for CMD_ClearIMB2 command");
+ dev_err(dev->class_dev,
+ "bug! this function should not be used for CMD_ClearIMB2 command\n");
return -EINVAL;
}
if (inb(dev->iobase + IMB2) == omb[2]) {
int retval;
+
retval = pci1760_clear_imb2(dev);
if (retval < 0)
return retval;
@@ -826,7 +827,7 @@ static int pci_dio_reset(struct comedi_device *dev)
outb(0, dev->iobase + PCI1730_DO + 1);
outb(0, dev->iobase + PCI1730_IDO);
outb(0, dev->iobase + PCI1730_IDO + 1);
- /* NO break there! */
+ /* fallthrough */
case TYPE_PCI1733:
/* disable interrupts */
outb(0, dev->iobase + PCI1730_3_INT_EN);
@@ -886,7 +887,7 @@ static int pci_dio_reset(struct comedi_device *dev)
outb(0x80, dev->iobase + PCI1753E_ICR1);
outb(0x80, dev->iobase + PCI1753E_ICR2);
outb(0x80, dev->iobase + PCI1753E_ICR3);
- /* NO break there! */
+ /* fallthrough */
case TYPE_PCI1753:
outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear
* interrupts */
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 781104aa533e..7b5ed439c164 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -33,7 +33,6 @@ Configuration Options:
#include <linux/module.h>
#include "../comedidev.h"
-#define AIO_IIRO_16_SIZE 0x08
#define AIO_IIRO_16_RELAY_0_7 0x00
#define AIO_IIRO_16_INPUT_0_7 0x01
#define AIO_IIRO_16_IRQ 0x02
@@ -74,7 +73,7 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], AIO_IIRO_16_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h
index 2ba736444610..cf6a497b092c 100644
--- a/drivers/staging/comedi/drivers/amcc_s5933.h
+++ b/drivers/staging/comedi/drivers/amcc_s5933.h
@@ -41,7 +41,7 @@
#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
#define AMCC_FIFO_DEPTH_DWORD 8
-#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
/****************************************************************************/
/* AMCC - PCI Interrupt Control/Status Register */
@@ -52,8 +52,10 @@
#define INTCSR_INBOX_BYTE(x) (((x) & 0x3) << 8)
#define INTCSR_INBOX_SELECT(x) (((x) & 0x3) << 10)
#define INTCSR_INBOX_FULL_INT 0x1000 /* enable inbox full interrupt */
-#define INTCSR_INBOX_INTR_STATUS 0x20000 /* read, or write clear inbox full interrupt */
-#define INTCSR_INTR_ASSERTED 0x800000 /* read only, interrupt asserted */
+/* read, or write clear inbox full interrupt */
+#define INTCSR_INBOX_INTR_STATUS 0x20000
+/* read only, interrupt asserted */
+#define INTCSR_INTR_ASSERTED 0x800000
/****************************************************************************/
/* AMCC - PCI non-volatile ram command register (byte 3 of master control/status register) */
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index dc1dee79fc16..17d2e20663cb 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -278,8 +278,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
ret = comedi_request_region(dev, it->options[0], thisboard->mainsize);
if (ret)
return ret;
- devpriv->io.u.iobase = dev->iobase;
- devpriv->io.regtype = io_regtype;
+
return amplc_dio200_common_attach(dev, irq, 0);
}
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h
index 43160b9944bb..e0afe2cee2d6 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.h
+++ b/drivers/staging/comedi/drivers/amplc_dio200.h
@@ -28,18 +28,6 @@
#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 };
@@ -75,7 +63,6 @@ struct dio200_board {
* Comedi device private data.
*/
struct dio200_private {
- struct dio200_region io; /* Register region */
int intr_sd;
};
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c
index 3edaa4028da2..f0d709e0dafc 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200_common.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c
@@ -151,13 +151,12 @@ 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);
+
+ if (dev->mmio)
+ return readb(dev->mmio + offset);
+ return inb(dev->iobase + offset);
}
/*
@@ -167,13 +166,13 @@ 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);
+
+ if (dev->mmio)
+ writeb(val, dev->mmio + offset);
else
- writeb(val, devpriv->io.u.membase + offset);
+ outb(val, dev->iobase + offset);
}
/*
@@ -183,13 +182,12 @@ 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);
+
+ if (dev->mmio)
+ return readl(dev->mmio + offset);
+ return inl(dev->iobase + offset);
}
/*
@@ -199,13 +197,13 @@ 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);
+
+ if (dev->mmio)
+ writel(val, dev->mmio + offset);
else
- writel(val, devpriv->io.u.membase + offset);
+ outl(val, dev->iobase + offset);
}
/*
@@ -327,7 +325,7 @@ static void dio200_read_scan_intr(struct comedi_device *dev,
/* Error! Stop acquisition. */
dio200_stop_intr(dev, s);
s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- comedi_error(dev, "buffer overflow");
+ dev_err(dev->class_dev, "buffer overflow\n");
}
/* Check for end of acquisition. */
@@ -1197,13 +1195,10 @@ 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;
-
- if (!thisboard || !devpriv)
- return;
- if (dev->irq)
+ if (dev->irq) {
free_irq(dev->irq, dev);
+ dev->irq = 0;
+ }
}
EXPORT_SYMBOL_GPL(amplc_dio200_common_detach);
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
index e0367380b37a..fbf05687347f 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c
@@ -228,13 +228,6 @@
#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.
*/
@@ -394,16 +387,14 @@ static int dio200_pci_auto_attach(struct comedi_device *dev,
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->mmio = pci_ioremap_bar(pci_dev, bar);
+ if (!dev->mmio) {
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;
+ dev->iobase = pci_resource_start(pci_dev, bar);
}
switch (context_model) {
case pcie215_model:
@@ -421,14 +412,9 @@ static int dio200_pci_auto_attach(struct comedi_device *dev,
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);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
@@ -440,22 +426,11 @@ static struct comedi_driver dio200_pci_comedi_driver = {
};
static const struct pci_device_id 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
- },
+ { PCI_VDEVICE(AMPLICON, 0x000b), pci215_model },
+ { PCI_VDEVICE(AMPLICON, 0x000a), pci272_model },
+ { PCI_VDEVICE(AMPLICON, 0x0011), pcie236_model },
+ { PCI_VDEVICE(AMPLICON, 0x0012), pcie215_model },
+ { PCI_VDEVICE(AMPLICON, 0x0014), pcie296_model },
{0}
};
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
index c9a96ad00559..875cc19cb969 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -1,444 +1,53 @@
/*
- comedi/drivers/amplc_pc236.c
- Driver for Amplicon PC36AT and PCI236 DIO boards.
-
- 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.
-*/
-/*
-Driver: amplc_pc236
-Description: Amplicon PC36AT, PCI236
-Author: Ian Abbott <abbotti@mev.co.uk>
-Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236)
-Updated: Wed, 01 Apr 2009 15:41:25 +0100
-Status: works
-
-Configuration options - PC36AT:
- [0] - I/O port base address
- [1] - IRQ (optional)
-
-Configuration options - PCI236:
- [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.
-
-The PC36AT ISA board and PCI236 PCI board have a single 8255 appearing
-as subdevice 0.
-
-Subdevice 1 pretends to be a digital input device, but it always returns
-0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
-a rising edge on port C bit 3 acts as an external trigger, which can be
-used to wake up tasks. This is like the comedi_parport device, but the
-only way to physically disable the interrupt on the PC36AT is to remove
-the IRQ jumper. If no interrupt is connected, then subdevice 1 is
-unused.
-*/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-
-#include "../comedidev.h"
-
-#include "comedi_fc.h"
-#include "8255.h"
-#include "plx9052.h"
-
-#define PC236_DRIVER_NAME "amplc_pc236"
-
-#define DO_ISA IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_ISA)
-#define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI)
-
-/* PCI236 PCI configuration register information */
-#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
-#define PCI_DEVICE_ID_INVALID 0xffff
-
-/* PC36AT / PCI236 registers */
-
-#define PC236_IO_SIZE 4
-#define PC236_LCR_IO_SIZE 128
-
-/* 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.
- */
-
-enum pc236_bustype { isa_bustype, pci_bustype };
-enum pc236_model { pc36at_model, pci236_model, anypci_model };
-
-struct pc236_board {
- const char *name;
- unsigned short devid;
- enum pc236_bustype bustype;
- enum pc236_model model;
-};
-static const struct pc236_board pc236_boards[] = {
-#if DO_ISA
- {
- .name = "pc36at",
- .bustype = isa_bustype,
- .model = pc36at_model,
- },
-#endif
-#if DO_PCI
- {
- .name = "pci236",
- .devid = PCI_DEVICE_ID_AMPLICON_PCI236,
- .bustype = pci_bustype,
- .model = pci236_model,
- },
- {
- .name = PC236_DRIVER_NAME,
- .devid = PCI_DEVICE_ID_INVALID,
- .bustype = pci_bustype,
- .model = anypci_model, /* wildcard */
- },
-#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 pc236_private {
- unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
- int enable_irq;
-};
-
-/* test if ISA supported and this is an ISA board */
-static inline bool is_isa_board(const struct pc236_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 pc236_board *board)
-{
- return DO_PCI && board->bustype == pci_bustype;
-}
-
-/*
- * This function looks for a board matching the supplied PCI device.
- */
-static const struct pc236_board *pc236_find_pci_board(struct pci_dev *pci_dev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(pc236_boards); i++)
- if (is_pci_board(&pc236_boards[i]) &&
- pci_dev->device == pc236_boards[i].devid)
- return &pc236_boards[i];
- return NULL;
-}
-
-/*
- * This function looks for a PCI device matching the requested board name,
- * bus and slot.
- */
-static struct pci_dev *pc236_find_pci_dev(struct comedi_device *dev,
- struct comedi_devconfig *it)
-{
- const struct pc236_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 pc236_board *foundboard;
-
- foundboard = pc236_find_pci_board(pci_dev);
- if (foundboard == NULL)
- continue;
- /* Replace wildcard board_ptr. */
- dev->board_ptr = 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 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!).
+ * comedi/drivers/amplc_pc236.c
+ * Driver for Amplicon PC36AT DIO boards.
+ *
+ * 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.
*/
-static void pc236_intr_disable(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct pc236_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->enable_irq = 0;
- if (is_pci_board(thisboard))
- outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
/*
- * This function is called to mark the interrupt as enabled (a command
- * configured on subdevice 1) and to physically enable the interrupt
- * (not possible on the PC36AT, except by (re)connecting the IRQ jumper!).
+ * Driver: amplc_pc236
+ * Description: Amplicon PC36AT
+ * Author: Ian Abbott <abbotti@mev.co.uk>
+ * Devices: [Amplicon] PC36AT (pc36at)
+ * Updated: Fri, 25 Jul 2014 15:32:40 +0000
+ * Status: works
+ *
+ * Configuration options - PC36AT:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional)
+ *
+ * The PC36AT board has a single 8255 appearing as subdevice 0.
+ *
+ * Subdevice 1 pretends to be a digital input device, but it always returns
+ * 0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
+ * a rising edge on port C bit 3 acts as an external trigger, which can be
+ * used to wake up tasks. This is like the comedi_parport device, but the
+ * only way to physically disable the interrupt on the PC36AT is to remove
+ * the IRQ jumper. If no interrupt is connected, then subdevice 1 is
+ * unused.
*/
-static void pc236_intr_enable(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct pc236_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->spinlock, flags);
- devpriv->enable_irq = 1;
- if (is_pci_board(thisboard))
- outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-/*
- * This function is called when an interrupt occurs to check whether
- * the interrupt has been marked as enabled and was generated by the
- * board. If so, the function prepares the hardware for the next
- * interrupt.
- * Returns 0 if the interrupt should be ignored.
- */
-static int pc236_intr_check(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(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)) {
- intcsr = inl(devpriv->lcr_iobase + PLX9052_INTCSR);
- if (!(intcsr & PLX9052_INTCSR_LI1STAT)) {
- retval = 0;
- } else {
- /* Clear interrupt and keep it enabled. */
- outl(PCI236_INTR_ENABLE,
- devpriv->lcr_iobase + PLX9052_INTCSR);
- }
- }
- }
- spin_unlock_irqrestore(&dev->spinlock, flags);
-
- return retval;
-}
-
-/*
- * Input from subdevice 1.
- * Copied from the comedi_parport driver.
- */
-static int pc236_intr_insn(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
- unsigned int *data)
-{
- data[1] = 0;
- return insn->n;
-}
-
-/*
- * Subdevice 1 command test.
- * Copied from the comedi_parport driver.
- */
-static int pc236_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);
- err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
- err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
- err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
- err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
- if (err)
- return 1;
-
- /* Step 2a : make sure trigger sources are unique */
- /* Step 2b : and mutually compatible */
-
- if (err)
- return 2;
-
- /* Step 3: check it 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);
- err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
-
- if (err)
- return 3;
-
- /* step 4: ignored */
-
- if (err)
- return 4;
-
- return 0;
-}
-
-/*
- * Subdevice 1 command.
- */
-static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- pc236_intr_enable(dev);
-
- return 0;
-}
-
-/*
- * Subdevice 1 cancel command.
- */
-static int pc236_intr_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s)
-{
- pc236_intr_disable(dev);
-
- return 0;
-}
-
-/*
- * Interrupt service routine.
- * Based on the comedi_parport driver.
- */
-static irqreturn_t pc236_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct comedi_subdevice *s = dev->read_subdev;
- int handled;
-
- handled = pc236_intr_check(dev);
- if (dev->attached && handled) {
- comedi_buf_put(s, 0);
- s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
- comedi_event(dev, s);
- }
- return IRQ_RETVAL(handled);
-}
-
-static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
- unsigned int irq, unsigned long req_irq_flags)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
- struct comedi_subdevice *s;
- int ret;
-
- dev->board_name = thisboard->name;
- dev->iobase = iobase;
-
- ret = comedi_alloc_subdevices(dev, 2);
- if (ret)
- return ret;
-
- s = &dev->subdevices[0];
- /* digital i/o subdevice (8255) */
- ret = subdev_8255_init(dev, s, NULL, iobase);
- if (ret)
- return ret;
-
- s = &dev->subdevices[1];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_UNUSED;
- pc236_intr_disable(dev);
- if (irq) {
- if (request_irq(irq, pc236_interrupt, req_irq_flags,
- PC236_DRIVER_NAME, dev) >= 0) {
- dev->irq = irq;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->maxdata = 1;
- s->range_table = &range_digital;
- s->insn_bits = pc236_intr_insn;
- s->len_chanlist = 1;
- s->do_cmdtest = pc236_intr_cmdtest;
- s->do_cmd = pc236_intr_cmd;
- s->cancel = pc236_intr_cancel;
- }
- }
-
- return 0;
-}
-
-static int pc236_pci_common_attach(struct comedi_device *dev,
- struct pci_dev *pci_dev)
-{
- struct pc236_private *devpriv = dev->private;
- unsigned long iobase;
- int ret;
-
- comedi_set_hw_dev(dev, &pci_dev->dev);
+#include <linux/module.h>
- ret = comedi_pci_enable(dev);
- if (ret)
- return ret;
+#include "../comedidev.h"
- 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);
-}
+#include "amplc_pc236.h"
-/*
- * 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 pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- const struct pc236_board *thisboard = comedi_board(dev);
struct pc236_private *devpriv;
int ret;
@@ -446,127 +55,31 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- /* Process options according to bus type. */
- if (is_isa_board(thisboard)) {
- ret = comedi_request_region(dev, it->options[0], PC236_IO_SIZE);
- if (ret)
- return ret;
-
- return pc236_common_attach(dev, dev->iobase, it->options[1], 0);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pci_dev;
-
- pci_dev = pc236_find_pci_dev(dev, it);
- if (!pci_dev)
- return -EIO;
- return pc236_pci_common_attach(dev, pci_dev);
- } else {
- dev_err(dev->class_dev, PC236_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 pc236_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
-{
- struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
- struct pc236_private *devpriv;
-
- if (!DO_PCI)
- return -EINVAL;
-
- dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n",
- pci_name(pci_dev));
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
+ ret = comedi_request_region(dev, it->options[0], 0x4);
+ if (ret)
+ return ret;
- dev->board_ptr = pc236_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 pc236_detach().
- * TODO: Remove the pci_dev_get() and matching pci_dev_put() once
- * support for manual attachment of PCI devices via pc236_attach()
- * has been removed.
- */
- pci_dev_get(pci_dev);
- return pc236_pci_common_attach(dev, pci_dev);
+ return amplc_pc236_common_attach(dev, dev->iobase, it->options[1], 0);
}
-static void pc236_detach(struct comedi_device *dev)
-{
- const struct pc236_board *thisboard = comedi_board(dev);
-
- if (!thisboard)
- return;
- if (dev->iobase)
- pc236_intr_disable(dev);
- if (is_isa_board(thisboard)) {
- comedi_legacy_detach(dev);
- } else if (is_pci_board(thisboard)) {
- struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- if (dev->irq)
- free_irq(dev->irq, dev);
- comedi_pci_disable(dev);
- if (pcidev)
- pci_dev_put(pcidev);
- }
-}
+static const struct pc236_board pc236_boards[] = {
+ {
+ .name = "pc36at",
+ },
+};
-/*
- * 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_pc236_driver = {
- .driver_name = PC236_DRIVER_NAME,
+ .driver_name = "amplc_pc236",
.module = THIS_MODULE,
.attach = pc236_attach,
- .auto_attach = pc236_auto_attach,
- .detach = pc236_detach,
+ .detach = comedi_legacy_detach,
.board_name = &pc236_boards[0].name,
.offset = sizeof(struct pc236_board),
.num_names = ARRAY_SIZE(pc236_boards),
};
-#if DO_PCI
-static const struct pci_device_id pc236_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) },
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, pc236_pci_table);
-
-static int amplc_pc236_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- return comedi_pci_auto_config(dev, &amplc_pc236_driver,
- id->driver_data);
-}
-
-static struct pci_driver amplc_pc236_pci_driver = {
- .name = PC236_DRIVER_NAME,
- .id_table = pc236_pci_table,
- .probe = &amplc_pc236_pci_probe,
- .remove = comedi_pci_auto_unconfig,
-};
-
-module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver);
-#else
module_comedi_driver(amplc_pc236_driver);
-#endif
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Amplicon PC36AT DIO boards");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.h b/drivers/staging/comedi/drivers/amplc_pc236.h
new file mode 100644
index 000000000000..91d6d9c065b5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236.h
@@ -0,0 +1,42 @@
+/*
+ * comedi/drivers/amplc_pc236.h
+ * Header for "amplc_pc236", "amplc_pci236" and "amplc_pc236_common".
+ *
+ * Copyright (C) 2002-2014 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.
+ */
+
+#ifndef AMPLC_PC236_H_INCLUDED
+#define AMPLC_PC236_H_INCLUDED
+
+#include <linux/types.h>
+
+struct comedi_device;
+
+struct pc236_board {
+ const char *name;
+ void (*intr_update_cb)(struct comedi_device *dev, bool enable);
+ bool (*intr_chk_clr_cb)(struct comedi_device *dev);
+};
+
+struct pc236_private {
+ unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
+ bool enable_irq;
+};
+
+int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
+ unsigned int irq, unsigned long req_irq_flags);
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c
new file mode 100644
index 000000000000..18e237cca419
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c
@@ -0,0 +1,206 @@
+/*
+ * comedi/drivers/amplc_pc236_common.c
+ * Common support code for "amplc_pc236" and "amplc_pci236".
+ *
+ * Copyright (C) 2002-2014 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.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include "../comedidev.h"
+
+#include "amplc_pc236.h"
+#include "comedi_fc.h"
+#include "8255.h"
+
+static void pc236_intr_update(struct comedi_device *dev, bool enable)
+{
+ const struct pc236_board *thisboard = comedi_board(dev);
+ struct pc236_private *devpriv = dev->private;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->enable_irq = enable;
+ if (thisboard->intr_update_cb)
+ thisboard->intr_update_cb(dev, enable);
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called when an interrupt occurs to check whether
+ * the interrupt has been marked as enabled and was generated by the
+ * board. If so, the function prepares the hardware for the next
+ * interrupt.
+ * Returns false if the interrupt should be ignored.
+ */
+static bool pc236_intr_check(struct comedi_device *dev)
+{
+ const struct pc236_board *thisboard = comedi_board(dev);
+ struct pc236_private *devpriv = dev->private;
+ bool retval = false;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->spinlock, flags);
+ if (devpriv->enable_irq) {
+ if (thisboard->intr_chk_clr_cb)
+ retval = thisboard->intr_chk_clr_cb(dev);
+ else
+ retval = true;
+ }
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return retval;
+}
+
+static int pc236_intr_insn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data)
+{
+ data[1] = 0;
+ return insn->n;
+}
+
+static int pc236_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);
+ err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+ err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+ err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+ err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+ if (err)
+ return 1;
+
+ /* Step 2a : make sure trigger sources are unique */
+ /* Step 2b : and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* Step 3: check it 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);
+ err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+ if (err)
+ return 3;
+
+ /* step 4: ignored */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ pc236_intr_update(dev, true);
+
+ return 0;
+}
+
+static int pc236_intr_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ pc236_intr_update(dev, false);
+
+ return 0;
+}
+
+static irqreturn_t pc236_interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ bool handled;
+
+ handled = pc236_intr_check(dev);
+ if (dev->attached && handled) {
+ comedi_buf_put(s, 0);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
+ return IRQ_RETVAL(handled);
+}
+
+int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
+ unsigned int irq, unsigned long req_irq_flags)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ dev->iobase = iobase;
+
+ ret = comedi_alloc_subdevices(dev, 2);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[0];
+ /* digital i/o subdevice (8255) */
+ ret = subdev_8255_init(dev, s, NULL, iobase);
+ if (ret)
+ return ret;
+
+ s = &dev->subdevices[1];
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_UNUSED;
+ pc236_intr_update(dev, false);
+ if (irq) {
+ if (request_irq(irq, pc236_interrupt, req_irq_flags,
+ dev->board_name, dev) >= 0) {
+ dev->irq = irq;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pc236_intr_insn;
+ s->len_chanlist = 1;
+ s->do_cmdtest = pc236_intr_cmdtest;
+ s->do_cmd = pc236_intr_cmd;
+ s->cancel = pc236_intr_cancel;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(amplc_pc236_common_attach);
+
+static int __init amplc_pc236_common_init(void)
+{
+ return 0;
+}
+module_init(amplc_pc236_common_init);
+
+static void __exit amplc_pc236_common_exit(void)
+{
+}
+module_exit(amplc_pc236_common_exit);
+
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi helper for amplc_pc236 and amplc_pci236");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index 7c10d28d2784..f8e551d8fd9e 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -36,10 +36,7 @@ The state of the outputs can be read.
#include <linux/module.h>
#include "../comedidev.h"
-#define PC263_DRIVER_NAME "amplc_pc263"
-
/* PC263 registers */
-#define PC263_IO_SIZE 2
/*
* Board descriptions for Amplicon PC263.
@@ -75,7 +72,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], PC263_IO_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
@@ -98,7 +95,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
static struct comedi_driver amplc_pc263_driver = {
- .driver_name = PC263_DRIVER_NAME,
+ .driver_name = "amplc_pc263",
.module = THIS_MODULE,
.attach = pc263_attach,
.detach = comedi_legacy_detach,
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index 339c47c1eb97..45aba1f950fc 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -108,8 +108,6 @@ Caveats:
#include "comedi_fc.h"
#include "8253.h"
-#define DRIVER_NAME "amplc_pci224"
-
/*
* PCI IDs.
*/
@@ -120,7 +118,6 @@ Caveats:
/*
* PCI224/234 i/o space 1 (PCIBAR2) registers.
*/
-#define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
#define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
#define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
#define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
@@ -133,7 +130,6 @@ Caveats:
/*
* PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
*/
-#define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
#define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
#define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
#define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
@@ -354,7 +350,7 @@ static const struct pci224_board pci224_boards[] = {
.ao_bits = 16,
},
{
- .name = DRIVER_NAME,
+ .name = "amplc_pci224",
.devid = PCI_DEVICE_ID_INVALID,
.model = any_model, /* wildcard */
},
@@ -1206,8 +1202,8 @@ static int pci224_attach_common(struct comedi_device *dev,
if (options) {
for (n = 2; n < 3 + s->n_chan; n++) {
if (options[n] < 0 || options[n] > 1) {
- dev_warn(dev->class_dev, DRIVER_NAME
- ": warning! bad options[%u]=%d\n",
+ dev_warn(dev->class_dev,
+ "warning! bad options[%u]=%d\n",
n, options[n]);
}
}
@@ -1237,8 +1233,8 @@ static int pci224_attach_common(struct comedi_device *dev,
devpriv->hwrange = hwrange_pci224_external;
} else {
if (options && options[2] != 0) {
- dev_warn(dev->class_dev, DRIVER_NAME
- ": warning! bad options[2]=%d\n",
+ dev_warn(dev->class_dev,
+ "warning! bad options[2]=%d\n",
options[2]);
}
s->range_table = &range_pci224_internal;
@@ -1250,14 +1246,13 @@ static int pci224_attach_common(struct comedi_device *dev,
if (irq) {
ret = request_irq(irq, pci224_interrupt, IRQF_SHARED,
- DRIVER_NAME, dev);
+ dev->board_name, dev);
if (ret < 0) {
dev_err(dev->class_dev,
"error! unable to allocate irq %u\n", irq);
return ret;
- } else {
- dev->irq = irq;
}
+ dev->irq = irq;
}
return 0;
@@ -1268,7 +1263,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct pci224_private *devpriv;
struct pci_dev *pci_dev;
- dev_info(dev->class_dev, DRIVER_NAME ": attach\n");
+ dev_info(dev->class_dev, "attach\n");
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
@@ -1287,8 +1282,7 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
struct pci224_private *devpriv;
- dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n",
- pci_name(pci_dev));
+ dev_info(dev->class_dev, "attach pci %s\n", pci_name(pci_dev));
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
@@ -1297,7 +1291,7 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused)
dev->board_ptr = pci224_find_pci_board(pci_dev);
if (dev->board_ptr == NULL) {
dev_err(dev->class_dev,
- DRIVER_NAME ": BUG! cannot determine board type!\n");
+ "BUG! cannot determine board type!\n");
return -EINVAL;
}
/*
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
index 3895bc7cb3e3..684275d76e8c 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -1,188 +1,189 @@
- /*
- comedi/drivers/amplc_pci230.c
- Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
-
- Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
-
- 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.
+/*
+ * comedi/drivers/amplc_pci230.c
+ * Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
+ *
+ * Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
+ *
+ * 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.
+ */
- 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.
- */
/*
-Driver: amplc_pci230
-Description: Amplicon PCI230, PCI260 Multifunction I/O boards
-Author: Allan Willcox <allanwillcox@ozemail.com.au>,
- Steve D Sharples <steve.sharples@nottingham.ac.uk>,
- Ian Abbott <abbotti@mev.co.uk>
-Updated: Wed, 22 Oct 2008 12:34:49 +0100
-Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
- PCI230+ (pci230+ or amplc_pci230),
- PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
-Status: works
-
-Configuration options:
- [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.
-
-Configuring a "amplc_pci230" will match any supported card and it will
-choose the best match, picking the "+" models if possible. Configuring
-a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
-a PCI230. Configuring a "pci260" will match a PCI260 or PCI260+ card
-and it will be treated as a PCI260. Configuring a "pci230+" will match
-a PCI230+ card. Configuring a "pci260+" will match a PCI260+ card.
-
-Subdevices:
-
- PCI230(+) PCI260(+)
- --------- ---------
- Subdevices 3 1
- 0 AI AI
- 1 AO
- 2 DIO
-
-AI Subdevice:
-
- The AI subdevice has 16 single-ended channels or 8 differential
- channels.
-
- The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
- PCI260+ cards have 16-bit resolution.
-
- For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
- inputs 14 and 15 for channel 7). If the card is physically a PCI230
- or PCI260 then it actually uses a "pseudo-differential" mode where the
- inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
- use true differential sampling. Another difference is that if the
- card is physically a PCI230 or PCI260, the inverting input is 2N,
- whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
- PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
- PCI260+) and differential mode is used, the differential inputs need
- to be physically swapped on the connector.
-
- The following input ranges are supported:
-
- 0 => [-10, +10] V
- 1 => [-5, +5] V
- 2 => [-2.5, +2.5] V
- 3 => [-1.25, +1.25] V
- 4 => [0, 10] V
- 5 => [0, 5] V
- 6 => [0, 2.5] V
-
-AI Commands:
-
- +=========+==============+===========+============+==========+
- |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
- +=========+==============+===========+============+==========+
- |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
- |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
- | | |TRIG_INT | | |
- | |--------------|-----------| | |
- | | TRIG_TIMER(1)|TRIG_TIMER | | |
- | | TRIG_EXT(2) | | | |
- | | TRIG_INT | | | |
- +---------+--------------+-----------+------------+----------+
-
- Note 1: If AI command and AO command are used simultaneously, only
- one may have scan_begin_src == TRIG_TIMER.
-
- Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
- DIO channel 16 (pin 49) which will need to be configured as
- a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
- (pin 17) is used instead. For PCI230, scan_begin_src ==
- TRIG_EXT is not supported. The trigger is a rising edge
- on the input.
-
- Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
- (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
- convert_arg value is interpreted as follows:
-
- convert_arg == (CR_EDGE | 0) => rising edge
- convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
- convert_arg == 0 => falling edge (backwards compatibility)
- convert_arg == 1 => rising edge (backwards compatibility)
-
- All entries in the channel list must use the same analogue reference.
- If the analogue reference is not AREF_DIFF (not differential) each
- pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
- input range. The input ranges used in the sequence must be all
- bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
- sequence must consist of 1 or more identical subsequences. Within the
- subsequence, channels must be in ascending order with no repeated
- channels. For example, the following sequences are valid: 0 1 2 3
- (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
- subsequence), 1 1 1 1 (repeated valid subsequence). The following
- sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
- (incompletely repeated subsequence). Some versions of the PCI230+ and
- PCI260+ have a bug that requires a subsequence longer than one entry
- long to include channel 0.
-
-AO Subdevice:
-
- The AO subdevice has 2 channels with 12-bit resolution.
-
- The following output ranges are supported:
-
- 0 => [0, 10] V
- 1 => [-10, +10] V
-
-AO Commands:
-
- +=========+==============+===========+============+==========+
- |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
- +=========+==============+===========+============+==========+
- |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
- | | TRIG_EXT(2) | | |TRIG_COUNT|
- | | TRIG_INT | | | |
- +---------+--------------+-----------+------------+----------+
-
- Note 1: If AI command and AO command are used simultaneously, only
- one may have scan_begin_src == TRIG_TIMER.
-
- Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
- configured as a PCI230+ and is only supported on later
- versions of the card. As a card configured as a PCI230+ is
- not guaranteed to support external triggering, please consider
- this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
- input (PCI230+ pin 25). Triggering will be on the rising edge
- unless the CR_INVERT flag is set in scan_begin_arg.
-
- The channels in the channel sequence must be in ascending order with
- no repeats. All entries in the channel sequence must use the same
- output range.
-
-DIO Subdevice:
-
- The DIO subdevice 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 chip is supported.
-
- Bit 0 of port C (DIO channel 16) is also used as an external scan
- trigger input for AI commands on PCI230 and PCI230+, so would need to
- be configured as an input to use it for that purpose.
-*/
+ * Driver: amplc_pci230
+ * Description: Amplicon PCI230, PCI260 Multifunction I/O boards
+ * Author: Allan Willcox <allanwillcox@ozemail.com.au>,
+ * Steve D Sharples <steve.sharples@nottingham.ac.uk>,
+ * Ian Abbott <abbotti@mev.co.uk>
+ * Updated: Wed, 22 Oct 2008 12:34:49 +0100
+ * Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
+ * PCI230+ (pci230+ or amplc_pci230),
+ * PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
+ * Status: works
+ *
+ * Configuration options:
+ * [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.
+ *
+ * Configuring a "amplc_pci230" will match any supported card and it will
+ * choose the best match, picking the "+" models if possible. Configuring
+ * a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
+ * a PCI230. Configuring a "pci260" will match a PCI260 or PCI260+ card
+ * and it will be treated as a PCI260. Configuring a "pci230+" will match
+ * a PCI230+ card. Configuring a "pci260+" will match a PCI260+ card.
+ *
+ * Subdevices:
+ *
+ * PCI230(+) PCI260(+)
+ * --------- ---------
+ * Subdevices 3 1
+ * 0 AI AI
+ * 1 AO
+ * 2 DIO
+ *
+ * AI Subdevice:
+ *
+ * The AI subdevice has 16 single-ended channels or 8 differential
+ * channels.
+ *
+ * The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
+ * PCI260+ cards have 16-bit resolution.
+ *
+ * For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
+ * inputs 14 and 15 for channel 7). If the card is physically a PCI230
+ * or PCI260 then it actually uses a "pseudo-differential" mode where the
+ * inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
+ * use true differential sampling. Another difference is that if the
+ * card is physically a PCI230 or PCI260, the inverting input is 2N,
+ * whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
+ * PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
+ * PCI260+) and differential mode is used, the differential inputs need
+ * to be physically swapped on the connector.
+ *
+ * The following input ranges are supported:
+ *
+ * 0 => [-10, +10] V
+ * 1 => [-5, +5] V
+ * 2 => [-2.5, +2.5] V
+ * 3 => [-1.25, +1.25] V
+ * 4 => [0, 10] V
+ * 5 => [0, 5] V
+ * 6 => [0, 2.5] V
+ *
+ * AI Commands:
+ *
+ * +=========+==============+===========+============+==========+
+ * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ * +=========+==============+===========+============+==========+
+ * |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
+ * |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
+ * | | |TRIG_INT | | |
+ * | |--------------|-----------| | |
+ * | | TRIG_TIMER(1)|TRIG_TIMER | | |
+ * | | TRIG_EXT(2) | | | |
+ * | | TRIG_INT | | | |
+ * +---------+--------------+-----------+------------+----------+
+ *
+ * Note 1: If AI command and AO command are used simultaneously, only
+ * one may have scan_begin_src == TRIG_TIMER.
+ *
+ * Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
+ * DIO channel 16 (pin 49) which will need to be configured as
+ * a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
+ * (pin 17) is used instead. For PCI230, scan_begin_src ==
+ * TRIG_EXT is not supported. The trigger is a rising edge
+ * on the input.
+ *
+ * Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
+ * (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
+ * convert_arg value is interpreted as follows:
+ *
+ * convert_arg == (CR_EDGE | 0) => rising edge
+ * convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
+ * convert_arg == 0 => falling edge (backwards compatibility)
+ * convert_arg == 1 => rising edge (backwards compatibility)
+ *
+ * All entries in the channel list must use the same analogue reference.
+ * If the analogue reference is not AREF_DIFF (not differential) each
+ * pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
+ * input range. The input ranges used in the sequence must be all
+ * bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
+ * sequence must consist of 1 or more identical subsequences. Within the
+ * subsequence, channels must be in ascending order with no repeated
+ * channels. For example, the following sequences are valid: 0 1 2 3
+ * (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
+ * subsequence), 1 1 1 1 (repeated valid subsequence). The following
+ * sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
+ * (incompletely repeated subsequence). Some versions of the PCI230+ and
+ * PCI260+ have a bug that requires a subsequence longer than one entry
+ * long to include channel 0.
+ *
+ * AO Subdevice:
+ *
+ * The AO subdevice has 2 channels with 12-bit resolution.
+ * The following output ranges are supported:
+ * 0 => [0, 10] V
+ * 1 => [-10, +10] V
+ *
+ * AO Commands:
+ *
+ * +=========+==============+===========+============+==========+
+ * |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ * +=========+==============+===========+============+==========+
+ * |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
+ * | | TRIG_EXT(2) | | |TRIG_COUNT|
+ * | | TRIG_INT | | | |
+ * +---------+--------------+-----------+------------+----------+
+ *
+ * Note 1: If AI command and AO command are used simultaneously, only
+ * one may have scan_begin_src == TRIG_TIMER.
+ *
+ * Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
+ * configured as a PCI230+ and is only supported on later
+ * versions of the card. As a card configured as a PCI230+ is
+ * not guaranteed to support external triggering, please consider
+ * this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
+ * input (PCI230+ pin 25). Triggering will be on the rising edge
+ * unless the CR_INVERT flag is set in scan_begin_arg.
+ *
+ * The channels in the channel sequence must be in ascending order with
+ * no repeats. All entries in the channel sequence must use the same
+ * output range.
+ *
+ * DIO Subdevice:
+ *
+ * The DIO subdevice 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 chip is supported.
+ *
+ * Bit 0 of port C (DIO channel 16) is also used as an external scan
+ * trigger input for AI commands on PCI230 and PCI230+, so would need to
+ * be configured as an input to use it for that purpose.
+ */
+
/*
-Extra triggered scan functionality, interrupt bug-fix added by Steve Sharples.
-Support for PCI230+/260+, more triggered scan functionality, and workarounds
-for (or detection of) various hardware problems added by Ian Abbott.
-*/
+ * Extra triggered scan functionality, interrupt bug-fix added by Steve
+ * Sharples. Support for PCI230+/260+, more triggered scan functionality,
+ * and workarounds for (or detection of) various hardware problems added
+ * by Ian Abbott.
+ */
#include <linux/module.h>
#include <linux/pci.h>
@@ -195,15 +196,16 @@ for (or detection of) various hardware problems added by Ian Abbott.
#include "8253.h"
#include "8255.h"
-/* PCI230 PCI configuration register information */
+/*
+ * PCI230 PCI configuration register information
+ */
#define PCI_DEVICE_ID_PCI230 0x0000
#define PCI_DEVICE_ID_PCI260 0x0006
#define PCI_DEVICE_ID_INVALID 0xffff
-#define PCI230_IO1_SIZE 32 /* Size of I/O space 1 */
-#define PCI230_IO2_SIZE 16 /* Size of I/O space 2 */
-
-/* PCI230 i/o space 1 registers. */
+/*
+ * PCI230 i/o space 1 registers.
+ */
#define PCI230_PPI_X_BASE 0x00 /* User PPI (82C55) base */
#define PCI230_PPI_X_A 0x00 /* User PPI (82C55) port A */
#define PCI230_PPI_X_B 0x01 /* User PPI (82C55) port B */
@@ -219,7 +221,9 @@ for (or detection of) various hardware problems added by Ian Abbott.
#define PCI230_INT_SCE 0x1E /* Interrupt source mask (w) */
#define PCI230_INT_STAT 0x1E /* Interrupt status (r) */
-/* PCI230 i/o space 2 registers. */
+/*
+ * PCI230 i/o space 2 registers.
+ */
#define PCI230_DACCON 0x00 /* DAC control */
#define PCI230_DACOUT1 0x02 /* DAC channel 0 (w) */
#define PCI230_DACOUT2 0x04 /* DAC channel 1 (w) (not FIFO mode) */
@@ -242,57 +246,64 @@ for (or detection of) various hardware problems added by Ian Abbott.
#define PCI230P2_DACSWTRIG 0x02 /* DAC soft trigger (FIFO mode) (r) */
#define PCI230P2_DACEN 0x06 /* DAC channel enable (FIFO mode) */
-/* Convertor related constants. */
-#define PCI230_DAC_SETTLE 5 /* Analogue output settling time in µs */
- /* (DAC itself is 1µs nominally). */
-#define PCI230_ADC_SETTLE 1 /* Analogue input settling time in µs */
- /* (ADC itself is 1.6µs nominally but we poll
- * anyway). */
-#define PCI230_MUX_SETTLE 10 /* ADC MUX settling time in µS */
- /* - 10µs for se, 20µs de. */
-
-/* DACCON read-write values. */
-#define PCI230_DAC_OR_UNI (0<<0) /* Output range unipolar */
-#define PCI230_DAC_OR_BIP (1<<0) /* Output range bipolar */
-#define PCI230_DAC_OR_MASK (1<<0)
-/* The following applies only if DAC FIFO support is enabled in the EXTFUNC
- * register (and only for PCI230+ hardware version 2 onwards). */
-#define PCI230P2_DAC_FIFO_EN (1<<8) /* FIFO enable */
-/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards). */
-#define PCI230P2_DAC_TRIG_NONE (0<<2) /* No trigger */
-#define PCI230P2_DAC_TRIG_SW (1<<2) /* Software trigger trigger */
-#define PCI230P2_DAC_TRIG_EXTP (2<<2) /* EXTTRIG +ve edge trigger */
-#define PCI230P2_DAC_TRIG_EXTN (3<<2) /* EXTTRIG -ve edge trigger */
-#define PCI230P2_DAC_TRIG_Z2CT0 (4<<2) /* CT0-OUT +ve edge trigger */
-#define PCI230P2_DAC_TRIG_Z2CT1 (5<<2) /* CT1-OUT +ve edge trigger */
-#define PCI230P2_DAC_TRIG_Z2CT2 (6<<2) /* CT2-OUT +ve edge trigger */
-#define PCI230P2_DAC_TRIG_MASK (7<<2)
-#define PCI230P2_DAC_FIFO_WRAP (1<<7) /* FIFO wraparound mode */
-#define PCI230P2_DAC_INT_FIFO_EMPTY (0<<9) /* FIFO interrupt empty */
-#define PCI230P2_DAC_INT_FIFO_NEMPTY (1<<9)
-#define PCI230P2_DAC_INT_FIFO_NHALF (2<<9) /* FIFO intr not half full */
-#define PCI230P2_DAC_INT_FIFO_HALF (3<<9)
-#define PCI230P2_DAC_INT_FIFO_NFULL (4<<9) /* FIFO interrupt not full */
-#define PCI230P2_DAC_INT_FIFO_FULL (5<<9)
-#define PCI230P2_DAC_INT_FIFO_MASK (7<<9)
-
-/* DACCON read-only values. */
-#define PCI230_DAC_BUSY (1<<1) /* DAC busy. */
-/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards). */
-#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1<<5) /* Underrun error */
-#define PCI230P2_DAC_FIFO_EMPTY (1<<13) /* FIFO empty */
-#define PCI230P2_DAC_FIFO_FULL (1<<14) /* FIFO full */
-#define PCI230P2_DAC_FIFO_HALF (1<<15) /* FIFO half full */
-
-/* DACCON write-only, transient values. */
-/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
- * hardware version 2 onwards). */
-#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1<<5) /* Clear underrun */
-#define PCI230P2_DAC_FIFO_RESET (1<<12) /* FIFO reset */
-
-/* PCI230+ hardware version 2 DAC FIFO levels. */
+/*
+ * DACCON read-write values.
+ */
+#define PCI230_DAC_OR_UNI (0 << 0) /* Output range unipolar */
+#define PCI230_DAC_OR_BIP (1 << 0) /* Output range bipolar */
+#define PCI230_DAC_OR_MASK (1 << 0)
+/*
+ * The following applies only if DAC FIFO support is enabled in the EXTFUNC
+ * register (and only for PCI230+ hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_FIFO_EN (1 << 8) /* FIFO enable */
+/*
+ * The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_TRIG_NONE (0 << 2) /* No trigger */
+#define PCI230P2_DAC_TRIG_SW (1 << 2) /* Software trigger trigger */
+#define PCI230P2_DAC_TRIG_EXTP (2 << 2) /* EXTTRIG +ve edge trigger */
+#define PCI230P2_DAC_TRIG_EXTN (3 << 2) /* EXTTRIG -ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT0 (4 << 2) /* CT0-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT1 (5 << 2) /* CT1-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT2 (6 << 2) /* CT2-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_MASK (7 << 2)
+#define PCI230P2_DAC_FIFO_WRAP (1 << 7) /* FIFO wraparound mode */
+#define PCI230P2_DAC_INT_FIFO_EMPTY (0 << 9) /* FIFO interrupt empty */
+#define PCI230P2_DAC_INT_FIFO_NEMPTY (1 << 9)
+#define PCI230P2_DAC_INT_FIFO_NHALF (2 << 9) /* FIFO intr not half full */
+#define PCI230P2_DAC_INT_FIFO_HALF (3 << 9)
+#define PCI230P2_DAC_INT_FIFO_NFULL (4 << 9) /* FIFO interrupt not full */
+#define PCI230P2_DAC_INT_FIFO_FULL (5 << 9)
+#define PCI230P2_DAC_INT_FIFO_MASK (7 << 9)
+
+/*
+ * DACCON read-only values.
+ */
+#define PCI230_DAC_BUSY (1 << 1) /* DAC busy. */
+/*
+ * The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1 << 5) /* Underrun error */
+#define PCI230P2_DAC_FIFO_EMPTY (1 << 13) /* FIFO empty */
+#define PCI230P2_DAC_FIFO_FULL (1 << 14) /* FIFO full */
+#define PCI230P2_DAC_FIFO_HALF (1 << 15) /* FIFO half full */
+
+/*
+ * DACCON write-only, transient values.
+ */
+/*
+ * The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards).
+ */
+#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1 << 5) /* Clear underrun */
+#define PCI230P2_DAC_FIFO_RESET (1 << 12) /* FIFO reset */
+
+/*
+ * PCI230+ hardware version 2 DAC FIFO levels.
+ */
#define PCI230P2_DAC_FIFOLEVEL_HALF 512
#define PCI230P2_DAC_FIFOLEVEL_FULL 1024
/* Free space in DAC FIFO. */
@@ -302,56 +313,62 @@ for (or detection of) various hardware problems added by Ian Abbott.
#define PCI230P2_DAC_FIFOROOM_HALFTOFULL 1
#define PCI230P2_DAC_FIFOROOM_FULL 0
-/* ADCCON read/write values. */
-#define PCI230_ADC_TRIG_NONE (0<<0) /* No trigger */
-#define PCI230_ADC_TRIG_SW (1<<0) /* Software trigger trigger */
-#define PCI230_ADC_TRIG_EXTP (2<<0) /* EXTTRIG +ve edge trigger */
-#define PCI230_ADC_TRIG_EXTN (3<<0) /* EXTTRIG -ve edge trigger */
-#define PCI230_ADC_TRIG_Z2CT0 (4<<0) /* CT0-OUT +ve edge trigger */
-#define PCI230_ADC_TRIG_Z2CT1 (5<<0) /* CT1-OUT +ve edge trigger */
-#define PCI230_ADC_TRIG_Z2CT2 (6<<0) /* CT2-OUT +ve edge trigger */
-#define PCI230_ADC_TRIG_MASK (7<<0)
-#define PCI230_ADC_IR_UNI (0<<3) /* Input range unipolar */
-#define PCI230_ADC_IR_BIP (1<<3) /* Input range bipolar */
-#define PCI230_ADC_IR_MASK (1<<3)
-#define PCI230_ADC_IM_SE (0<<4) /* Input mode single ended */
-#define PCI230_ADC_IM_DIF (1<<4) /* Input mode differential */
-#define PCI230_ADC_IM_MASK (1<<4)
-#define PCI230_ADC_FIFO_EN (1<<8) /* FIFO enable */
-#define PCI230_ADC_INT_FIFO_EMPTY (0<<9)
-#define PCI230_ADC_INT_FIFO_NEMPTY (1<<9) /* FIFO interrupt not empty */
-#define PCI230_ADC_INT_FIFO_NHALF (2<<9)
-#define PCI230_ADC_INT_FIFO_HALF (3<<9) /* FIFO interrupt half full */
-#define PCI230_ADC_INT_FIFO_NFULL (4<<9)
-#define PCI230_ADC_INT_FIFO_FULL (5<<9) /* FIFO interrupt full */
-#define PCI230P_ADC_INT_FIFO_THRESH (7<<9) /* FIFO interrupt threshold */
-#define PCI230_ADC_INT_FIFO_MASK (7<<9)
-
-/* ADCCON write-only, transient values. */
-#define PCI230_ADC_FIFO_RESET (1<<12) /* FIFO reset */
-#define PCI230_ADC_GLOB_RESET (1<<13) /* Global reset */
-
-/* ADCCON read-only values. */
-#define PCI230_ADC_BUSY (1<<15) /* ADC busy */
-#define PCI230_ADC_FIFO_EMPTY (1<<12) /* FIFO empty */
-#define PCI230_ADC_FIFO_FULL (1<<13) /* FIFO full */
-#define PCI230_ADC_FIFO_HALF (1<<14) /* FIFO half full */
-#define PCI230_ADC_FIFO_FULL_LATCHED (1<<5) /* Indicates overrun occurred */
-
-/* PCI230 ADC FIFO levels. */
+/*
+ * ADCCON read/write values.
+ */
+#define PCI230_ADC_TRIG_NONE (0 << 0) /* No trigger */
+#define PCI230_ADC_TRIG_SW (1 << 0) /* Software trigger trigger */
+#define PCI230_ADC_TRIG_EXTP (2 << 0) /* EXTTRIG +ve edge trigger */
+#define PCI230_ADC_TRIG_EXTN (3 << 0) /* EXTTRIG -ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT0 (4 << 0) /* CT0-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT1 (5 << 0) /* CT1-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT2 (6 << 0) /* CT2-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_MASK (7 << 0)
+#define PCI230_ADC_IR_UNI (0 << 3) /* Input range unipolar */
+#define PCI230_ADC_IR_BIP (1 << 3) /* Input range bipolar */
+#define PCI230_ADC_IR_MASK (1 << 3)
+#define PCI230_ADC_IM_SE (0 << 4) /* Input mode single ended */
+#define PCI230_ADC_IM_DIF (1 << 4) /* Input mode differential */
+#define PCI230_ADC_IM_MASK (1 << 4)
+#define PCI230_ADC_FIFO_EN (1 << 8) /* FIFO enable */
+#define PCI230_ADC_INT_FIFO_EMPTY (0 << 9)
+#define PCI230_ADC_INT_FIFO_NEMPTY (1 << 9) /* FIFO interrupt not empty */
+#define PCI230_ADC_INT_FIFO_NHALF (2 << 9)
+#define PCI230_ADC_INT_FIFO_HALF (3 << 9) /* FIFO interrupt half full */
+#define PCI230_ADC_INT_FIFO_NFULL (4 << 9)
+#define PCI230_ADC_INT_FIFO_FULL (5 << 9) /* FIFO interrupt full */
+#define PCI230P_ADC_INT_FIFO_THRESH (7 << 9) /* FIFO interrupt threshold */
+#define PCI230_ADC_INT_FIFO_MASK (7 << 9)
+
+/*
+ * ADCCON write-only, transient values.
+ */
+#define PCI230_ADC_FIFO_RESET (1 << 12) /* FIFO reset */
+#define PCI230_ADC_GLOB_RESET (1 << 13) /* Global reset */
+
+/*
+ * ADCCON read-only values.
+ */
+#define PCI230_ADC_BUSY (1 << 15) /* ADC busy */
+#define PCI230_ADC_FIFO_EMPTY (1 << 12) /* FIFO empty */
+#define PCI230_ADC_FIFO_FULL (1 << 13) /* FIFO full */
+#define PCI230_ADC_FIFO_HALF (1 << 14) /* FIFO half full */
+#define PCI230_ADC_FIFO_FULL_LATCHED (1 << 5) /* FIFO overrun occurred */
+
+/*
+ * PCI230 ADC FIFO levels.
+ */
#define PCI230_ADC_FIFOLEVEL_HALFFULL 2049 /* Value for FIFO half full */
#define PCI230_ADC_FIFOLEVEL_FULL 4096 /* FIFO size */
-/* Value to write to ADCSWTRIG to trigger ADC conversion in software trigger
- * mode. Can be anything. */
-#define PCI230_ADC_CONV 0xffff
-
-/* PCI230+ EXTFUNC values. */
-#define PCI230P_EXTFUNC_GAT_EXTTRIG (1<<0)
- /* Route EXTTRIG pin to external gate inputs. */
+/*
+ * PCI230+ EXTFUNC values.
+ */
+/* Route EXTTRIG pin to external gate inputs. */
+#define PCI230P_EXTFUNC_GAT_EXTTRIG (1 << 0)
/* PCI230+ hardware version 2 values. */
-#define PCI230P2_EXTFUNC_DACFIFO (1<<1)
- /* Allow DAC FIFO to be enabled. */
+/* Allow DAC FIFO to be enabled. */
+#define PCI230P2_EXTFUNC_DACFIFO (1 << 1)
/*
* Counter/timer clock input configuration sources.
@@ -395,19 +412,20 @@ for (or detection of) various hardware problems added by Ian Abbott.
* Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
*/
-/* Interrupt enables/status register values. */
+/*
+ * Interrupt enables/status register values.
+ */
#define PCI230_INT_DISABLE 0
-#define PCI230_INT_PPI_C0 (1<<0)
-#define PCI230_INT_PPI_C3 (1<<1)
-#define PCI230_INT_ADC (1<<2)
-#define PCI230_INT_ZCLK_CT1 (1<<5)
+#define PCI230_INT_PPI_C0 (1 << 0)
+#define PCI230_INT_PPI_C3 (1 << 1)
+#define PCI230_INT_ADC (1 << 2)
+#define PCI230_INT_ZCLK_CT1 (1 << 5)
/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
-#define PCI230P2_INT_DAC (1<<4)
-
-#define PCI230_TEST_BIT(val, n) ((val>>n)&1)
- /* Assumes bits numbered with zero offset, ie. 0-15 */
+#define PCI230P2_INT_DAC (1 << 4)
-/* (Potentially) shared resources and their owners */
+/*
+ * (Potentially) shared resources and their owners
+ */
enum {
RES_Z2CT0, /* Z2-CT0 */
RES_Z2CT1, /* Z2-CT1 */
@@ -449,83 +467,70 @@ struct pci230_board {
int have_dio;
unsigned int min_hwver; /* Minimum hardware version supported. */
};
+
static const struct pci230_board pci230_boards[] = {
{
- .name = "pci230+",
- .id = PCI_DEVICE_ID_PCI230,
- .ai_chans = 16,
- .ai_bits = 16,
- .ao_chans = 2,
- .ao_bits = 12,
- .have_dio = 1,
- .min_hwver = 1,
- },
+ .name = "pci230+",
+ .id = PCI_DEVICE_ID_PCI230,
+ .ai_chans = 16,
+ .ai_bits = 16,
+ .ao_chans = 2,
+ .ao_bits = 12,
+ .have_dio = 1,
+ .min_hwver = 1,
+ },
{
- .name = "pci260+",
- .id = PCI_DEVICE_ID_PCI260,
- .ai_chans = 16,
- .ai_bits = 16,
- .ao_chans = 0,
- .ao_bits = 0,
- .have_dio = 0,
- .min_hwver = 1,
- },
+ .name = "pci260+",
+ .id = PCI_DEVICE_ID_PCI260,
+ .ai_chans = 16,
+ .ai_bits = 16,
+ .min_hwver = 1,
+ },
{
- .name = "pci230",
- .id = PCI_DEVICE_ID_PCI230,
- .ai_chans = 16,
- .ai_bits = 12,
- .ao_chans = 2,
- .ao_bits = 12,
- .have_dio = 1,
- },
+ .name = "pci230",
+ .id = PCI_DEVICE_ID_PCI230,
+ .ai_chans = 16,
+ .ai_bits = 12,
+ .ao_chans = 2,
+ .ao_bits = 12,
+ .have_dio = 1,
+ },
{
- .name = "pci260",
- .id = PCI_DEVICE_ID_PCI260,
- .ai_chans = 16,
- .ai_bits = 12,
- .ao_chans = 0,
- .ao_bits = 0,
- .have_dio = 0,
- },
+ .name = "pci260",
+ .id = PCI_DEVICE_ID_PCI260,
+ .ai_chans = 16,
+ .ai_bits = 12,
+ },
{
- .name = "amplc_pci230", /* Wildcard matches any above */
- .id = PCI_DEVICE_ID_INVALID,
- },
+ /* Wildcard matches any above */
+ .name = "amplc_pci230",
+ .id = PCI_DEVICE_ID_INVALID,
+ },
};
-/* 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 pci230_private {
spinlock_t isr_spinlock; /* Interrupt spin lock */
spinlock_t res_spinlock; /* Shared resources spin lock */
spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */
spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */
- unsigned long state; /* State flags */
- unsigned long iobase1; /* PCI230's I/O space 1 */
+ unsigned long state; /* State flags */
+ unsigned long iobase1; /* PCI230's I/O space 1 */
unsigned int ao_readback[2]; /* Used for AO readback */
- unsigned int ai_scan_count; /* Number of analogue input scans
- * remaining. */
- unsigned int ai_scan_pos; /* Current position within analogue
- * input scan */
- unsigned int ao_scan_count; /* Number of analogue output scans
- * remaining. */
- int intr_cpuid; /* ID of CPU running interrupt routine. */
- unsigned short hwver; /* Hardware version (for '+' models). */
- unsigned short adccon; /* ADCCON register value. */
- unsigned short daccon; /* DACCON register value. */
- unsigned short adcfifothresh; /* ADC FIFO programmable interrupt
- * level threshold (PCI230+/260+). */
- unsigned short adcg; /* ADCG register value. */
- unsigned char int_en; /* Interrupt enables bits. */
- unsigned char ai_bipolar; /* Set if bipolar input range so we
- * know to mangle it. */
- unsigned char ao_bipolar; /* Set if bipolar output range so we
- * know to mangle it. */
- unsigned char ier; /* Copy of interrupt enables/status register. */
- unsigned char intr_running; /* Flag set in interrupt routine. */
- unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners. */
+ unsigned int ai_scan_count; /* Number of AI scans remaining */
+ unsigned int ai_scan_pos; /* Current position within AI scan */
+ unsigned int ao_scan_count; /* Number of AO scans remaining. */
+ int intr_cpuid; /* ID of CPU running ISR */
+ unsigned short hwver; /* Hardware version (for '+' models) */
+ unsigned short adccon; /* ADCCON register value */
+ unsigned short daccon; /* DACCON register value */
+ unsigned short adcfifothresh; /* ADC FIFO threshold (PCI230+/260+) */
+ unsigned short adcg; /* ADCG register value */
+ unsigned char int_en; /* Interrupt enable bits */
+ unsigned char ai_bipolar; /* Flag AI range is bipolar */
+ unsigned char ao_bipolar; /* Flag AO range is bipolar */
+ unsigned char ier; /* Copy of interrupt enable register */
+ unsigned char intr_running; /* Flag set in interrupt routine */
+ unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners */
};
/* PCI230 clock source periods in ns */
@@ -575,13 +580,16 @@ static unsigned short pci230_ai_read(struct comedi_device *dev)
/* Read sample. */
data = inw(dev->iobase + PCI230_ADCDATA);
- /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
- * four bits reserved for expansion). */
- /* PCI230+ is 16 bit AI. */
+ /*
+ * PCI230 is 12 bit - stored in upper bits of 16 bit register
+ * (lower four bits reserved for expansion). PCI230+ is 16 bit AI.
+ */
data = data >> (16 - thisboard->ai_bits);
- /* If a bipolar range was specified, mangle it (twos
- * complement->straight binary). */
+ /*
+ * If a bipolar range was specified, mangle it
+ * (twos complement->straight binary).
+ */
if (devpriv->ai_bipolar)
data ^= 1 << (thisboard->ai_bits - 1);
@@ -594,14 +602,17 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
const struct pci230_board *thisboard = comedi_board(dev);
struct pci230_private *devpriv = dev->private;
- /* If a bipolar range was specified, mangle it (straight binary->twos
- * complement). */
+ /*
+ * If a bipolar range was specified, mangle it
+ * (straight binary->twos complement).
+ */
if (devpriv->ao_bipolar)
datum ^= 1 << (thisboard->ao_bits - 1);
- /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
- * four bits reserved for expansion). */
- /* PCI230+ is also 12 bit AO. */
+ /*
+ * PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+ * four bits reserved for expansion). PCI230+ is also 12 bit AO.
+ */
datum <<= (16 - thisboard->ao_bits);
return datum;
}
@@ -616,10 +627,8 @@ static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
devpriv->ao_readback[chan] = datum;
/* Write mangled datum to appropriate DACOUT register. */
- outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
- ? PCI230_DACOUT1
- :
- PCI230_DACOUT2));
+ outw(pci230_ao_mangle_datum(dev, datum),
+ dev->iobase + (((chan) == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2));
}
static inline void pci230_ao_write_fifo(struct comedi_device *dev,
@@ -648,18 +657,17 @@ static int get_resources(struct comedi_device *dev, unsigned int res_mask,
ok = 1;
claimed = 0;
spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
- for (b = 1, i = 0; (i < NUM_RESOURCES)
- && (res_mask != 0); b <<= 1, i++) {
- if ((res_mask & b) != 0) {
+ for (b = 1, i = 0; (i < NUM_RESOURCES) && res_mask; b <<= 1, i++) {
+ if (res_mask & b) {
res_mask &= ~b;
if (devpriv->res_owner[i] == OWNER_NONE) {
devpriv->res_owner[i] = owner;
claimed |= b;
} else if (devpriv->res_owner[i] != owner) {
- for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
- if ((claimed & b) != 0) {
- devpriv->res_owner[i]
- = OWNER_NONE;
+ for (b = 1, i = 0; claimed; b <<= 1, i++) {
+ if (claimed & b) {
+ devpriv->res_owner[i] =
+ OWNER_NONE;
claimed &= ~b;
}
}
@@ -687,13 +695,11 @@ static void put_resources(struct comedi_device *dev, unsigned int res_mask,
unsigned long irqflags;
spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
- for (b = 1, i = 0; (i < NUM_RESOURCES)
- && (res_mask != 0); b <<= 1, i++) {
- if ((res_mask & b) != 0) {
+ for (b = 1, i = 0; (i < NUM_RESOURCES) && res_mask; b <<= 1, i++) {
+ if (res_mask & b) {
res_mask &= ~b;
if (devpriv->res_owner[i] == owner)
devpriv->res_owner[i] = OWNER_NONE;
-
}
}
spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
@@ -712,15 +718,14 @@ static inline void put_all_resources(struct comedi_device *dev,
}
static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
- unsigned int round_mode)
+ unsigned int flags)
{
uint64_t div;
unsigned int rem;
div = ns;
rem = do_div(div, timebase);
- round_mode &= TRIG_ROUND_MASK;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
default:
case TRIG_ROUND_NEAREST:
div += (rem + (timebase / 2)) / timebase;
@@ -734,36 +739,36 @@ static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
}
-/* Given desired period in ns, returns the required internal clock source
- * and gets the initial count. */
+/*
+ * Given desired period in ns, returns the required internal clock source
+ * and gets the initial count.
+ */
static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
- unsigned int round_mode)
+ unsigned int flags)
{
unsigned int clk_src, cnt;
for (clk_src = CLK_10MHZ;; clk_src++) {
- cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
+ cnt = divide_ns(ns, pci230_timebase[clk_src], flags);
if ((cnt <= 65536) || (clk_src == CLK_1KHZ))
break;
-
}
*count = cnt;
return clk_src;
}
-static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int flags)
{
unsigned int count;
unsigned int clk_src;
- clk_src = pci230_choose_clk_count(*ns, &count, round);
+ clk_src = pci230_choose_clk_count(*ns, &count, flags);
*ns = count * pci230_timebase[clk_src];
- return;
}
static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
unsigned int mode, uint64_t ns,
- unsigned int round)
+ unsigned int flags)
{
struct pci230_private *devpriv = dev->private;
unsigned int clk_src;
@@ -772,7 +777,7 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
/* Set mode. */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
/* Determine clock source and count. */
- clk_src = pci230_choose_clk_count(ns, &count, round);
+ clk_src = pci230_choose_clk_count(ns, &count, flags);
/* Program clock source. */
outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
/* Set initial count. */
@@ -829,7 +834,8 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
}
}
- /* Use Z2-CT2 as a conversion trigger instead of the built-in
+ /*
+ * Use Z2-CT2 as a conversion trigger instead of the built-in
* software trigger, as otherwise triggering of differential channels
* doesn't work properly for some versions of PCI230/260. Also set
* FIFO mode because the ADC busy bit only works for software triggers.
@@ -842,12 +848,16 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
/* Differential. */
gainshift = chan * 2;
if (devpriv->hwver == 0) {
- /* Original PCI230/260 expects both inputs of the
- * differential channel to be enabled. */
+ /*
+ * Original PCI230/260 expects both inputs of the
+ * differential channel to be enabled.
+ */
adcen = 3 << gainshift;
} else {
- /* PCI230+/260+ expects only one input of the
- * differential channel to be enabled. */
+ /*
+ * PCI230+/260+ expects only one input of the
+ * differential channel to be enabled.
+ */
adcen = 1 << gainshift;
}
adccon |= PCI230_ADC_IM_DIF;
@@ -857,16 +867,18 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
gainshift = chan & ~1;
adccon |= PCI230_ADC_IM_SE;
}
- devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
- | (pci230_ai_gain[range] << gainshift);
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
+ (pci230_ai_gain[range] << gainshift);
if (devpriv->ai_bipolar)
adccon |= PCI230_ADC_IR_BIP;
else
adccon |= PCI230_ADC_IR_UNI;
- /* Enable only this channel in the scan list - otherwise by default
- * we'll get one sample from each channel. */
+ /*
+ * Enable only this channel in the scan list - otherwise by default
+ * we'll get one sample from each channel.
+ */
outw(adcen, dev->iobase + PCI230_ADCEN);
/* Set gain for channel. */
@@ -878,8 +890,10 @@ static int pci230_ai_rinsn(struct comedi_device *dev,
/* Convert n samples */
for (n = 0; n < insn->n; n++) {
- /* Trigger conversion by toggling Z2-CT2 output (finish with
- * output high). */
+ /*
+ * Trigger conversion by toggling Z2-CT2 output
+ * (finish with output high).
+ */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
I8254_MODE0);
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
@@ -913,13 +927,17 @@ static int pci230_ao_winsn(struct comedi_device *dev,
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
- /* Set range - see analogue output range table; 0 => unipolar 10V,
- * 1 => bipolar +/-10V range scale */
+ /*
+ * Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale
+ */
devpriv->ao_bipolar = pci230_ao_bipolar[range];
outw(range, dev->iobase + PCI230_DACCON);
- /* Writing a list of values to an AO channel is probably not
- * very useful, but that's how the interface is defined. */
+ /*
+ * Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined.
+ */
for (i = 0; i < insn->n; i++) {
/* Write value to DAC and store it. */
pci230_ao_write_nofifo(dev, data[i], chan);
@@ -929,8 +947,10 @@ static int pci230_ao_winsn(struct comedi_device *dev,
return i;
}
-/* AO subdevices should have a read insn as well as a write insn.
- * Usually this means copying a value stored in devpriv. */
+/*
+ * AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv.
+ */
static int pci230_ao_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn,
unsigned int *data)
@@ -1031,10 +1051,11 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
+/*
+ * Comedi limit due to unsigned int cmd. Driver limit =
+ * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
+ */
#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
- /*- Comedi limit due to unsigned int cmd. Driver limit
- * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
- * clock) = 65.536s */
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
@@ -1044,17 +1065,21 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
MIN_SPEED_AO);
break;
case TRIG_EXT:
- /* External trigger - for PCI230+ hardware version 2 onwards. */
+ /*
+ * External trigger - for PCI230+ hardware version 2 onwards.
+ */
/* Trigger number must be 0. */
- if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
err |= -EINVAL;
}
- /* The only flags allowed are CR_EDGE and CR_INVERT. The
- * CR_EDGE flag is ignored. */
- if ((cmd->scan_begin_arg
- & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
+ /*
+ * The only flags allowed are CR_EDGE and CR_INVERT.
+ * The CR_EDGE flag is ignored.
+ */
+ if (cmd->scan_begin_arg &
+ (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
CR_FLAGS_MASK &
~(CR_EDGE | CR_INVERT));
@@ -1074,14 +1099,11 @@ static int pci230_ao_cmdtest(struct comedi_device *dev,
if (err)
return 3;
- /* Step 4: fix up any arguments.
- * "argument conflict" returned by comedilib to user mode process
- * if this fails. */
+ /* Step 4: fix up any arguments */
if (cmd->scan_begin_src == TRIG_TIMER) {
tmp = cmd->scan_begin_arg;
- pci230_ns_to_single_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
if (tmp != cmd->scan_begin_arg)
err++;
}
@@ -1126,8 +1148,10 @@ static void pci230_ao_stop(struct comedi_device *dev,
/* Using DAC FIFO interrupt. */
intsrc = PCI230P2_INT_DAC;
}
- /* Disable interrupt and wait for interrupt routine to finish running
- * unless we are called from the interrupt routine. */
+ /*
+ * Disable interrupt and wait for interrupt routine to finish running
+ * unless we are called from the interrupt routine.
+ */
spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
devpriv->int_en &= ~intsrc;
while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
@@ -1140,11 +1164,13 @@ static void pci230_ao_stop(struct comedi_device *dev,
}
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
if (devpriv->hwver >= 2) {
- /* Using DAC FIFO. Reset FIFO, clear underrun error,
- * disable FIFO. */
+ /*
+ * Using DAC FIFO. Reset FIFO, clear underrun error,
+ * disable FIFO.
+ */
devpriv->daccon &= PCI230_DAC_OR_MASK;
- outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
- | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET |
+ PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
dev->iobase + PCI230_DACCON);
}
/* Release resources. */
@@ -1168,7 +1194,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev,
if (ret == 0) {
s->async->events |= COMEDI_CB_OVERFLOW;
pci230_ao_stop(dev, s);
- comedi_error(dev, "AO buffer underrun");
+ dev_err(dev->class_dev, "AO buffer underrun\n");
return;
}
/* Write value to DAC. */
@@ -1215,26 +1241,28 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
}
if (events == 0) {
/* Check for FIFO underrun. */
- if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
- comedi_error(dev, "AO FIFO underrun");
+ if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
+ dev_err(dev->class_dev, "AO FIFO underrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
}
- /* Check for buffer underrun if FIFO less than half full
+ /*
+ * Check for buffer underrun if FIFO less than half full
* (otherwise there will be loads of "DAC FIFO not half full"
- * interrupts). */
- if ((num_scans == 0)
- && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
- comedi_error(dev, "AO buffer underrun");
+ * interrupts).
+ */
+ if ((num_scans == 0) &&
+ ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
+ dev_err(dev->class_dev, "AO buffer underrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
}
}
if (events == 0) {
/* Determine how much room is in the FIFO (in samples). */
- if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0)
+ if (dacstat & PCI230P2_DAC_FIFO_FULL)
room = PCI230P2_DAC_FIFOROOM_FULL;
- else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0)
+ else if (dacstat & PCI230P2_DAC_FIFO_HALF)
room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
- else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0)
+ else if (dacstat & PCI230P2_DAC_FIFO_EMPTY)
room = PCI230P2_DAC_FIFOROOM_EMPTY;
else
room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
@@ -1257,26 +1285,27 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
if (cmd->stop_src == TRIG_COUNT) {
devpriv->ao_scan_count -= num_scans;
if (devpriv->ao_scan_count == 0) {
- /* All data for the command has been written
+ /*
+ * All data for the command has been written
* to FIFO. Set FIFO interrupt trigger level
- * to 'empty'. */
- devpriv->daccon = (devpriv->daccon
- &
- ~PCI230P2_DAC_INT_FIFO_MASK)
- | PCI230P2_DAC_INT_FIFO_EMPTY;
+ * to 'empty'.
+ */
+ devpriv->daccon =
+ (devpriv->daccon &
+ ~PCI230P2_DAC_INT_FIFO_MASK) |
+ PCI230P2_DAC_INT_FIFO_EMPTY;
outw(devpriv->daccon,
dev->iobase + PCI230_DACCON);
}
}
/* Check if FIFO underrun occurred while writing to FIFO. */
dacstat = inw(dev->iobase + PCI230_DACCON);
- if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
- comedi_error(dev, "AO FIFO underrun");
+ if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) {
+ dev_err(dev->class_dev, "AO FIFO underrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
}
}
- if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
- != 0) {
+ if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
/* Stopping AO due to completion or error. */
pci230_ao_stop(dev, s);
running = 0;
@@ -1294,7 +1323,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
struct pci230_private *devpriv = dev->private;
unsigned long irqflags;
- if (trig_num != 0)
+ if (trig_num)
return -EINVAL;
spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
@@ -1373,11 +1402,10 @@ static void pci230_ao_start(struct comedi_device *dev,
scantrig = PCI230P2_DAC_TRIG_NONE;
break;
}
- devpriv->daccon = (devpriv->daccon
- & ~PCI230P2_DAC_TRIG_MASK) |
+ devpriv->daccon =
+ (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) |
scantrig;
outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
-
}
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
@@ -1441,7 +1469,6 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* Claim Z2-CT1. */
if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD))
return -EBUSY;
-
}
/* Get number of scans required. */
@@ -1450,8 +1477,10 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
else /* TRIG_NONE, user calls cancel */
devpriv->ao_scan_count = 0;
- /* Set range - see analogue output range table; 0 => unipolar 10V,
- * 1 => bipolar +/-10V range scale */
+ /*
+ * Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale
+ */
range = CR_RANGE(cmd->chanlist[0]);
devpriv->ao_bipolar = pci230_ao_bipolar[range];
daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
@@ -1474,26 +1503,28 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
*
* N.B. DAC FIFO interrupts are currently disabled.
*/
- daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
- | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
- | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
+ daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET |
+ PCI230P2_DAC_FIFO_UNDERRUN_CLEAR |
+ PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
}
/* Set DACCON. */
outw(daccon, dev->iobase + PCI230_DACCON);
/* Preserve most of DACCON apart from write-only, transient bits. */
- devpriv->daccon = daccon
- & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
+ devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET |
+ PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
if (cmd->scan_begin_src == TRIG_TIMER) {
- /* Set the counter timer 1 to the specified scan frequency. */
- /* cmd->scan_begin_arg is sampling period in ns */
- /* gate it off for now. */
+ /*
+ * Set the counter timer 1 to the specified scan frequency.
+ * cmd->scan_begin_arg is sampling period in ns.
+ * Gate it off for now.
+ */
outb(GAT_CONFIG(1, GAT_GND),
devpriv->iobase1 + PCI230_ZGAT_SCE);
pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ cmd->flags);
}
/* N.B. cmd->start_src == TRIG_INT */
@@ -1519,8 +1550,8 @@ static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
chanlist_len = 1;
min_scan_period = chanlist_len * cmd->convert_arg;
- if ((min_scan_period < chanlist_len)
- || (min_scan_period < cmd->convert_arg)) {
+ if ((min_scan_period < chanlist_len) ||
+ (min_scan_period < cmd->convert_arg)) {
/* Arithmetic overflow. */
min_scan_period = UINT_MAX;
err++;
@@ -1570,10 +1601,10 @@ static int pci230_ai_check_chanlist(struct comedi_device *dev,
if (subseq_len > 0 &&
cmd->chanlist[i % subseq_len] != chanspec) {
- dev_dbg(dev->class_dev,
- "%s: channel numbers must increase or sequence must repeat exactly\n",
- __func__);
- return -EINVAL;
+ dev_dbg(dev->class_dev,
+ "%s: channel numbers must increase or sequence must repeat exactly\n",
+ __func__);
+ return -EINVAL;
}
if (aref != prev_aref) {
@@ -1607,7 +1638,7 @@ static int pci230_ai_check_chanlist(struct comedi_device *dev,
if (subseq_len == 0)
subseq_len = cmd->chanlist_len;
- if ((cmd->chanlist_len % subseq_len) != 0) {
+ if (cmd->chanlist_len % subseq_len) {
dev_dbg(dev->class_dev,
"%s: sequence must repeat exactly\n", __func__);
return -EINVAL;
@@ -1625,7 +1656,7 @@ static int pci230_ai_check_chanlist(struct comedi_device *dev,
* the bug, but the second one does, and we can't tell them apart!
*/
if (devpriv->hwver > 0 && devpriv->hwver < 4) {
- if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0]) != 0) {
+ if (subseq_len > 1 && CR_CHAN(cmd->chanlist[0])) {
dev_info(dev->class_dev,
"amplc_pci230: ai_cmdtest: Buggy PCI230+/260+ h/w version %u requires first channel of multi-channel sequence to be 0 (corrected in h/w version 4)\n",
devpriv->hwver);
@@ -1680,8 +1711,8 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
* set up to generate a fixed number of timed conversion pulses.
*/
- if ((cmd->scan_begin_src != TRIG_FOLLOW)
- && (cmd->convert_src != TRIG_TIMER))
+ if ((cmd->scan_begin_src != TRIG_FOLLOW) &&
+ (cmd->convert_src != TRIG_TIMER))
err |= -EINVAL;
if (err)
@@ -1694,17 +1725,20 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
+/*
+ * Comedi limit due to unsigned int cmd. Driver limit =
+ * 2^16 (16bit * counter) * 1000000ns (1kHz onboard clock) = 65.536s
+ */
#define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */
- /*- Comedi limit due to unsigned int cmd. Driver limit
- * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
- * clock) = 65.536s */
if (cmd->convert_src == TRIG_TIMER) {
unsigned int max_speed_ai;
if (devpriv->hwver == 0) {
- /* PCI230 or PCI260. Max speed depends whether
- * single-ended or pseudo-differential. */
+ /*
+ * PCI230 or PCI260. Max speed depends whether
+ * single-ended or pseudo-differential.
+ */
if (cmd->chanlist && (cmd->chanlist_len > 0)) {
/* Peek analogue reference of first channel. */
if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF)
@@ -1734,17 +1768,19 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
* convert_arg == (CR_EDGE | CR_INVERT | 0)
* => trigger on -ve edge.
*/
- if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
+ if (cmd->convert_arg & CR_FLAGS_MASK) {
/* Trigger number must be 0. */
- if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
+ if (cmd->convert_arg & ~CR_FLAGS_MASK) {
cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
~CR_FLAGS_MASK);
err |= -EINVAL;
}
- /* The only flags allowed are CR_INVERT and CR_EDGE.
- * CR_EDGE is required. */
- if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
- != CR_EDGE) {
+ /*
+ * The only flags allowed are CR_INVERT and CR_EDGE.
+ * CR_EDGE is required.
+ */
+ if ((cmd->convert_arg &
+ (CR_FLAGS_MASK & ~CR_INVERT)) != CR_EDGE) {
/* Set CR_EDGE, preserve CR_INVERT. */
cmd->convert_arg = COMBINE(cmd->start_arg,
(CR_EDGE | 0),
@@ -1753,9 +1789,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
err |= -EINVAL;
}
} else {
- /* Backwards compatibility with previous versions. */
- /* convert_arg == 0 => trigger on -ve edge. */
- /* convert_arg == 1 => trigger on +ve edge. */
+ /*
+ * Backwards compatibility with previous versions:
+ * convert_arg == 0 => trigger on -ve edge.
+ * convert_arg == 1 => trigger on +ve edge.
+ */
err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1);
}
} else {
@@ -1768,16 +1806,18 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
if (cmd->scan_begin_src == TRIG_EXT) {
- /* external "trigger" to begin each scan
+ /*
+ * external "trigger" to begin each scan:
* scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
- * of CT2 (sample convert trigger is CT2) */
- if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ * of CT2 (sample convert trigger is CT2)
+ */
+ if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
~CR_FLAGS_MASK);
err |= -EINVAL;
}
/* The only flag allowed is CR_EDGE, which is ignored. */
- if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) {
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
CR_FLAGS_MASK & ~CR_EDGE);
err |= -EINVAL;
@@ -1794,14 +1834,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if (err)
return 3;
- /* Step 4: fix up any arguments.
- * "argument conflict" returned by comedilib to user mode process
- * if this fails. */
+ /* Step 4: fix up any arguments */
if (cmd->convert_src == TRIG_TIMER) {
tmp = cmd->convert_arg;
- pci230_ns_to_single_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ pci230_ns_to_single_timer(&cmd->convert_arg, cmd->flags);
if (tmp != cmd->convert_arg)
err++;
}
@@ -1809,8 +1846,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
/* N.B. cmd->convert_arg is also TRIG_TIMER */
tmp = cmd->scan_begin_arg;
- pci230_ns_to_single_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg, cmd->flags);
if (!pci230_ai_check_scan_period(cmd)) {
/* Was below minimum required. Round up. */
pci230_ns_to_single_timer(&cmd->scan_begin_arg,
@@ -1844,7 +1880,7 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
unsigned short triglev;
unsigned short adccon;
- if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
+ if (cmd->flags & TRIG_WAKE_EOS) {
/* Wake at end of scan. */
wake = scanlen - devpriv->ai_scan_pos;
} else {
@@ -1853,8 +1889,8 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
- wake = (devpriv->ai_scan_count * scanlen)
- - devpriv->ai_scan_pos;
+ wake = (devpriv->ai_scan_count * scanlen) -
+ devpriv->ai_scan_pos;
}
}
if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
@@ -1885,27 +1921,30 @@ static int pci230_ai_inttrig_convert(struct comedi_device *dev,
struct pci230_private *devpriv = dev->private;
unsigned long irqflags;
- if (trig_num != 0)
+ if (trig_num)
return -EINVAL;
spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
unsigned int delayus;
- /* Trigger conversion by toggling Z2-CT2 output. Finish
- * with output high. */
+ /*
+ * Trigger conversion by toggling Z2-CT2 output.
+ * Finish with output high.
+ */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
I8254_MODE0);
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
I8254_MODE1);
- /* Delay. Should driver be responsible for this? An
+ /*
+ * Delay. Should driver be responsible for this? An
* alternative would be to wait until conversion is complete,
* but we can't tell when it's complete because the ADC busy
* bit has a different meaning when FIFO enabled (and when
- * FIFO not enabled, it only works for software triggers). */
- if (((devpriv->adccon & PCI230_ADC_IM_MASK)
- == PCI230_ADC_IM_DIF)
- && (devpriv->hwver == 0)) {
+ * FIFO not enabled, it only works for software triggers).
+ */
+ if (((devpriv->adccon & PCI230_ADC_IM_MASK) ==
+ PCI230_ADC_IM_DIF) && (devpriv->hwver == 0)) {
/* PCI230/260 in differential mode */
delayus = 8;
} else {
@@ -1929,7 +1968,7 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
unsigned long irqflags;
unsigned char zgat;
- if (trig_num != 0)
+ if (trig_num)
return -EINVAL;
spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
@@ -1968,8 +2007,10 @@ static void pci230_ai_stop(struct comedi_device *dev,
pci230_cancel_ct(dev, 0);
}
spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
- /* Disable ADC interrupt and wait for interrupt routine to finish
- * running unless we are called from the interrupt routine. */
+ /*
+ * Disable ADC interrupt and wait for interrupt routine to finish
+ * running unless we are called from the interrupt routine.
+ */
devpriv->int_en &= ~PCI230_INT_ADC;
while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
@@ -1980,10 +2021,12 @@ static void pci230_ai_stop(struct comedi_device *dev,
outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
}
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- /* Reset FIFO, disable FIFO and set start conversion source to none.
- * Keep se/diff and bip/uni settings */
- devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
- | PCI230_ADC_IM_MASK)) |
+ /*
+ * Reset FIFO, disable FIFO and set start conversion source to none.
+ * Keep se/diff and bip/uni settings.
+ */
+ devpriv->adccon =
+ (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) |
PCI230_ADC_TRIG_NONE;
outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
dev->iobase + PCI230_ADCCON);
@@ -2014,8 +2057,10 @@ static void pci230_ai_start(struct comedi_device *dev,
outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
- /* Update conversion trigger source which is currently set
- * to CT2 output, which is currently stuck high. */
+ /*
+ * Update conversion trigger source which is currently set
+ * to CT2 output, which is currently stuck high.
+ */
switch (cmd->convert_src) {
default:
conv = PCI230_ADC_TRIG_NONE;
@@ -2025,7 +2070,7 @@ static void pci230_ai_start(struct comedi_device *dev,
conv = PCI230_ADC_TRIG_Z2CT2;
break;
case TRIG_EXT:
- if ((cmd->convert_arg & CR_EDGE) != 0) {
+ if (cmd->convert_arg & CR_EDGE) {
if ((cmd->convert_arg & CR_INVERT) == 0) {
/* Trigger on +ve edge. */
conv = PCI230_ADC_TRIG_EXTP;
@@ -2035,7 +2080,7 @@ static void pci230_ai_start(struct comedi_device *dev,
}
} else {
/* Backwards compatibility. */
- if (cmd->convert_arg != 0) {
+ if (cmd->convert_arg) {
/* Trigger on +ve edge. */
conv = PCI230_ADC_TRIG_EXTP;
} else {
@@ -2045,31 +2090,39 @@ static void pci230_ai_start(struct comedi_device *dev,
}
break;
case TRIG_INT:
- /* Use CT2 output for software trigger due to problems
- * in differential mode on PCI230/260. */
+ /*
+ * Use CT2 output for software trigger due to problems
+ * in differential mode on PCI230/260.
+ */
conv = PCI230_ADC_TRIG_Z2CT2;
break;
}
- devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
- | conv;
+ devpriv->adccon =
+ (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv;
outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
if (cmd->convert_src == TRIG_INT)
async->inttrig = pci230_ai_inttrig_convert;
- /* Update FIFO interrupt trigger level, which is currently
- * set to "full". */
+ /*
+ * Update FIFO interrupt trigger level, which is currently
+ * set to "full".
+ */
pci230_ai_update_fifo_trigger_level(dev, s);
if (cmd->convert_src == TRIG_TIMER) {
/* Update timer gates. */
unsigned char zgat;
if (cmd->scan_begin_src != TRIG_FOLLOW) {
- /* Conversion timer CT2 needs to be gated by
- * inverted output of monostable CT2. */
+ /*
+ * Conversion timer CT2 needs to be gated by
+ * inverted output of monostable CT2.
+ */
zgat = GAT_CONFIG(2, GAT_NOUTNM2);
} else {
- /* Conversion timer CT2 needs to be gated on
- * continuously. */
+ /*
+ * Conversion timer CT2 needs to be gated on
+ * continuously.
+ */
zgat = GAT_CONFIG(2, GAT_VCC);
}
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
@@ -2111,11 +2164,13 @@ static void pci230_ai_start(struct comedi_device *dev,
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
- /* Scan period timer CT1 needs to be
- * gated on to start counting. */
+ /*
+ * Scan period timer CT1 needs to be
+ * gated on to start counting.
+ */
zgat = GAT_CONFIG(1, GAT_VCC);
- outb(zgat, devpriv->iobase1
- + PCI230_ZGAT_SCE);
+ outb(zgat, devpriv->iobase1 +
+ PCI230_ZGAT_SCE);
break;
case TRIG_INT:
async->inttrig =
@@ -2163,12 +2218,12 @@ static void pci230_handle_ai(struct comedi_device *dev,
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else if (devpriv->ai_scan_count == 0) {
todo = 0;
- } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
- || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL) ||
+ (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
- todo = (devpriv->ai_scan_count * scanlen)
- - devpriv->ai_scan_pos;
+ todo = (devpriv->ai_scan_count * scanlen) -
+ devpriv->ai_scan_pos;
if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL)
todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
}
@@ -2179,24 +2234,26 @@ static void pci230_handle_ai(struct comedi_device *dev,
if (fifoamount == 0) {
/* Read FIFO state. */
status_fifo = inw(dev->iobase + PCI230_ADCCON);
- if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
- /* Report error otherwise FIFO overruns will go
- * unnoticed by the caller. */
- comedi_error(dev, "AI FIFO overrun");
+ if (status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) {
+ /*
+ * Report error otherwise FIFO overruns will go
+ * unnoticed by the caller.
+ */
+ dev_err(dev->class_dev, "AI FIFO overrun\n");
events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
break;
- } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
+ } else if (status_fifo & PCI230_ADC_FIFO_EMPTY) {
/* FIFO empty. */
break;
- } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
+ } else if (status_fifo & PCI230_ADC_FIFO_HALF) {
/* FIFO half full. */
fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
} else {
/* FIFO not empty. */
if (devpriv->hwver > 0) {
/* Read PCI230+/260+ ADC FIFO level. */
- fifoamount = inw(dev->iobase
- + PCI230P_ADCFFLEV);
+ fifoamount =
+ inw(dev->iobase + PCI230P_ADCFFLEV);
if (fifoamount == 0) {
/* Shouldn't happen. */
break;
@@ -2209,7 +2266,7 @@ static void pci230_handle_ai(struct comedi_device *dev,
/* Read sample and store in Comedi's circular buffer. */
if (comedi_buf_put(s, pci230_ai_read(dev)) == 0) {
events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
- comedi_error(dev, "AI buffer overflow");
+ dev_err(dev->class_dev, "AI buffer overflow\n");
break;
}
fifoamount--;
@@ -2229,8 +2286,8 @@ static void pci230_handle_ai(struct comedi_device *dev,
events |= COMEDI_CB_BLOCK;
}
async->events |= events;
- if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
- COMEDI_CB_OVERFLOW)) != 0) {
+ if (async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+ COMEDI_CB_OVERFLOW)) {
/* disable hardware conversions */
pci230_ai_stop(dev, s);
} else {
@@ -2255,8 +2312,10 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* Determine which shared resources are needed.
*/
res_mask = 0;
- /* Need Z2-CT2 to supply a conversion trigger source at a high
- * logic level, even if not doing timed conversions. */
+ /*
+ * Need Z2-CT2 to supply a conversion trigger source at a high
+ * logic level, even if not doing timed conversions.
+ */
res_mask |= (1U << RES_Z2CT2);
if (cmd->scan_begin_src != TRIG_FOLLOW) {
/* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
@@ -2278,7 +2337,8 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ai_scan_count = 0;
devpriv->ai_scan_pos = 0; /* Position within scan. */
- /* Steps;
+ /*
+ * Steps:
* - Set channel scan list.
* - Set channel gains.
* - Enable and reset FIFO, specify uni/bip, se/diff, and set
@@ -2323,20 +2383,24 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (diff) {
gainshift = 2 * chan;
if (devpriv->hwver == 0) {
- /* Original PCI230/260 expects both inputs of
- * the differential channel to be enabled. */
+ /*
+ * Original PCI230/260 expects both inputs of
+ * the differential channel to be enabled.
+ */
adcen |= 3 << gainshift;
} else {
- /* PCI230+/260+ expects only one input of the
- * differential channel to be enabled. */
+ /*
+ * PCI230+/260+ expects only one input of the
+ * differential channel to be enabled.
+ */
adcen |= 1 << gainshift;
}
} else {
gainshift = (chan & ~1);
adcen |= 1 << chan;
}
- devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
- | (pci230_ai_gain[range] << gainshift);
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift)) |
+ (pci230_ai_gain[range] << gainshift);
}
/* Set channel scan list. */
@@ -2345,43 +2409,53 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* Set channel gains. */
outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
- /* Set counter/timer 2 output high for use as the initial start
- * conversion source. */
+ /*
+ * Set counter/timer 2 output high for use as the initial start
+ * conversion source.
+ */
i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
- /* Temporarily use CT2 output as conversion trigger source and
- * temporarily set FIFO interrupt trigger level to 'full'. */
+ /*
+ * Temporarily use CT2 output as conversion trigger source and
+ * temporarily set FIFO interrupt trigger level to 'full'.
+ */
adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
- /* Enable and reset FIFO, specify FIFO trigger level full, specify
+ /*
+ * Enable and reset FIFO, specify FIFO trigger level full, specify
* uni/bip, se/diff, and temporarily set the start conversion source
* to CT2 output. Note that CT2 output is currently high, and this
* will produce a false conversion trigger on some versions of the
- * PCI230/260, but that will be dealt with later. */
+ * PCI230/260, but that will be dealt with later.
+ */
devpriv->adccon = adccon;
outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
- /* Delay */
- /* Failure to include this will result in the first few channels'-worth
+ /*
+ * Delay -
+ * Failure to include this will result in the first few channels'-worth
* of data being corrupt, normally manifesting itself by large negative
* voltages. It seems the board needs time to settle between the first
* FIFO reset (above) and the second FIFO reset (below). Setting the
* channel gains and scan list _before_ the first FIFO reset also
- * helps, though only slightly. */
- udelay(25);
+ * helps, though only slightly.
+ */
+ usleep_range(25, 100);
/* Reset FIFO again. */
outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
if (cmd->convert_src == TRIG_TIMER) {
- /* Set up CT2 as conversion timer, but gate it off for now.
+ /*
+ * Set up CT2 as conversion timer, but gate it off for now.
* Note, counter/timer output 2 can be monitored on the
- * connector: PCI230 pin 21, PCI260 pin 18. */
+ * connector: PCI230 pin 21, PCI260 pin 18.
+ */
zgat = GAT_CONFIG(2, GAT_GND);
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
/* Set counter/timer 2 to the specified conversion period. */
pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ cmd->flags);
if (cmd->scan_begin_src != TRIG_FOLLOW) {
/*
* Set up monostable on CT0 output for scan timing. A
@@ -2398,8 +2472,8 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
zgat = GAT_CONFIG(0, GAT_VCC);
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
- ((uint64_t) cmd->convert_arg
- * cmd->scan_end_arg),
+ ((uint64_t)cmd->convert_arg *
+ cmd->scan_end_arg),
TRIG_ROUND_UP);
if (cmd->scan_begin_src == TRIG_TIMER) {
/*
@@ -2412,9 +2486,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
cmd->scan_begin_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK);
+ cmd->flags);
}
}
}
@@ -2452,9 +2524,11 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
valid_status_int = devpriv->int_en & status_int;
- /* Disable triggered interrupts.
+ /*
+ * Disable triggered interrupts.
* (Only those interrupts that need re-enabling, are, later in the
- * handler). */
+ * handler).
+ */
devpriv->ier = devpriv->int_en & ~status_int;
outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
devpriv->intr_running = 1;
@@ -2469,19 +2543,19 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
* two.
*/
- if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
+ if (valid_status_int & PCI230_INT_ZCLK_CT1) {
s = dev->write_subdev;
pci230_handle_ao_nofifo(dev, s);
comedi_event(dev, s);
}
- if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
+ if (valid_status_int & PCI230P2_INT_DAC) {
s = dev->write_subdev;
pci230_handle_ao_fifo(dev, s);
comedi_event(dev, s);
}
- if ((valid_status_int & PCI230_INT_ADC) != 0) {
+ if (valid_status_int & PCI230_INT_ADC) {
s = dev->read_subdev;
pci230_handle_ai(dev, s);
comedi_event(dev, s);
@@ -2511,8 +2585,10 @@ static bool pci230_match_pci_board(const struct pci230_board *board,
/* Looking for a '+' model. First check length of registers. */
if (pci_resource_len(pci_dev, 3) < 32)
return false; /* Not a '+' model. */
- /* TODO: temporarily enable PCI device and read the hardware version
- * register. For now, assume it's okay. */
+ /*
+ * TODO: temporarily enable PCI device and read the hardware version
+ * register. For now, assume it's okay.
+ */
return true;
}
@@ -2601,8 +2677,10 @@ static int pci230_attach_common(struct comedi_device *dev,
if (rc)
return rc;
- /* Read base addresses of the PCI230's two I/O regions from PCI
- * configuration register. */
+ /*
+ * Read base addresses of the PCI230's two I/O regions from PCI
+ * configuration register.
+ */
iobase1 = pci_resource_start(pci_dev, 2);
iobase2 = pci_resource_start(pci_dev, 3);
dev_dbg(dev->class_dev,
@@ -2612,8 +2690,10 @@ static int pci230_attach_common(struct comedi_device *dev,
dev->iobase = iobase2;
/* Read bits of DACCON register - only the output range. */
devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
- /* Read hardware version register and set extended function register
- * if they exist. */
+ /*
+ * Read hardware version register and set extended function register
+ * if they exist.
+ */
if (pci_resource_len(pci_dev, 3) >= 32) {
unsigned short extfunc = 0;
@@ -2627,25 +2707,29 @@ static int pci230_attach_common(struct comedi_device *dev,
}
if (devpriv->hwver > 0) {
if (!thisboard->have_dio) {
- /* No DIO ports. Route counters' external gates
+ /*
+ * No DIO ports. Route counters' external gates
* to the EXTTRIG signal (PCI260+ pin 17).
* (Otherwise, they would be routed to DIO
* inputs PC0, PC1 and PC2 which don't exist
- * on PCI260[+].) */
+ * on PCI260[+].)
+ */
extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
}
- if ((thisboard->ao_chans > 0)
- && (devpriv->hwver >= 2)) {
+ if ((thisboard->ao_chans > 0) &&
+ (devpriv->hwver >= 2)) {
/* Enable DAC FIFO functionality. */
extfunc |= PCI230P2_EXTFUNC_DACFIFO;
}
}
outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
- if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
- /* Temporarily enable DAC FIFO, reset it and disable
- * FIFO wraparound. */
- outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
- | PCI230P2_DAC_FIFO_RESET,
+ if (extfunc & PCI230P2_EXTFUNC_DACFIFO) {
+ /*
+ * Temporarily enable DAC FIFO, reset it and disable
+ * FIFO wraparound.
+ */
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN |
+ PCI230P2_DAC_FIFO_RESET,
dev->iobase + PCI230_DACCON);
/* Clear DAC FIFO channel enable register. */
outw(0, dev->iobase + PCI230P2_DACEN);
@@ -2657,8 +2741,8 @@ static int pci230_attach_common(struct comedi_device *dev,
outb(0, devpriv->iobase1 + PCI230_INT_SCE);
/* Set ADC to a reasonable state. */
devpriv->adcg = 0;
- devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
- | PCI230_ADC_IR_BIP;
+ devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE |
+ PCI230_ADC_IR_BIP;
outw(1 << 0, dev->iobase + PCI230_ADCEN);
outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
@@ -2682,13 +2766,13 @@ static int pci230_attach_common(struct comedi_device *dev,
s->n_chan = thisboard->ai_chans;
s->maxdata = (1 << thisboard->ai_bits) - 1;
s->range_table = &pci230_ai_range;
- s->insn_read = &pci230_ai_rinsn;
+ s->insn_read = pci230_ai_rinsn;
s->len_chanlist = 256; /* but there are restrictions. */
if (dev->irq) {
dev->read_subdev = s;
s->subdev_flags |= SDF_CMD_READ;
- s->do_cmd = &pci230_ai_cmd;
- s->do_cmdtest = &pci230_ai_cmdtest;
+ s->do_cmd = pci230_ai_cmd;
+ s->do_cmdtest = pci230_ai_cmdtest;
s->cancel = pci230_ai_cancel;
}
@@ -2700,14 +2784,14 @@ static int pci230_attach_common(struct comedi_device *dev,
s->n_chan = thisboard->ao_chans;
s->maxdata = (1 << thisboard->ao_bits) - 1;
s->range_table = &pci230_ao_range;
- s->insn_write = &pci230_ao_winsn;
- s->insn_read = &pci230_ao_rinsn;
+ s->insn_write = pci230_ao_winsn;
+ s->insn_read = pci230_ao_rinsn;
s->len_chanlist = thisboard->ao_chans;
if (dev->irq) {
dev->write_subdev = s;
s->subdev_flags |= SDF_CMD_WRITE;
- s->do_cmd = &pci230_ao_cmd;
- s->do_cmdtest = &pci230_ao_cmdtest;
+ s->do_cmd = pci230_ao_cmd;
+ s->do_cmdtest = pci230_ao_cmdtest;
s->cancel = pci230_ao_cancel;
}
} else {
@@ -2748,7 +2832,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
}
static int pci230_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+ unsigned long context_unused)
{
struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
int rc;
diff --git a/drivers/staging/comedi/drivers/amplc_pci236.c b/drivers/staging/comedi/drivers/amplc_pci236.c
new file mode 100644
index 000000000000..436aebaf7621
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci236.c
@@ -0,0 +1,161 @@
+/*
+ * comedi/drivers/amplc_pci236.c
+ * Driver for Amplicon PCI236 DIO boards.
+ *
+ * Copyright (C) 2002-2014 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.
+ */
+/*
+ * Driver: amplc_pci236
+ * Description: Amplicon PCI236
+ * Author: Ian Abbott <abbotti@mev.co.uk>
+ * Devices: [Amplicon] PCI236 (amplc_pci236)
+ * Updated: Fri, 25 Jul 2014 15:32:40 +0000
+ * Status: works
+ *
+ * Configuration options:
+ * none
+ *
+ * Manual configuration of PCI board (PCI236) is not supported; it is
+ * configured automatically.
+ *
+ * The PCI236 board has a single 8255 appearing as subdevice 0.
+ *
+ * Subdevice 1 pretends to be a digital input device, but it always
+ * returns 0 when read. However, if you run a command with
+ * scan_begin_src=TRIG_EXT, a rising edge on port C bit 3 acts as an
+ * external trigger, which can be used to wake up tasks. This is like
+ * the comedi_parport device. If no interrupt is connected, then
+ * subdevice 1 is unused.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#include "../comedidev.h"
+
+#include "amplc_pc236.h"
+#include "plx9052.h"
+
+/* 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)
+
+static void pci236_intr_update_cb(struct comedi_device *dev, bool enable)
+{
+ struct pc236_private *devpriv = dev->private;
+
+ /* this will also clear the "local interrupt 1" latch */
+ outl(enable ? PCI236_INTR_ENABLE : PCI236_INTR_DISABLE,
+ devpriv->lcr_iobase + PLX9052_INTCSR);
+}
+
+static bool pci236_intr_chk_clr_cb(struct comedi_device *dev)
+{
+ struct pc236_private *devpriv = dev->private;
+
+ /* check if interrupt occurred */
+ if (!(inl(devpriv->lcr_iobase + PLX9052_INTCSR) &
+ PLX9052_INTCSR_LI1STAT))
+ return false;
+ /* clear the interrupt */
+ pci236_intr_update_cb(dev, devpriv->enable_irq);
+ return true;
+}
+
+static const struct pc236_board pc236_pci_board = {
+ .name = "pci236",
+ .intr_update_cb = pci236_intr_update_cb,
+ .intr_chk_clr_cb = pci236_intr_chk_clr_cb,
+};
+
+static int pci236_auto_attach(struct comedi_device *dev,
+ unsigned long context_unused)
+{
+ struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
+ struct pc236_private *devpriv;
+ unsigned long iobase;
+ int ret;
+
+ dev_info(dev->class_dev, "amplc_pci236: attach pci %s\n",
+ pci_name(pci_dev));
+
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
+ return -ENOMEM;
+
+ dev->board_ptr = &pc236_pci_board;
+ dev->board_name = pc236_pci_board.name;
+ 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 amplc_pc236_common_attach(dev, iobase, pci_dev->irq,
+ IRQF_SHARED);
+}
+
+static void pci236_detach(struct comedi_device *dev)
+{
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ comedi_pci_disable(dev);
+}
+
+static struct comedi_driver amplc_pci236_driver = {
+ .driver_name = "amplc_pci236",
+ .module = THIS_MODULE,
+ .auto_attach = pci236_auto_attach,
+ .detach = pci236_detach,
+};
+
+static const struct pci_device_id pci236_pci_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, 0x0009) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, pci236_pci_table);
+
+static int amplc_pci236_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ return comedi_pci_auto_config(dev, &amplc_pci236_driver,
+ id->driver_data);
+}
+
+static struct pci_driver amplc_pci236_pci_driver = {
+ .name = "amplc_pci236",
+ .id_table = pci236_pci_table,
+ .probe = &amplc_pci236_pci_probe,
+ .remove = comedi_pci_auto_unconfig,
+};
+
+module_comedi_pci_driver(amplc_pci236_driver, amplc_pci236_pci_driver);
+
+MODULE_AUTHOR("Comedi http://www.comedi.org");
+MODULE_DESCRIPTION("Comedi driver for Amplicon PCI236 DIO boards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c
index 93ed03ee416a..748a6b108f32 100644
--- a/drivers/staging/comedi/drivers/amplc_pci263.c
+++ b/drivers/staging/comedi/drivers/amplc_pci263.c
@@ -37,11 +37,6 @@ The state of the outputs can be read.
#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,
@@ -88,14 +83,14 @@ static int pci263_auto_attach(struct comedi_device *dev,
}
static struct comedi_driver amplc_pci263_driver = {
- .driver_name = PCI263_DRIVER_NAME,
+ .driver_name = "amplc_pci263",
.module = THIS_MODULE,
.auto_attach = pci263_auto_attach,
.detach = comedi_pci_disable,
};
static const struct pci_device_id pci263_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, 0x000c) },
{0}
};
MODULE_DEVICE_TABLE(pci, pci263_pci_table);
@@ -108,7 +103,7 @@ static int amplc_pci263_pci_probe(struct pci_dev *dev,
}
static struct pci_driver amplc_pci263_pci_driver = {
- .name = PCI263_DRIVER_NAME,
+ .name = "amplc_pci263",
.id_table = pci263_pci_table,
.probe = &amplc_pci263_pci_probe,
.remove = comedi_pci_auto_unconfig,
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index eb1b92d72e87..853733e28845 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -46,8 +46,6 @@ Status: experimental
#include "comedi_fc.h"
#include "8253.h"
-#define DAS16CS_SIZE 18
-
#define DAS16CS_ADC_DATA 0
#define DAS16CS_DIO_MUX 2
#define DAS16CS_MISC1 4
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 7377da1aff7c..4a7bd4e5dd72 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -461,7 +461,6 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
break;
default:
return -EINVAL;
- break;
}
return insn->n;
}
@@ -622,7 +621,7 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
static const int caldac_8800_udelay = 1;
if (address >= num_caldac_channels) {
- comedi_error(dev, "illegal caldac channel");
+ dev_err(dev->class_dev, "illegal caldac channel\n");
return -1;
}
@@ -774,9 +773,8 @@ static int cb_pcidas_trimpot_write(struct comedi_device *dev,
trimpot_8402_write(dev, channel, value);
break;
default:
- comedi_error(dev, "driver bug?");
+ dev_err(dev->class_dev, "driver bug?\n");
return -1;
- break;
}
return 1;
@@ -1251,9 +1249,8 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
break;
default:
spin_unlock_irqrestore(&dev->spinlock, flags);
- comedi_error(dev, "error setting dac pacer source");
+ dev_err(dev->class_dev, "error setting dac pacer source\n");
return -1;
- break;
}
spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -1303,7 +1300,7 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
if (cmd->stop_src == TRIG_NONE ||
(cmd->stop_src == TRIG_COUNT
&& devpriv->ao_count)) {
- comedi_error(dev, "dac fifo underflow");
+ dev_err(dev->class_dev, "dac fifo underflow\n");
async->events |= COMEDI_CB_ERROR;
}
async->events |= COMEDI_CB_EOA;
@@ -1414,8 +1411,8 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
devpriv->control_status + INT_ADCFIFO);
spin_unlock_irqrestore(&dev->spinlock, flags);
} else if (status & EOAI) {
- comedi_error(dev,
- "bug! encountered end of acquisition interrupt?");
+ dev_err(dev->class_dev,
+ "bug! encountered end of acquisition interrupt?\n");
/* clear EOA interrupt latch */
spin_lock_irqsave(&dev->spinlock, flags);
outw(devpriv->adc_fifo_bits | EOAI,
@@ -1424,7 +1421,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
}
/* check for fifo overflow */
if (status & LADFUL) {
- comedi_error(dev, "fifo overflow");
+ dev_err(dev->class_dev, "fifo overflow\n");
/* clear overflow interrupt latch */
spin_lock_irqsave(&dev->spinlock, flags);
outw(devpriv->adc_fifo_bits | LADFUL,
@@ -1474,11 +1471,12 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
outl(INTCSR_INBOX_INTR_STATUS,
devpriv->s5933_config + AMCC_OP_REG_INTCSR);
- if (request_irq(pcidev->irq, cb_pcidas_interrupt,
- IRQF_SHARED, dev->driver->driver_name, dev)) {
+ ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret) {
dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
pcidev->irq);
- return -EINVAL;
+ return ret;
}
dev->irq = pcidev->irq;
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 035c3a176005..fa12614cef2a 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -80,8 +80,6 @@ TODO:
make ao fifo size adjustable like ai fifo
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
@@ -179,7 +177,7 @@ enum read_write_registers {
DAC_FIFO_REG = 0x300,
};
-/* devpriv->dio_counter_iobase registers */
+/* dev->mmio registers */
enum dio_counter_registers {
DIO_8255_OFFSET = 0x0,
DO_REG = 0x20,
@@ -636,8 +634,8 @@ static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
{
if (board->layout == LAYOUT_4020)
return MAX_AI_DMA_RING_COUNT;
- else
- return MIN_AI_DMA_RING_COUNT;
+
+ return MIN_AI_DMA_RING_COUNT;
}
static const int bytes_in_sample = 2;
@@ -1045,9 +1043,9 @@ static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
if ((thisboard->layout == LAYOUT_64XX && !use_differential) ||
(thisboard->layout == LAYOUT_60XX && use_differential))
return ADC_SE_DIFF_BIT;
- else
- return 0;
-};
+
+ return 0;
+}
struct ext_clock_info {
/* master clock divisor to use for scans with external master clock */
@@ -1064,12 +1062,11 @@ struct pcidas64_private {
/* base addresses (ioremapped) */
void __iomem *plx9080_iobase;
void __iomem *main_iobase;
- void __iomem *dio_counter_iobase;
/* local address (used by dma controller) */
uint32_t local0_iobase;
uint32_t local1_iobase;
/* number of analog input samples remaining */
- volatile unsigned int ai_count;
+ unsigned int ai_count;
/* dma buffers for analog input */
uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
/* physical addresses of ai dma buffers */
@@ -1081,7 +1078,7 @@ struct pcidas64_private {
dma_addr_t ai_dma_desc_bus_addr;
/* index of the ai dma descriptor/buffer
* that is currently being used */
- volatile unsigned int ai_dma_index;
+ unsigned int ai_dma_index;
/* dma buffers for analog output */
uint16_t *ao_buffer[AO_DMA_RING_COUNT];
/* physical addresses of ao dma buffers */
@@ -1089,35 +1086,35 @@ struct pcidas64_private {
struct plx_dma_desc *ao_dma_desc;
dma_addr_t ao_dma_desc_bus_addr;
/* keeps track of buffer where the next ao sample should go */
- volatile unsigned int ao_dma_index;
+ unsigned int ao_dma_index;
/* number of analog output samples remaining */
- volatile unsigned long ao_count;
+ unsigned long ao_count;
/* remember what the analog outputs are set to, to allow readback */
- volatile unsigned int ao_value[2];
+ unsigned int ao_value[2];
unsigned int hw_revision; /* stc chip hardware revision number */
/* last bits sent to INTR_ENABLE_REG register */
- volatile unsigned int intr_enable_bits;
+ unsigned int intr_enable_bits;
/* last bits sent to ADC_CONTROL1_REG register */
- volatile uint16_t adc_control1_bits;
+ uint16_t adc_control1_bits;
/* last bits sent to FIFO_SIZE_REG register */
- volatile uint16_t fifo_size_bits;
+ uint16_t fifo_size_bits;
/* last bits sent to HW_CONFIG_REG register */
- volatile uint16_t hw_config_bits;
- volatile uint16_t dac_control1_bits;
+ uint16_t hw_config_bits;
+ uint16_t dac_control1_bits;
/* last bits written to plx9080 control register */
- volatile uint32_t plx_control_bits;
+ uint32_t plx_control_bits;
/* last bits written to plx interrupt control and status register */
- volatile uint32_t plx_intcsr_bits;
+ uint32_t plx_intcsr_bits;
/* index of calibration source readable through ai ch0 */
- volatile int calibration_source;
+ int calibration_source;
/* bits written to i2c calibration/range register */
- volatile uint8_t i2c_cal_range_bits;
+ uint8_t i2c_cal_range_bits;
/* configure digital triggers to trigger on falling edge */
- volatile unsigned int ext_trig_falling;
+ unsigned int ext_trig_falling;
/* states of various devices stored to enable read-back */
unsigned int ad8402_state[2];
unsigned int caldac_state[8];
- volatile short ai_cmd_running;
+ short ai_cmd_running;
unsigned int ai_fifo_segment_length;
struct ext_clock_info ext_clock;
unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
@@ -1160,7 +1157,7 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
bits = 0x700;
break;
default:
- comedi_error(dev, "bug! in ai_range_bits_6xxx");
+ dev_err(dev->class_dev, "bug! in %s\n", __func__);
break;
}
if (range->min == 0)
@@ -1180,16 +1177,16 @@ static unsigned int hw_revision(const struct comedi_device *dev,
}
static void set_dac_range_bits(struct comedi_device *dev,
- volatile uint16_t *bits, unsigned int channel,
+ uint16_t *bits, unsigned int channel,
unsigned int range)
{
const struct pcidas64_board *thisboard = comedi_board(dev);
unsigned int code = thisboard->ao_range_code[range];
if (channel > 1)
- comedi_error(dev, "bug! bad channel?");
+ dev_err(dev->class_dev, "bug! bad channel?\n");
if (code & ~0x3)
- comedi_error(dev, "bug! bad range code?");
+ dev_err(dev->class_dev, "bug! bad range code?\n");
*bits &= ~(0x3 << (2 * channel));
*bits |= code << (2 * channel);
@@ -1531,10 +1528,10 @@ static int alloc_and_init_dma_members(struct comedi_device *dev)
static inline void warn_external_queue(struct comedi_device *dev)
{
- comedi_error(dev,
- "AO command and AI external channel queue cannot be used simultaneously.");
- comedi_error(dev,
- "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
+ dev_err(dev->class_dev,
+ "AO command and AI external channel queue cannot be used simultaneously\n");
+ dev_err(dev->class_dev,
+ "Use internal AI channel queue (channels must be consecutive and use same range/aref)\n");
}
/* Their i2c requires a huge delay on setting clock or data high for some reason */
@@ -1648,7 +1645,8 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
/* get acknowledge */
if (i2c_read_ack(dev) != 0) {
- comedi_error(dev, "i2c write failed: no acknowledge");
+ dev_err(dev->class_dev, "%s failed: no acknowledge\n",
+ __func__);
i2c_stop(dev);
return;
}
@@ -1656,7 +1654,8 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
for (i = 0; i < length; i++) {
i2c_write_byte(dev, data[i]);
if (i2c_read_ack(dev) != 0) {
- comedi_error(dev, "i2c write failed: no acknowledge");
+ dev_err(dev->class_dev, "%s failed: no acknowledge\n",
+ __func__);
i2c_stop(dev);
return;
}
@@ -1769,6 +1768,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
* as it is very slow */
if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
uint8_t i2c_data = devpriv->i2c_cal_range_bits;
+
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
}
@@ -1796,8 +1796,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
return ret;
if (thisboard->layout == LAYOUT_4020)
- data[n] = readl(devpriv->dio_counter_iobase +
- ADC_FIFO_REG) & 0xffff;
+ data[n] = readl(dev->mmio + ADC_FIFO_REG) & 0xffff;
else
data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG);
}
@@ -1874,7 +1873,6 @@ static int ai_config_master_clock_4020(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
data[4] = divisor;
@@ -1890,10 +1888,8 @@ static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
switch (thisboard->layout) {
case LAYOUT_4020:
return ai_config_master_clock_4020(dev, data);
- break;
default:
return -EINVAL;
- break;
}
return -EINVAL;
@@ -1907,16 +1903,12 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
switch (id) {
case INSN_CONFIG_ALT_SOURCE:
return ai_config_calibration_source(dev, data);
- break;
case INSN_CONFIG_BLOCK_SIZE:
return ai_config_block_size(dev, data);
- break;
case INSN_CONFIG_TIMER_1:
return ai_config_master_clock(dev, data);
- break;
default:
return -EINVAL;
- break;
}
return -EINVAL;
}
@@ -1991,8 +1983,6 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
scan_divisor = min_scan_divisor;
cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
}
-
- return;
}
static int cb_pcidas64_ai_check_chanlist(struct comedi_device *dev,
@@ -2162,8 +2152,8 @@ static int use_hw_sample_counter(struct comedi_cmd *cmd)
if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
return 1;
- else
- return 0;
+
+ return 0;
}
static void setup_sample_counters(struct comedi_device *dev,
@@ -2224,7 +2214,6 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
break;
default:
return 0;
- break;
}
return count - 3;
}
@@ -2243,7 +2232,7 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
divisor = devpriv->ext_clock.divisor;
break;
default: /* should never happen */
- comedi_error(dev, "bug! failed to set ai pacing!");
+ dev_err(dev->class_dev, "bug! failed to set ai pacing!\n");
divisor = 1000;
break;
}
@@ -2454,6 +2443,7 @@ static int setup_channel_queue(struct comedi_device *dev,
* as it is very slow */
if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
uint8_t i2c_data = devpriv->i2c_cal_range_bits;
+
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
}
@@ -2694,7 +2684,7 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
}
for (i = 0; read_code != write_code && i < max_transfer;) {
- fifo_data = readl(devpriv->dio_counter_iobase + ADC_FIFO_REG);
+ fifo_data = readl(dev->mmio + ADC_FIFO_REG);
cfc_write_to_buffer(s, fifo_data & 0xffff);
i++;
if (i < max_transfer) {
@@ -2775,7 +2765,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
/* check for fifo overrun */
if (status & ADC_OVERRUN_BIT) {
- comedi_error(dev, "fifo overrun");
+ dev_err(dev->class_dev, "fifo overrun\n");
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
}
/* spin lock makes sure no one else changes plx dma control reg */
@@ -3138,7 +3128,8 @@ static void set_dac_select_reg(struct comedi_device *dev,
first_channel = CR_CHAN(cmd->chanlist[0]);
last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
if (last_channel < first_channel)
- comedi_error(dev, "bug! last ao channel < first ao channel");
+ dev_err(dev->class_dev,
+ "bug! last ao channel < first ao channel\n");
bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
@@ -3161,7 +3152,7 @@ static void set_dac_interval_regs(struct comedi_device *dev,
divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
if (divisor > max_counter_value) {
- comedi_error(dev, "bug! ao divisor too big");
+ dev_err(dev->class_dev, "bug! ao divisor too big\n");
divisor = max_counter_value;
}
writew(divisor & 0xffff,
@@ -3381,32 +3372,31 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
static int dio_callback(int dir, int port, int data, unsigned long arg)
{
void __iomem *iobase = (void __iomem *)arg;
+
if (dir) {
writeb(data, iobase + port);
return 0;
- } else {
- return readb(iobase + port);
}
+ return readb(iobase + port);
}
static int dio_callback_4020(int dir, int port, int data, unsigned long arg)
{
void __iomem *iobase = (void __iomem *)arg;
+
if (dir) {
writew(data, iobase + 2 * port);
return 0;
- } else {
- return readw(iobase + 2 * port);
}
+ return readw(iobase + 2 * port);
}
static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
unsigned int bits;
- bits = readb(devpriv->dio_counter_iobase + DI_REG);
+ bits = readb(dev->mmio + DI_REG);
bits &= 0xf;
data[1] = bits;
data[0] = 0;
@@ -3419,10 +3409,8 @@ static int do_wbits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
+ writeb(s->state, dev->mmio + DO_REG);
data[1] = s->state;
@@ -3434,15 +3422,13 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- writeb(s->io_bits,
- devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+ writeb(s->io_bits, dev->mmio + DIO_DIRECTION_60XX_REG);
return insn->n;
}
@@ -3452,14 +3438,10 @@ static int dio_60xx_wbits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct pcidas64_private *devpriv = dev->private;
-
- if (comedi_dio_update_state(s, data)) {
- writeb(s->state,
- devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
- }
+ if (comedi_dio_update_state(s, data))
+ writeb(s->state, dev->mmio + DIO_DATA_60XX_REG);
- data[1] = readb(devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
+ data[1] = readb(dev->mmio + DIO_DATA_60XX_REG);
return insn->n;
}
@@ -3496,7 +3478,7 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
static const int caldac_8800_udelay = 1;
if (address >= num_caldac_channels) {
- comedi_error(dev, "illegal caldac channel");
+ dev_err(dev->class_dev, "illegal caldac channel\n");
return -1;
}
for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
@@ -3568,9 +3550,8 @@ static int caldac_i2c_write(struct comedi_device *dev,
serial_bytes[0] = GAIN_1_3;
break;
default:
- comedi_error(dev, "invalid caldac channel\n");
+ dev_err(dev->class_dev, "invalid caldac channel\n");
return -1;
- break;
}
serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
serial_bytes[2] = value & 0xff;
@@ -3863,8 +3844,7 @@ static int setup_subdevices(struct comedi_device *dev)
ret = subdev_8255_init(dev, s, dio_callback_4020,
(unsigned long)dio_8255_iobase);
} else {
- dio_8255_iobase =
- devpriv->dio_counter_iobase + DIO_8255_OFFSET;
+ dio_8255_iobase = dev->mmio + DIO_8255_OFFSET;
ret = subdev_8255_init(dev, s, dio_callback,
(unsigned long)dio_8255_iobase);
}
@@ -3965,10 +3945,9 @@ static int auto_attach(struct comedi_device *dev,
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);
+ dev->mmio = pci_ioremap_bar(pcidev, 3);
- if (!devpriv->plx9080_iobase || !devpriv->main_iobase
- || !devpriv->dio_counter_iobase) {
+ if (!devpriv->plx9080_iobase || !devpriv->main_iobase || !dev->mmio) {
dev_warn(dev->class_dev, "failed to remap io memory\n");
return -ENOMEM;
}
@@ -3997,12 +3976,13 @@ static int auto_attach(struct comedi_device *dev,
devpriv->hw_revision);
init_plx9080(dev);
init_stc_registers(dev);
- /* get irq */
- if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
- "cb_pcidas64", dev)) {
+
+ retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (retval) {
dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
pcidev->irq);
- return -EINVAL;
+ return retval;
}
dev->irq = pcidev->irq;
dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
@@ -4031,8 +4011,8 @@ static void detach(struct comedi_device *dev)
}
if (devpriv->main_iobase)
iounmap(devpriv->main_iobase);
- if (devpriv->dio_counter_iobase)
- iounmap(devpriv->dio_counter_iobase);
+ if (dev->mmio)
+ iounmap(dev->mmio);
/* free pci dma buffers */
for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
if (devpriv->ai_buffer[i])
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index 50e522e6e690..ccb9c72bc0c3 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -47,9 +47,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details.
/* Registers for the PCIM-DAS1602/16 */
-/* sizes of io regions (bytes) */
-#define BADR3_SIZE 16
-
/* DAC Offsets */
#define ADC_TRIG 0
#define DAC0_OFFSET 2
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 67a09aa6b721..845a67905ca6 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -146,10 +146,8 @@ static unsigned short fake_waveform(struct comedi_device *dev,
switch (channel) {
case SAWTOOTH_CHAN:
return fake_sawtooth(dev, range, current_time);
- break;
case SQUARE_CHAN:
return fake_squarewave(dev, range, current_time);
- break;
default:
break;
}
@@ -305,8 +303,8 @@ static int waveform_ai_cmd(struct comedi_device *dev,
struct comedi_cmd *cmd = &s->async->cmd;
if (cmd->flags & TRIG_RT) {
- comedi_error(dev,
- "commands at RT priority not supported in this driver");
+ dev_err(dev->class_dev,
+ "commands at RT priority not supported in this driver\n");
return -1;
}
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
index 0a9c32e9db4a..f066fb06dc1d 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -30,8 +30,6 @@ Configuration Options: not applicable, uses comedi PCI auto config
#include "../comedidev.h"
-#define PCI_DEVICE_ID_PIO1616L 0x8172
-
/*
* Register map
*/
@@ -110,7 +108,7 @@ static int contec_pci_dio_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id contec_pci_dio_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, 0x8172) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table);
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index a8f6036ad82b..cd369cd40114 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -113,8 +113,8 @@ Configuration options: not applicable, uses PCI auto config
#define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin"
-#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */
-#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */
/* Initialization bits for the Serial EEPROM Control Register */
#define DAQBOARD2000_SECRProgPinHi 0x8001767e
@@ -128,8 +128,8 @@ Configuration options: not applicable, uses PCI auto config
#define DAQBOARD2000_EEPROM_PRESENT 0x10000000
/* CPLD status bits */
-#define DAQBOARD2000_CPLD_INIT 0x0002
-#define DAQBOARD2000_CPLD_DONE 0x0004
+#define DAQBOARD2000_CPLD_INIT 0x0002
+#define DAQBOARD2000_CPLD_DONE 0x0004
static const struct comedi_lrange range_daqboard2000_ai = {
13, {
@@ -274,19 +274,16 @@ struct daqboard2000_private {
enum {
card_daqboard_2000
} card;
- void __iomem *daq;
void __iomem *plx;
unsigned int ao_readback[2];
};
static void writeAcqScanListEntry(struct comedi_device *dev, u16 entry)
{
- struct daqboard2000_private *devpriv = dev->private;
-
/* udelay(4); */
- writew(entry & 0x00ff, devpriv->daq + acqScanListFIFO);
+ writew(entry & 0x00ff, dev->mmio + acqScanListFIFO);
/* udelay(4); */
- writew((entry >> 8) & 0x00ff, devpriv->daq + acqScanListFIFO);
+ writew((entry >> 8) & 0x00ff, dev->mmio + acqScanListFIFO);
}
static void setup_sampling(struct comedi_device *dev, int chan, int gain)
@@ -338,10 +335,9 @@ static int daqboard2000_ai_status(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct daqboard2000_private *devpriv = dev->private;
unsigned int status;
- status = readw(devpriv->daq + acqControl);
+ status = readw(dev->mmio + acqControl);
if (status & context)
return 0;
return -EBUSY;
@@ -352,22 +348,21 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct daqboard2000_private *devpriv = dev->private;
int gain, chan;
int ret;
int i;
writew(DAQBOARD2000_AcqResetScanListFifo |
DAQBOARD2000_AcqResetResultsFifo |
- DAQBOARD2000_AcqResetConfigPipe, devpriv->daq + acqControl);
+ DAQBOARD2000_AcqResetConfigPipe, dev->mmio + acqControl);
/*
* If pacer clock is not set to some high value (> 10 us), we
* risk multiple samples to be put into the result FIFO.
*/
/* 1 second, should be long enough */
- writel(1000000, devpriv->daq + acqPacerClockDivLow);
- writew(0, devpriv->daq + acqPacerClockDivHigh);
+ writel(1000000, dev->mmio + acqPacerClockDivLow);
+ writew(0, dev->mmio + acqPacerClockDivHigh);
gain = CR_RANGE(insn->chanspec);
chan = CR_CHAN(insn->chanspec);
@@ -379,15 +374,14 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
setup_sampling(dev, chan, gain);
/* Enable reading from the scanlist FIFO */
- writew(DAQBOARD2000_SeqStartScanList,
- devpriv->daq + acqControl);
+ writew(DAQBOARD2000_SeqStartScanList, dev->mmio + acqControl);
ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status,
DAQBOARD2000_AcqConfigPipeFull);
if (ret)
return ret;
- writew(DAQBOARD2000_AdcPacerEnable, devpriv->daq + acqControl);
+ writew(DAQBOARD2000_AdcPacerEnable, dev->mmio + acqControl);
ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status,
DAQBOARD2000_AcqLogicScanning);
@@ -399,9 +393,9 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
if (ret)
return ret;
- data[i] = readw(devpriv->daq + acqResultsFIFO);
- writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl);
- writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl);
+ data[i] = readw(dev->mmio + acqResultsFIFO);
+ writew(DAQBOARD2000_AdcPacerDisable, dev->mmio + acqControl);
+ writew(DAQBOARD2000_SeqStopScanList, dev->mmio + acqControl);
}
return i;
@@ -427,11 +421,10 @@ static int daqboard2000_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct daqboard2000_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int status;
- status = readw(devpriv->daq + dacControl);
+ status = readw(dev->mmio + dacControl);
if ((status & ((chan + 1) * 0x0010)) == 0)
return 0;
return -EBUSY;
@@ -453,11 +446,10 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
* OK, since it works OK without enabling the DAC's,
* let's keep it as simple as possible...
*/
- writew((chan + 2) * 0x0010 | 0x0001,
- devpriv->daq + dacControl);
+ writew((chan + 2) * 0x0010 | 0x0001, dev->mmio + dacControl);
udelay(1000);
#endif
- writew(data[i], devpriv->daq + dacSetting(chan));
+ writew(data[i], dev->mmio + dacSetting(chan));
ret = comedi_timeout(dev, s, insn, daqboard2000_ao_eoc, 0);
if (ret)
@@ -469,8 +461,7 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
* Since we never enabled the DAC's, we don't need
* to disable it...
*/
- writew((chan + 2) * 0x0010 | 0x0000,
- devpriv->daq + dacControl);
+ writew((chan + 2) * 0x0010 | 0x0000, dev->mmio + dacControl);
udelay(1000);
#endif
}
@@ -512,14 +503,13 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev)
static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
{
- struct daqboard2000_private *devpriv = dev->private;
int result = 0;
int i;
int cpld;
/* timeout after 50 tries -> 5ms */
for (i = 0; i < 50; i++) {
- cpld = readw(devpriv->daq + 0x1000);
+ cpld = readw(dev->mmio + 0x1000);
if ((cpld & mask) == mask) {
result = 1;
break;
@@ -532,12 +522,11 @@ static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
static int daqboard2000_writeCPLD(struct comedi_device *dev, int data)
{
- struct daqboard2000_private *devpriv = dev->private;
int result = 0;
udelay(10);
- writew(data, devpriv->daq + 0x1000);
- if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
+ writew(data, dev->mmio + 0x1000);
+ if ((readw(dev->mmio + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
DAQBOARD2000_CPLD_INIT) {
result = 1;
}
@@ -593,23 +582,21 @@ static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev)
static void daqboard2000_adcDisarm(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
-
/* Disable hardware triggers */
udelay(2);
writew(DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable,
- devpriv->daq + trigControl);
+ dev->mmio + trigControl);
udelay(2);
writew(DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable,
- devpriv->daq + trigControl);
+ dev->mmio + trigControl);
/* Stop the scan list FIFO from loading the configuration pipe */
udelay(2);
- writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl);
+ writew(DAQBOARD2000_SeqStopScanList, dev->mmio + acqControl);
/* Stop the pacer clock */
udelay(2);
- writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl);
+ writew(DAQBOARD2000_AdcPacerDisable, dev->mmio + acqControl);
/* Stop the input dma (abort channel 1) */
daqboard2000_adcStopDmaTransfer(dev);
@@ -617,23 +604,22 @@ static void daqboard2000_adcDisarm(struct comedi_device *dev)
static void daqboard2000_activateReferenceDacs(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
unsigned int val;
int timeout;
/* Set the + reference dac value in the FPGA */
- writew(0x80 | DAQBOARD2000_PosRefDacSelect, devpriv->daq + refDacs);
+ writew(0x80 | DAQBOARD2000_PosRefDacSelect, dev->mmio + refDacs);
for (timeout = 0; timeout < 20; timeout++) {
- val = readw(devpriv->daq + dacControl);
+ val = readw(dev->mmio + dacControl);
if ((val & DAQBOARD2000_RefBusy) == 0)
break;
udelay(2);
}
/* Set the - reference dac value in the FPGA */
- writew(0x80 | DAQBOARD2000_NegRefDacSelect, devpriv->daq + refDacs);
+ writew(0x80 | DAQBOARD2000_NegRefDacSelect, dev->mmio + refDacs);
for (timeout = 0; timeout < 20; timeout++) {
- val = readw(devpriv->daq + dacControl);
+ val = readw(dev->mmio + dacControl);
if ((val & DAQBOARD2000_RefBusy) == 0)
break;
udelay(2);
@@ -673,9 +659,8 @@ static int daqboard2000_8255_cb(int dir, int port, int data,
if (dir) {
writew(data, mmio_base + port * 2);
return 0;
- } else {
- return readw(mmio_base + port * 2);
}
+ return readw(mmio_base + port * 2);
}
static const void *daqboard2000_find_boardinfo(struct comedi_device *dev,
@@ -719,8 +704,8 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
return result;
devpriv->plx = pci_ioremap_bar(pcidev, 0);
- devpriv->daq = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->plx || !devpriv->daq)
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!devpriv->plx || !dev->mmio)
return -ENOMEM;
result = comedi_alloc_subdevices(dev, 3);
@@ -759,7 +744,7 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[2];
result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
- (unsigned long)(devpriv->daq + dioP2ExpansionIO8Bit));
+ (unsigned long)(dev->mmio + dioP2ExpansionIO8Bit));
if (result)
return result;
@@ -773,8 +758,8 @@ static void daqboard2000_detach(struct comedi_device *dev)
if (dev->irq)
free_irq(dev->irq, dev);
if (devpriv) {
- if (devpriv->daq)
- iounmap(devpriv->daq);
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (devpriv->plx)
iounmap(devpriv->plx);
}
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index c5e352fb5555..fcf916a80c8d 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -273,7 +273,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
else
data[n] = (1 << 15) - (lsb | (msb & 0x7f) << 8);
} else {
- comedi_error(dev, "bug! unknown ai encoding");
+ dev_err(dev->class_dev, "bug! unknown ai encoding\n");
return -1;
}
}
@@ -452,7 +452,6 @@ static int das08_counter_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
return 2;
}
diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c
index d94af09151b0..4ce3eb0a64cc 100644
--- a/drivers/staging/comedi/drivers/das08_pci.c
+++ b/drivers/staging/comedi/drivers/das08_pci.c
@@ -38,8 +38,6 @@
#include "das08.h"
-#define PCI_DEVICE_ID_PCIDAS08 0x0029
-
static const struct das08_board_struct das08_pci_boards[] = {
{
.name = "pci-das08",
@@ -90,7 +88,7 @@ static int das08_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id das08_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) },
+ { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0029) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, das08_pci_table);
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 2feecf199f27..057bc16f8ddc 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -506,18 +506,18 @@ static void das16_ai_disable(struct comedi_device *dev)
static int disable_dma_on_even(struct comedi_device *dev)
{
struct das16_private_struct *devpriv = dev->private;
- int residue;
- int i;
static const int disable_limit = 100;
static const int enable_timeout = 100;
+ int residue;
+ int new_residue;
+ int i;
+ int j;
disable_dma(devpriv->dma_chan);
residue = get_dma_residue(devpriv->dma_chan);
for (i = 0; i < disable_limit && (residue % 2); ++i) {
- int j;
enable_dma(devpriv->dma_chan);
for (j = 0; j < enable_timeout; ++j) {
- int new_residue;
udelay(2);
new_residue = get_dma_residue(devpriv->dma_chan);
if (new_residue != residue)
@@ -729,14 +729,14 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
}
static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
- int rounding_flags)
+ unsigned int flags)
{
struct das16_private_struct *devpriv = dev->private;
unsigned long timer_base = dev->iobase + DAS16_TIMER_BASE_REG;
i8253_cascade_ns_to_timer(devpriv->clockbase,
&devpriv->divisor1, &devpriv->divisor2,
- &ns, rounding_flags);
+ &ns, flags);
i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
@@ -782,9 +782,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* set counter mode and counts */
- cmd->convert_arg =
- das16_set_pacer(dev, cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags);
/* enable counters */
byte = 0;
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index ec039fbff0f9..5b6998b54060 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -60,7 +60,6 @@ irq can be omitted, although the cmd interface will not work without it.
#include "8253.h"
#include "comedi_fc.h"
-#define DAS16M1_SIZE 16
#define DAS16M1_SIZE2 8
#define FIFO_SIZE 1024 /* 1024 sample fifo */
@@ -126,7 +125,7 @@ static const struct comedi_lrange range_das16m1 = {
struct das16m1_private_struct {
unsigned int control_state;
- volatile unsigned int adc_count; /* number of samples completed */
+ unsigned int adc_count; /* number of samples completed */
/* initial value in lower half of hardware conversion counter,
* needed to keep track of whether new count has been loaded into
* counter yet (loaded by first sample conversion) */
@@ -460,7 +459,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
* overrun interrupts, but we might as well try */
if (status & OVRUN) {
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_error(dev, "fifo overflow");
+ dev_err(dev->class_dev, "fifo overflow\n");
}
cfc_handle_events(dev, s);
@@ -477,7 +476,7 @@ static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s)
das16m1_handler(dev, status);
spin_unlock_irqrestore(&dev->spinlock, flags);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static irqreturn_t das16m1_interrupt(int irq, void *d)
@@ -486,7 +485,7 @@ static irqreturn_t das16m1_interrupt(int irq, void *d)
struct comedi_device *dev = d;
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
/* prevent race with comedi_poll() */
@@ -495,7 +494,7 @@ static irqreturn_t das16m1_interrupt(int irq, void *d)
status = inb(dev->iobase + DAS16M1_CS);
if ((status & (IRQDATA | OVRUN)) == 0) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
spin_unlock(&dev->spinlock);
return IRQ_NONE;
}
@@ -549,7 +548,7 @@ static int das16m1_attach(struct comedi_device *dev,
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], DAS16M1_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
/* Request an additional region for the 8255 */
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index 859519026c4c..0cfca33965f6 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -421,7 +421,7 @@ static const struct das1800_board das1800_boards[] = {
};
struct das1800_private {
- volatile unsigned int count; /* number of data points left to be taken */
+ 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 */
unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
int irq_dma_bits; /* bits for control register b */
@@ -430,7 +430,7 @@ struct das1800_private {
int dma_bits;
unsigned int dma0; /* dma channels used */
unsigned int dma1;
- volatile unsigned int dma_current; /* dma channel currently in use */
+ unsigned int dma_current; /* dma channel currently in use */
uint16_t *ai_buf0; /* pointers to dma buffers */
uint16_t *ai_buf1;
uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
@@ -492,7 +492,6 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev,
numPoints * sizeof(devpriv->ai_buf0[0]));
if (cmd->stop_src == TRIG_COUNT)
devpriv->count -= numPoints;
- return;
}
static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
@@ -517,8 +516,6 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
if (cmd->stop_src == TRIG_COUNT)
devpriv->count--;
}
-
- return;
}
/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
@@ -549,8 +546,6 @@ static void das1800_flush_dma_channel(struct comedi_device *dev,
cfc_write_array_to_buffer(s, buffer, num_bytes);
if (cmd->stop_src == TRIG_COUNT)
devpriv->count -= num_samples;
-
- return;
}
/* flushes remaining data from board when external trigger has stopped acquisition
@@ -583,8 +578,6 @@ static void das1800_flush_dma(struct comedi_device *dev,
/* get any remaining samples in fifo */
das1800_handle_fifo_not_empty(dev, s);
-
- return;
}
static void das1800_handle_dma(struct comedi_device *dev,
@@ -619,8 +612,6 @@ static void das1800_handle_dma(struct comedi_device *dev,
}
}
}
-
- return;
}
static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -663,7 +654,7 @@ static void das1800_ai_handler(struct comedi_device *dev)
if (status & OVF) {
/* clear OVF interrupt bit */
outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
- comedi_error(dev, "DAS1800 FIFO overflow");
+ dev_err(dev->class_dev, "FIFO overflow\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return;
@@ -696,7 +687,7 @@ static int das1800_ai_poll(struct comedi_device *dev,
das1800_ai_handler(dev);
spin_unlock_irqrestore(&dev->spinlock, flags);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static irqreturn_t das1800_interrupt(int irq, void *d)
@@ -705,7 +696,7 @@ static irqreturn_t das1800_interrupt(int irq, void *d)
unsigned int status;
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
@@ -1060,8 +1051,6 @@ static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
enable_dma(devpriv->dma1);
}
release_dma_lock(lock_flags);
-
- return;
}
/* programs channel/gain list into card */
@@ -1088,8 +1077,6 @@ static void program_chanlist(struct comedi_device *dev,
}
outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-
- return;
}
/* analog input do_cmd */
@@ -1192,7 +1179,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
break;
}
if (i == timeout) {
- comedi_error(dev, "timeout");
+ dev_err(dev->class_dev, "timeout\n");
n = -ETIME;
goto exit;
}
@@ -1301,7 +1288,6 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
dev_err(dev->class_dev,
"dma 5,6 / 6,7 / or 7,5\n");
return -EINVAL;
- break;
}
if (request_dma(dma0, dev->driver->driver_name)) {
dev_err(dev->class_dev,
@@ -1343,84 +1329,60 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
static int das1800_probe(struct comedi_device *dev)
{
+ const struct das1800_board *board = comedi_board(dev);
+ int index;
int id;
- int board;
- id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
- board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
+ /* calc the offset to the boardinfo that was found by the core */
+ index = board - das1800_boards;
+ /* verify that the board id matches the boardinfo */
+ id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
switch (id) {
case 0x3:
- if (board == das1801st_da || board == das1802st_da ||
- board == das1701st_da || board == das1702st_da) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800st-da series\n");
- return das1801st;
+ if (index == das1801st_da || index == das1802st_da ||
+ index == das1701st_da || index == das1702st_da)
+ return index;
+ index = das1801st;
break;
case 0x4:
- if (board == das1802hr_da || board == das1702hr_da) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1802hr-da\n");
- return das1802hr;
+ if (index == das1802hr_da || index == das1702hr_da)
+ return index;
+ index = das1802hr;
break;
case 0x5:
- if (board == das1801ao || board == das1802ao ||
- board == das1701ao || board == das1702ao) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800ao series\n");
- return das1801ao;
+ if (index == das1801ao || index == das1802ao ||
+ index == das1701ao || index == das1702ao)
+ return index;
+ index = das1801ao;
break;
case 0x6:
- if (board == das1802hr || board == das1702hr) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1802hr\n");
- return das1802hr;
+ if (index == das1802hr || index == das1702hr)
+ return index;
+ index = das1802hr;
break;
case 0x7:
- if (board == das1801st || board == das1802st ||
- board == das1701st || board == das1702st) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800st series\n");
- return das1801st;
+ if (index == das1801st || index == das1802st ||
+ index == das1701st || index == das1702st)
+ return index;
+ index = das1801st;
break;
case 0x8:
- if (board == das1801hc || board == das1802hc) {
- dev_dbg(dev->class_dev, "Board model: %s\n",
- das1800_boards[board].name);
- return board;
- }
- printk
- (" Board model (probed, not recommended): das-1800hc series\n");
- return das1801hc;
+ if (index == das1801hc || index == das1802hc)
+ return index;
+ index = das1801hc;
break;
default:
- printk
- (" Board model: probe returned 0x%x (unknown, please report)\n",
- id);
- return board;
+ dev_err(dev->class_dev,
+ "Board model: probe returned 0x%x (unknown, please report)\n",
+ id);
break;
}
- return -1;
+ dev_err(dev->class_dev,
+ "Board model (probed, not recommended): %s series\n",
+ das1800_boards[index].name);
+
+ return index;
}
static int das1800_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 6f7f8d531dd5..cbbb29797b83 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -65,7 +65,6 @@ cmd triggers supported:
#include "8253.h"
#include "comedi_fc.h"
-#define DAS800_SIZE 8
#define N_CHAN_AI 8 /* number of analog input channels */
/* Registers for the das800 */
@@ -686,7 +685,7 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], DAS800_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index ad7a5d53b97b..e9cd2517ad81 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -40,9 +40,6 @@ Configuration Options:
#include "comedi_fc.h"
/* Board register addresses */
-
-#define DMM32AT_MEMSIZE 0x10
-
#define DMM32AT_CONV 0x00
#define DMM32AT_AILSB 0x00
#define DMM32AT_AUXDOUT 0x01
@@ -237,7 +234,7 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev,
return n;
}
-static int dmm32at_ns_to_timer(unsigned int *ns, int round)
+static int dmm32at_ns_to_timer(unsigned int *ns, unsigned int flags)
{
/* trivial timer */
return *ns;
@@ -352,12 +349,12 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- dmm32at_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ dmm32at_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- dmm32at_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ dmm32at_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -491,7 +488,7 @@ static irqreturn_t dmm32at_isr(int irq, void *d)
int i;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
@@ -684,7 +681,7 @@ static int dmm32at_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
- ret = comedi_request_region(dev, it->options[0], DMM32AT_MEMSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index 4263014426f8..ad8ba0be4878 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -40,9 +40,6 @@ Configuration options:
#define DT2801_MAX_DMA_SIZE (64 * 1024)
-/* Ports */
-#define DT2801_IOSIZE 2
-
/* define's */
/* ====================== */
@@ -552,7 +549,7 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret = 0;
int n_ai_chans;
- ret = comedi_request_region(dev, it->options[0], DT2801_IOSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
index ba7c2ba618e6..a2e9caf3256f 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -169,8 +169,6 @@ static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = {
#define TIMEOUT 10000
-#define DT2811_SIZE 8
-
#define DT2811_ADCSR 0
#define DT2811_ADGCR 1
#define DT2811_ADDATLO 2
@@ -344,7 +342,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret;
struct comedi_subdevice *s;
- ret = comedi_request_region(dev, it->options[0], DT2811_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index 904c9f0e4afb..9216c35c414e 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -42,8 +42,6 @@ addition, the clock does not seem to be very accurate.
#include "comedi_fc.h"
-#define DT2814_SIZE 2
-
#define DT2814_CSR 0
#define DT2814_DATA 1
@@ -171,7 +169,7 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->scan_begin_arg;
- dt2814_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ dt2814_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
if (err)
@@ -187,9 +185,7 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
int chan;
int trigvar;
- trigvar =
- dt2814_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ trigvar = dt2814_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
chan = CR_CHAN(cmd->chanlist[0]);
@@ -209,7 +205,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d)
int data;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
@@ -245,7 +241,7 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret;
int i;
- ret = comedi_request_region(dev, it->options[0], DT2814_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index b9ac4ed8babb..a98fb66fdd53 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -56,8 +56,6 @@ Configuration options:
#include <linux/delay.h>
-#define DT2815_SIZE 2
-
#define DT2815_DATA 0
#define DT2815_STATUS 1
@@ -154,7 +152,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
const struct comedi_lrange *current_range_type, *voltage_range_type;
int ret;
- ret = comedi_request_region(dev, it->options[0], DT2815_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x2);
if (ret)
return ret;
@@ -195,6 +193,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
status = inb(dev->iobase + DT2815_STATUS);
if (status == 4) {
unsigned int program;
+
program = (it->options[4] & 0x3) << 3 | 0x7;
outb(program, dev->iobase + DT2815_DATA);
dev_dbg(dev->class_dev, "program: 0x%x (@t=%d)\n",
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
index bf589936e546..5131deebf66f 100644
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -36,8 +36,6 @@ Configuration options:
#include <linux/module.h>
#include "../comedidev.h"
-#define DT2817_SIZE 5
-
#define DT2817_CR 0
#define DT2817_DATA 1
@@ -114,7 +112,7 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it)
int ret;
struct comedi_subdevice *s;
- ret = comedi_request_region(dev, it->options[0], DT2817_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x5);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index c2a66dcf99fe..5de26745783a 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -1,55 +1,69 @@
/*
- comedi/drivers/dt282x.c
- Hardware driver for Data Translation DT2821 series
-
- 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.
+ * dt282x.c
+ * Comedi driver for Data Translation DT2821 series
+ *
+ * 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.
*/
+
/*
-Driver: dt282x
-Description: Data Translation DT2821 series (including DT-EZ)
-Author: ds
-Devices: [Data Translation] DT2821 (dt2821),
- DT2821-F-16SE (dt2821-f), DT2821-F-8DI (dt2821-f),
- DT2821-G-16SE (dt2821-f), DT2821-G-8DI (dt2821-g),
- DT2823 (dt2823),
- DT2824-PGH (dt2824-pgh), DT2824-PGL (dt2824-pgl), DT2825 (dt2825),
- DT2827 (dt2827), DT2828 (dt2828), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
- DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
-Status: complete
-Updated: Wed, 22 Aug 2001 17:11:34 -0700
-
-Configuration options:
- [0] - I/O port base address
- [1] - IRQ
- [2] - DMA 1
- [3] - DMA 2
- [4] - AI jumpered for 0=single ended, 1=differential
- [5] - AI jumpered for 0=straight binary, 1=2's complement
- [6] - AO 0 jumpered for 0=straight binary, 1=2's complement
- [7] - AO 1 jumpered for 0=straight binary, 1=2's complement
- [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
- [9] - AO 0 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
- 4=[-2.5,2.5]
- [10]- A0 1 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
- 4=[-2.5,2.5]
-
-Notes:
- - AO commands might be broken.
- - If you try to run a command on both the AI and AO subdevices
- simultaneously, bad things will happen. The driver needs to
- be fixed to check for this situation and return an error.
-*/
+ * Driver: dt282x
+ * Description: Data Translation DT2821 series (including DT-EZ)
+ * Author: ds
+ * Devices: (Data Translation) DT2821 [dt2821]
+ * (Data Translation) DT2821-F-16SE [dt2821-f]
+ * (Data Translation) DT2821-F-8DI [dt2821-f]
+ * (Data Translation) DT2821-G-16SE [dt2821-g]
+ * (Data Translation) DT2821-G-8DI [dt2821-g]
+ * (Data Translation) DT2823 [dt2823]
+ * (Data Translation) DT2824-PGH [dt2824-pgh]
+ * (Data Translation) DT2824-PGL [dt2824-pgl]
+ * (Data Translation) DT2825 [dt2825]
+ * (Data Translation) DT2827 [dt2827]
+ * (Data Translation) DT2828 [dt2828]
+ * (Data Translation) DT2928 [dt2829]
+ * (Data Translation) DT21-EZ [dt21-ez]
+ * (Data Translation) DT23-EZ [dt23-ez]
+ * (Data Translation) DT24-EZ [dt24-ez]
+ * (Data Translation) DT24-EZ-PGL [dt24-ez-pgl]
+ * Status: complete
+ * Updated: Wed, 22 Aug 2001 17:11:34 -0700
+ *
+ * Configuration options:
+ * [0] - I/O port base address
+ * [1] - IRQ (optional, required for async command support)
+ * [2] - DMA 1 (optional, required for async command support)
+ * [3] - DMA 2 (optional, required for async command support)
+ * [4] - AI jumpered for 0=single ended, 1=differential
+ * [5] - AI jumpered for 0=straight binary, 1=2's complement
+ * [6] - AO 0 data format (deprecated, see below)
+ * [7] - AO 1 data format (deprecated, see below)
+ * [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
+ * [9] - AO channel 0 range (deprecated, see below)
+ * [10]- AO channel 1 range (deprecated, see below)
+ *
+ * Notes:
+ * - AO commands might be broken.
+ * - If you try to run a command on both the AI and AO subdevices
+ * simultaneously, bad things will happen. The driver needs to
+ * be fixed to check for this situation and return an error.
+ * - AO range is not programmable. The AO subdevice has a range_table
+ * containing all the possible analog output ranges. Use the range
+ * that matches your board configuration to convert between data
+ * values and physical units. The format of the data written to the
+ * board is handled automatically based on the unipolar/bipolar
+ * range that is selected.
+ */
#include <linux/module.h>
#include "../comedidev.h"
@@ -63,93 +77,53 @@ Notes:
#include "comedi_fc.h"
-#define DT2821_SIZE 0x10
-
-/*
- * Registers in the DT282x
- */
-
-#define DT2821_ADCSR 0x00 /* A/D Control/Status */
-#define DT2821_CHANCSR 0x02 /* Channel Control/Status */
-#define DT2821_ADDAT 0x04 /* A/D data */
-#define DT2821_DACSR 0x06 /* D/A Control/Status */
-#define DT2821_DADAT 0x08 /* D/A data */
-#define DT2821_DIODAT 0x0a /* digital data */
-#define DT2821_SUPCSR 0x0c /* Supervisor Control/Status */
-#define DT2821_TMRCTR 0x0e /* Timer/Counter */
-
-/*
- * At power up, some registers are in a well-known state. The
- * masks and values are as follows:
- */
-
-#define DT2821_ADCSR_MASK 0xfff0
-#define DT2821_ADCSR_VAL 0x7c00
-
-#define DT2821_CHANCSR_MASK 0xf0f0
-#define DT2821_CHANCSR_VAL 0x70f0
-
-#define DT2821_DACSR_MASK 0x7c93
-#define DT2821_DACSR_VAL 0x7c90
-
-#define DT2821_SUPCSR_MASK 0xf8ff
-#define DT2821_SUPCSR_VAL 0x0000
-
-#define DT2821_TMRCTR_MASK 0xff00
-#define DT2821_TMRCTR_VAL 0xf000
-
/*
- * Bit fields of each register
+ * Register map
*/
-
-/* ADCSR */
-
-#define DT2821_ADERR 0x8000 /* (R) 1 for A/D error */
-#define DT2821_ADCLK 0x0200 /* (R/W) A/D clock enable */
- /* 0x7c00 read as 1's */
-#define DT2821_MUXBUSY 0x0100 /* (R) multiplexer busy */
-#define DT2821_ADDONE 0x0080 /* (R) A/D done */
-#define DT2821_IADDONE 0x0040 /* (R/W) interrupt on A/D done */
- /* 0x0030 gain select */
- /* 0x000f channel select */
-
-/* CHANCSR */
-
-#define DT2821_LLE 0x8000 /* (R/W) Load List Enable */
- /* 0x7000 read as 1's */
- /* 0x0f00 (R) present address */
- /* 0x00f0 read as 1's */
- /* 0x000f (R) number of entries - 1 */
-
-/* DACSR */
-
-#define DT2821_DAERR 0x8000 /* (R) D/A error */
-#define DT2821_YSEL 0x0200 /* (R/W) DAC 1 select */
-#define DT2821_SSEL 0x0100 /* (R/W) single channel select */
-#define DT2821_DACRDY 0x0080 /* (R) DAC ready */
-#define DT2821_IDARDY 0x0040 /* (R/W) interrupt on DAC ready */
-#define DT2821_DACLK 0x0020 /* (R/W) D/A clock enable */
-#define DT2821_HBOE 0x0002 /* (R/W) DIO high byte output enable */
-#define DT2821_LBOE 0x0001 /* (R/W) DIO low byte output enable */
-
-/* SUPCSR */
-
-#define DT2821_DMAD 0x8000 /* (R) DMA done */
-#define DT2821_ERRINTEN 0x4000 /* (R/W) interrupt on error */
-#define DT2821_CLRDMADNE 0x2000 /* (W) clear DMA done */
-#define DT2821_DDMA 0x1000 /* (R/W) dual DMA */
-#define DT2821_DS1 0x0800 /* (R/W) DMA select 1 */
-#define DT2821_DS0 0x0400 /* (R/W) DMA select 0 */
-#define DT2821_BUFFB 0x0200 /* (R/W) buffer B selected */
-#define DT2821_SCDN 0x0100 /* (R) scan done */
-#define DT2821_DACON 0x0080 /* (W) DAC single conversion */
-#define DT2821_ADCINIT 0x0040 /* (W) A/D initialize */
-#define DT2821_DACINIT 0x0020 /* (W) D/A initialize */
-#define DT2821_PRLD 0x0010 /* (W) preload multiplexer */
-#define DT2821_STRIG 0x0008 /* (W) software trigger */
-#define DT2821_XTRIG 0x0004 /* (R/W) external trigger enable */
-#define DT2821_XCLK 0x0002 /* (R/W) external clock enable */
-#define DT2821_BDINIT 0x0001 /* (W) initialize board */
+#define DT2821_ADCSR_REG 0x00
+#define DT2821_ADCSR_ADERR (1 << 15)
+#define DT2821_ADCSR_ADCLK (1 << 9)
+#define DT2821_ADCSR_MUXBUSY (1 << 8)
+#define DT2821_ADCSR_ADDONE (1 << 7)
+#define DT2821_ADCSR_IADDONE (1 << 6)
+#define DT2821_ADCSR_GS(x) (((x) & 0x3) << 4)
+#define DT2821_ADCSR_CHAN(x) (((x) & 0xf) << 0)
+#define DT2821_CHANCSR_REG 0x02
+#define DT2821_CHANCSR_LLE (1 << 15)
+#define DT2821_CHANCSR_PRESLA(x) (((x) & 0xf) >> 8)
+#define DT2821_CHANCSR_NUMB(x) ((((x) - 1) & 0xf) << 0)
+#define DT2821_ADDAT_REG 0x04
+#define DT2821_DACSR_REG 0x06
+#define DT2821_DACSR_DAERR (1 << 15)
+#define DT2821_DACSR_YSEL(x) ((x) << 9)
+#define DT2821_DACSR_SSEL (1 << 8)
+#define DT2821_DACSR_DACRDY (1 << 7)
+#define DT2821_DACSR_IDARDY (1 << 6)
+#define DT2821_DACSR_DACLK (1 << 5)
+#define DT2821_DACSR_HBOE (1 << 1)
+#define DT2821_DACSR_LBOE (1 << 0)
+#define DT2821_DADAT_REG 0x08
+#define DT2821_DIODAT_REG 0x0a
+#define DT2821_SUPCSR_REG 0x0c
+#define DT2821_SUPCSR_DMAD (1 << 15)
+#define DT2821_SUPCSR_ERRINTEN (1 << 14)
+#define DT2821_SUPCSR_CLRDMADNE (1 << 13)
+#define DT2821_SUPCSR_DDMA (1 << 12)
+#define DT2821_SUPCSR_DS_PIO (0 << 10)
+#define DT2821_SUPCSR_DS_AD_CLK (1 << 10)
+#define DT2821_SUPCSR_DS_DA_CLK (2 << 10)
+#define DT2821_SUPCSR_DS_AD_TRIG (3 << 10)
+#define DT2821_SUPCSR_BUFFB (1 << 9)
+#define DT2821_SUPCSR_SCDN (1 << 8)
+#define DT2821_SUPCSR_DACON (1 << 7)
+#define DT2821_SUPCSR_ADCINIT (1 << 6)
+#define DT2821_SUPCSR_DACINIT (1 << 5)
+#define DT2821_SUPCSR_PRLD (1 << 4)
+#define DT2821_SUPCSR_STRIG (1 << 3)
+#define DT2821_SUPCSR_XTRIG (1 << 2)
+#define DT2821_SUPCSR_XCLK (1 << 1)
+#define DT2821_SUPCSR_BDINIT (1 << 0)
+#define DT2821_TMRCTR_REG 0x0e
static const struct comedi_lrange range_dt282x_ai_lo_bipolar = {
4, {
@@ -205,146 +179,326 @@ static const struct comedi_lrange range_dt282x_ai_hi_unipolar = {
}
};
+/*
+ * The Analog Output range is set per-channel using jumpers on the board.
+ * All of these ranges may not be available on some DT2821 series boards.
+ * The default jumper setting has both channels set for +/-10V output.
+ */
+static const struct comedi_lrange dt282x_ao_range = {
+ 5, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ }
+};
+
struct dt282x_board {
const char *name;
- int adbits;
+ unsigned int ai_maxdata;
int adchan_se;
int adchan_di;
int ai_speed;
int ispgl;
int dachan;
- int dabits;
+ unsigned int ao_maxdata;
+};
+
+static const struct dt282x_board boardtypes[] = {
+ {
+ .name = "dt2821",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2821-f",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 6500,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2821-g",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 4000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2823",
+ .ai_maxdata = 0xffff,
+ .adchan_di = 4,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0xffff,
+ }, {
+ .name = "dt2824-pgh",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ }, {
+ .name = "dt2824-pgl",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ .ispgl = 1,
+ }, {
+ .name = "dt2825",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 20000,
+ .ispgl = 1,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2827",
+ .ai_maxdata = 0xffff,
+ .adchan_di = 4,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2828",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 4,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt2829",
+ .ai_maxdata = 0xffff,
+ .adchan_se = 8,
+ .ai_speed = 33250,
+ .dachan = 2,
+ .ao_maxdata = 0xffff,
+ }, {
+ .name = "dt21-ez",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ .dachan = 2,
+ .ao_maxdata = 0x0fff,
+ }, {
+ .name = "dt23-ez",
+ .ai_maxdata = 0xffff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ }, {
+ .name = "dt24-ez",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ }, {
+ .name = "dt24-ez-pgl",
+ .ai_maxdata = 0x0fff,
+ .adchan_se = 16,
+ .adchan_di = 8,
+ .ai_speed = 10000,
+ .ispgl = 1,
+ },
};
struct dt282x_private {
- int ad_2scomp; /* we have 2's comp jumper set */
- int da0_2scomp; /* same, for DAC0 */
- int da1_2scomp; /* same, for DAC1 */
+ unsigned int ad_2scomp:1;
- const struct comedi_lrange *darangelist[2];
+ unsigned int divisor;
- unsigned short ao[2];
+ unsigned short ao_readback[2];
- volatile int dacsr; /* software copies of registers */
- volatile int adcsr;
- volatile int supcsr;
+ int dacsr; /* software copies of registers */
+ int adcsr;
+ int supcsr;
- volatile int ntrig;
- volatile int nread;
+ int ntrig;
+ int nread;
struct {
int chan;
unsigned short *buf; /* DMA buffer */
- volatile int size; /* size of current transfer */
+ int size; /* size of current transfer */
} dma[2];
int dma_maxsize; /* max size of DMA transfer (in bytes) */
- int usedma; /* driver uses DMA */
- volatile int current_dma_index;
+ int current_dma_index;
int dma_dir;
};
-/*
- * Some useless abstractions
- */
-#define chan_to_DAC(a) ((a)&1)
+static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
+{
+ struct dt282x_private *devpriv = dev->private;
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
-static int prep_ai_dma(struct comedi_device *dev, int chan, int size);
-static int prep_ao_dma(struct comedi_device *dev, int chan, int size);
-static int dt282x_ai_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static int dt282x_ao_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static int dt282x_ns_to_timer(int *nanosec, int round_mode);
-static void dt282x_disable_dma(struct comedi_device *dev);
+ if (!devpriv->ntrig)
+ return 0;
-static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
+ if (n == 0)
+ n = devpriv->dma_maxsize;
+ if (n > devpriv->ntrig * 2)
+ n = devpriv->ntrig * 2;
+ devpriv->ntrig -= n / 2;
-static void dt282x_munge(struct comedi_device *dev, unsigned short *buf,
- unsigned int nbytes)
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+ set_dma_mode(dma_chan, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
+}
+
+static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
- unsigned int i;
- unsigned short mask = (1 << board->adbits) - 1;
- unsigned short sign = 1 << (board->adbits - 1);
- int n;
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
- if (devpriv->ad_2scomp)
- sign = 1 << (board->adbits - 1);
- else
- sign = 0;
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
- if (nbytes % 2)
- comedi_error(dev, "bug! odd number of bytes from dma xfer");
- n = nbytes / 2;
- for (i = 0; i < n; i++)
- buf[i] = (buf[i] & mask) ^ sign;
+ set_dma_mode(dma_chan, DMA_MODE_WRITE);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
}
-static void dt282x_ao_dma_interrupt(struct comedi_device *dev)
+static void dt282x_disable_dma(struct comedi_device *dev)
{
struct dt282x_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->write_subdev;
- void *ptr;
- int size;
+
+ disable_dma(devpriv->dma[0].chan);
+ disable_dma(devpriv->dma[1].chan);
+}
+
+static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
+{
+ unsigned int prescale, base, divider;
+
+ for (prescale = 0; prescale < 16; prescale++) {
+ if (prescale == 1)
+ continue;
+ base = 250 * (1 << prescale);
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*ns + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*ns) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*ns + base - 1) / base;
+ break;
+ }
+ if (divider < 256) {
+ *ns = divider * base;
+ return (prescale << 8) | (255 - divider);
+ }
+ }
+ base = 250 * (1 << 15);
+ divider = 255;
+ *ns = divider * base;
+ return (15 << 8) | (255 - divider);
+}
+
+static void dt282x_munge(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned short *buf,
+ unsigned int nbytes)
+{
+ struct dt282x_private *devpriv = dev->private;
+ unsigned int val;
int i;
- outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR);
+ if (nbytes % 2)
+ dev_err(dev->class_dev,
+ "bug! odd number of bytes from dma xfer\n");
- if (!s->async->prealloc_buf) {
- dev_err(dev->class_dev, "no buffer in %s\n", __func__);
- return;
+ for (i = 0; i < nbytes / 2; i++) {
+ val = buf[i];
+ val &= s->maxdata;
+ if (devpriv->ad_2scomp)
+ val = comedi_offset_munge(s, val);
+
+ buf[i] = val;
}
+}
- i = devpriv->current_dma_index;
- ptr = devpriv->dma[i].buf;
+static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct dt282x_private *devpriv = dev->private;
+ int cur_dma = devpriv->current_dma_index;
+ void *ptr = devpriv->dma[cur_dma].buf;
+ int size;
- disable_dma(devpriv->dma[i].chan);
+ outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
+ dev->iobase + DT2821_SUPCSR_REG);
- devpriv->current_dma_index = 1 - i;
+ disable_dma(devpriv->dma[cur_dma].chan);
+
+ devpriv->current_dma_index = 1 - cur_dma;
size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize);
if (size == 0) {
dev_err(dev->class_dev, "AO underrun\n");
s->async->events |= COMEDI_CB_OVERFLOW;
- return;
+ } else {
+ dt282x_prep_ao_dma(dev, cur_dma, size);
}
- prep_ao_dma(dev, i, size);
- return;
}
-static void dt282x_ai_dma_interrupt(struct comedi_device *dev)
+static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct dt282x_private *devpriv = dev->private;
- struct comedi_subdevice *s = dev->read_subdev;
- void *ptr;
- int size;
- int i;
+ int cur_dma = devpriv->current_dma_index;
+ void *ptr = devpriv->dma[cur_dma].buf;
+ int size = devpriv->dma[cur_dma].size;
int ret;
- outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
+ dev->iobase + DT2821_SUPCSR_REG);
- if (!s->async->prealloc_buf) {
- dev_err(dev->class_dev, "no buffer in %s\n", __func__);
- return;
- }
-
- i = devpriv->current_dma_index;
- ptr = devpriv->dma[i].buf;
- size = devpriv->dma[i].size;
+ disable_dma(devpriv->dma[cur_dma].chan);
- disable_dma(devpriv->dma[i].chan);
+ devpriv->current_dma_index = 1 - cur_dma;
- devpriv->current_dma_index = 1 - i;
-
- dt282x_munge(dev, ptr, size);
+ dt282x_munge(dev, s, ptr, size);
ret = cfc_write_array_to_buffer(s, ptr, size);
if (ret != size) {
s->async->events |= COMEDI_CB_OVERFLOW;
return;
}
- devpriv->nread -= size / 2;
+ devpriv->nread -= size / 2;
if (devpriv->nread < 0) {
dev_info(dev->class_dev, "nread off by one\n");
devpriv->nread = 0;
@@ -357,67 +511,12 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev)
/* clear the dual dma flag, making this the last dma segment */
/* XXX probably wrong */
if (!devpriv->ntrig) {
- devpriv->supcsr &= ~(DT2821_DDMA);
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr &= ~DT2821_SUPCSR_DDMA;
+ outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
}
#endif
/* restart the channel */
- prep_ai_dma(dev, i, 0);
-}
-
-static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
-{
- struct dt282x_private *devpriv = dev->private;
- int dma_chan;
- unsigned long dma_ptr;
- unsigned long flags;
-
- if (!devpriv->ntrig)
- return 0;
-
- if (n == 0)
- n = devpriv->dma_maxsize;
- if (n > devpriv->ntrig * 2)
- n = devpriv->ntrig * 2;
- devpriv->ntrig -= n / 2;
-
- devpriv->dma[dma_index].size = n;
- dma_chan = devpriv->dma[dma_index].chan;
- dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
-
- set_dma_mode(dma_chan, DMA_MODE_READ);
- flags = claim_dma_lock();
- clear_dma_ff(dma_chan);
- set_dma_addr(dma_chan, dma_ptr);
- set_dma_count(dma_chan, n);
- release_dma_lock(flags);
-
- enable_dma(dma_chan);
-
- return n;
-}
-
-static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
-{
- struct dt282x_private *devpriv = dev->private;
- int dma_chan;
- unsigned long dma_ptr;
- unsigned long flags;
-
- devpriv->dma[dma_index].size = n;
- dma_chan = devpriv->dma[dma_index].chan;
- dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
-
- set_dma_mode(dma_chan, DMA_MODE_WRITE);
- flags = claim_dma_lock();
- clear_dma_ff(dma_chan);
- set_dma_addr(dma_chan, dma_ptr);
- set_dma_count(dma_chan, n);
- release_dma_lock(flags);
-
- enable_dma(dma_chan);
-
- return n;
+ dt282x_prep_ai_dma(dev, cur_dma, 0);
}
static irqreturn_t dt282x_interrupt(int irq, void *d)
@@ -430,42 +529,42 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
int handled = 0;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
- adcsr = inw(dev->iobase + DT2821_ADCSR);
- dacsr = inw(dev->iobase + DT2821_DACSR);
- supcsr = inw(dev->iobase + DT2821_SUPCSR);
- if (supcsr & DT2821_DMAD) {
+ adcsr = inw(dev->iobase + DT2821_ADCSR_REG);
+ dacsr = inw(dev->iobase + DT2821_DACSR_REG);
+ supcsr = inw(dev->iobase + DT2821_SUPCSR_REG);
+ if (supcsr & DT2821_SUPCSR_DMAD) {
if (devpriv->dma_dir == DMA_MODE_READ)
- dt282x_ai_dma_interrupt(dev);
+ dt282x_ai_dma_interrupt(dev, s);
else
- dt282x_ao_dma_interrupt(dev);
+ dt282x_ao_dma_interrupt(dev, s_ao);
handled = 1;
}
- if (adcsr & DT2821_ADERR) {
+ if (adcsr & DT2821_ADCSR_ADERR) {
if (devpriv->nread != 0) {
- comedi_error(dev, "A/D error");
+ dev_err(dev->class_dev, "A/D error\n");
s->async->events |= COMEDI_CB_ERROR;
}
handled = 1;
}
- if (dacsr & DT2821_DAERR) {
- comedi_error(dev, "D/A error");
+ if (dacsr & DT2821_DACSR_DAERR) {
+ dev_err(dev->class_dev, "D/A error\n");
s_ao->async->events |= COMEDI_CB_ERROR;
handled = 1;
}
#if 0
- if (adcsr & DT2821_ADDONE) {
+ if (adcsr & DT2821_ADCSR_ADDONE) {
int ret;
unsigned short data;
- data = inw(dev->iobase + DT2821_ADDAT);
- data &= (1 << board->adbits) - 1;
-
+ data = inw(dev->iobase + DT2821_ADDAT_REG);
+ data &= s->maxdata;
if (devpriv->ad_2scomp)
- data ^= 1 << (board->adbits - 1);
+ data = comedi_offset_munge(s, data);
+
ret = comedi_buf_put(s, data);
if (ret == 0)
@@ -475,9 +574,9 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
if (!devpriv->nread) {
s->async->events |= COMEDI_CB_EOA;
} else {
- if (supcsr & DT2821_SCDN)
- outw(devpriv->supcsr | DT2821_STRIG,
- dev->iobase + DT2821_SUPCSR);
+ if (supcsr & DT2821_SUPCSR_SCDN)
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
}
handled = 1;
}
@@ -492,17 +591,20 @@ static void dt282x_load_changain(struct comedi_device *dev, int n,
unsigned int *chanlist)
{
struct dt282x_private *devpriv = dev->private;
- unsigned int i;
- unsigned int chan, range;
+ int i;
- outw(DT2821_LLE | (n - 1), dev->iobase + DT2821_CHANCSR);
+ outw(DT2821_CHANCSR_LLE | DT2821_CHANCSR_NUMB(n),
+ dev->iobase + DT2821_CHANCSR_REG);
for (i = 0; i < n; i++) {
- chan = CR_CHAN(chanlist[i]);
- range = CR_RANGE(chanlist[i]);
- outw(devpriv->adcsr | (range << 4) | chan,
- dev->iobase + DT2821_ADCSR);
+ unsigned int chan = CR_CHAN(chanlist[i]);
+ unsigned int range = CR_RANGE(chanlist[i]);
+
+ outw(devpriv->adcsr |
+ DT2821_ADCSR_GS(range) |
+ DT2821_ADCSR_CHAN(chan),
+ dev->iobase + DT2821_ADCSR_REG);
}
- outw(n - 1, dev->iobase + DT2821_CHANCSR);
+ outw(DT2821_CHANCSR_NUMB(n), dev->iobase + DT2821_CHANCSR_REG);
}
static int dt282x_ai_timeout(struct comedi_device *dev,
@@ -512,14 +614,14 @@ static int dt282x_ai_timeout(struct comedi_device *dev,
{
unsigned int status;
- status = inw(dev->iobase + DT2821_ADCSR);
+ status = inw(dev->iobase + DT2821_ADCSR_REG);
switch (context) {
- case DT2821_MUXBUSY:
- if ((status & DT2821_MUXBUSY) == 0)
+ case DT2821_ADCSR_MUXBUSY:
+ if ((status & DT2821_ADCSR_MUXBUSY) == 0)
return 0;
break;
- case DT2821_ADDONE:
- if (status & DT2821_ADDONE)
+ case DT2821_ADCSR_ADDONE:
+ if (status & DT2821_ADCSR_ADDONE)
return 0;
break;
default:
@@ -536,47 +638,53 @@ static int dt282x_ai_timeout(struct comedi_device *dev,
*/
static int dt282x_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)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
+ unsigned int val;
int ret;
int i;
/* XXX should we really be enabling the ad clock here? */
- devpriv->adcsr = DT2821_ADCLK;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
+ devpriv->adcsr = DT2821_ADCSR_ADCLK;
+ outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
dt282x_load_changain(dev, 1, &insn->chanspec);
- outw(devpriv->supcsr | DT2821_PRLD, dev->iobase + DT2821_SUPCSR);
- ret = comedi_timeout(dev, s, insn, dt282x_ai_timeout, DT2821_MUXBUSY);
+ outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
+ dev->iobase + DT2821_SUPCSR_REG);
+ ret = comedi_timeout(dev, s, insn,
+ dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
if (ret)
return ret;
for (i = 0; i < insn->n; i++) {
- outw(devpriv->supcsr | DT2821_STRIG,
- dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
- ret = comedi_timeout(dev, s, insn, dt282x_ai_timeout,
- DT2821_ADDONE);
+ ret = comedi_timeout(dev, s, insn,
+ dt282x_ai_timeout, DT2821_ADCSR_ADDONE);
if (ret)
return ret;
- data[i] =
- inw(dev->iobase +
- DT2821_ADDAT) & ((1 << board->adbits) - 1);
+ val = inw(dev->iobase + DT2821_ADDAT_REG);
+ val &= s->maxdata;
if (devpriv->ad_2scomp)
- data[i] ^= (1 << (board->adbits - 1));
+ val = comedi_offset_munge(s, val);
+
+ data[i] = val;
}
return i;
}
static int dt282x_ai_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
const struct dt282x_board *board = comedi_board(dev);
+ struct dt282x_private *devpriv = dev->private;
int err = 0;
unsigned int arg;
@@ -634,7 +742,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->convert_arg;
- dt282x_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (err)
@@ -645,81 +753,62 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
- int timer;
int ret;
- if (devpriv->usedma == 0) {
- comedi_error(dev,
- "driver requires 2 dma channels"
- " to execute command");
- return -EIO;
- }
-
dt282x_disable_dma(dev);
- if (cmd->convert_arg < board->ai_speed)
- cmd->convert_arg = board->ai_speed;
- timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
- outw(timer, dev->iobase + DT2821_TMRCTR);
+ outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
- if (cmd->scan_begin_src == TRIG_FOLLOW) {
- /* internal trigger */
- devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0;
- } else {
- /* external trigger */
- devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0 | DT2821_DS1;
- }
- outw(devpriv->supcsr | DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_ADCINIT,
- dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr = DT2821_SUPCSR_ERRINTEN;
+ if (cmd->scan_begin_src == TRIG_FOLLOW)
+ devpriv->supcsr = DT2821_SUPCSR_DS_AD_CLK;
+ else
+ devpriv->supcsr = DT2821_SUPCSR_DS_AD_TRIG;
+ outw(devpriv->supcsr |
+ DT2821_SUPCSR_CLRDMADNE |
+ DT2821_SUPCSR_BUFFB |
+ DT2821_SUPCSR_ADCINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
devpriv->nread = devpriv->ntrig;
devpriv->dma_dir = DMA_MODE_READ;
devpriv->current_dma_index = 0;
- prep_ai_dma(dev, 0, 0);
+ dt282x_prep_ai_dma(dev, 0, 0);
if (devpriv->ntrig) {
- prep_ai_dma(dev, 1, 0);
- devpriv->supcsr |= DT2821_DDMA;
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR);
+ dt282x_prep_ai_dma(dev, 1, 0);
+ devpriv->supcsr |= DT2821_SUPCSR_DDMA;
+ outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
}
devpriv->adcsr = 0;
dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
- devpriv->adcsr = DT2821_ADCLK | DT2821_IADDONE;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
+ devpriv->adcsr = DT2821_ADCSR_ADCLK | DT2821_ADCSR_IADDONE;
+ outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
- outw(devpriv->supcsr | DT2821_PRLD, dev->iobase + DT2821_SUPCSR);
- ret = comedi_timeout(dev, s, NULL, dt282x_ai_timeout, DT2821_MUXBUSY);
+ outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
+ dev->iobase + DT2821_SUPCSR_REG);
+ ret = comedi_timeout(dev, s, NULL,
+ dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
if (ret)
return ret;
if (cmd->scan_begin_src == TRIG_FOLLOW) {
- outw(devpriv->supcsr | DT2821_STRIG,
- dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
} else {
- devpriv->supcsr |= DT2821_XTRIG;
- outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr |= DT2821_SUPCSR_XTRIG;
+ outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
}
return 0;
}
-static void dt282x_disable_dma(struct comedi_device *dev)
-{
- struct dt282x_private *devpriv = dev->private;
-
- if (devpriv->usedma) {
- disable_dma(devpriv->dma[0].chan);
- disable_dma(devpriv->dma[1].chan);
- }
-}
-
static int dt282x_ai_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
@@ -728,101 +817,66 @@ static int dt282x_ai_cancel(struct comedi_device *dev,
dt282x_disable_dma(dev);
devpriv->adcsr = 0;
- outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR);
+ outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
devpriv->supcsr = 0;
- outw(devpriv->supcsr | DT2821_ADCINIT, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_ADCINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
return 0;
}
-static int dt282x_ns_to_timer(int *nanosec, int round_mode)
-{
- int prescale, base, divider;
-
- for (prescale = 0; prescale < 16; prescale++) {
- if (prescale == 1)
- continue;
- base = 250 * (1 << prescale);
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- divider = (*nanosec + base / 2) / base;
- break;
- case TRIG_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case TRIG_ROUND_UP:
- divider = (*nanosec + base - 1) / base;
- break;
- }
- if (divider < 256) {
- *nanosec = divider * base;
- return (prescale << 8) | (255 - divider);
- }
- }
- base = 250 * (1 << 15);
- divider = 255;
- *nanosec = divider * base;
- return (15 << 8) | (255 - divider);
-}
-
-/*
- * Analog output routine. Selects single channel conversion,
- * selects correct channel, converts from 2's compliment to
- * offset binary if necessary, loads the data into the DAC
- * data register, and performs the conversion.
- */
static int dt282x_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 dt282x_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
- data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
- return 1;
+ return insn->n;
}
static int dt282x_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)
{
- const struct dt282x_board *board = comedi_board(dev);
struct dt282x_private *devpriv = dev->private;
- unsigned short d;
- unsigned int chan;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int val;
+ int i;
- chan = CR_CHAN(insn->chanspec);
- d = data[0];
- d &= (1 << board->dabits) - 1;
- devpriv->ao[chan] = d;
+ devpriv->dacsr |= DT2821_DACSR_SSEL | DT2821_DACSR_YSEL(chan);
- devpriv->dacsr |= DT2821_SSEL;
+ for (i = 0; i < insn->n; i++) {
+ val = data[i];
+ devpriv->ao_readback[chan] = val;
- if (chan) {
- /* select channel */
- devpriv->dacsr |= DT2821_YSEL;
- if (devpriv->da0_2scomp)
- d ^= (1 << (board->dabits - 1));
- } else {
- devpriv->dacsr &= ~DT2821_YSEL;
- if (devpriv->da1_2scomp)
- d ^= (1 << (board->dabits - 1));
- }
+ if (comedi_range_is_bipolar(s, range))
+ val = comedi_offset_munge(s, val);
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
- outw(d, dev->iobase + DT2821_DADAT);
+ outw(val, dev->iobase + DT2821_DADAT_REG);
- outw(devpriv->supcsr | DT2821_DACON, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_DACON,
+ dev->iobase + DT2821_SUPCSR_REG);
+ }
- return 1;
+ return insn->n;
}
static int dt282x_ao_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd)
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
+ struct dt282x_private *devpriv = dev->private;
int err = 0;
unsigned int arg;
@@ -865,7 +919,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev,
/* step 4: fix up any arguments */
arg = cmd->scan_begin_arg;
- dt282x_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
if (err)
@@ -892,7 +946,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
dev_err(dev->class_dev, "AO underrun\n");
return -EPIPE;
}
- prep_ao_dma(dev, 0, size);
+ dt282x_prep_ao_dma(dev, 0, size);
size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
devpriv->dma_maxsize);
@@ -900,9 +954,10 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
dev_err(dev->class_dev, "AO underrun\n");
return -EPIPE;
}
- prep_ao_dma(dev, 1, size);
+ dt282x_prep_ao_dma(dev, 1, size);
- outw(devpriv->supcsr | DT2821_STRIG, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
+ dev->iobase + DT2821_SUPCSR_REG);
s->async->inttrig = NULL;
return 1;
@@ -911,21 +966,18 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct dt282x_private *devpriv = dev->private;
- int timer;
struct comedi_cmd *cmd = &s->async->cmd;
- if (devpriv->usedma == 0) {
- comedi_error(dev,
- "driver requires 2 dma channels"
- " to execute command");
- return -EIO;
- }
-
dt282x_disable_dma(dev);
- devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
- outw(devpriv->supcsr | DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT,
- dev->iobase + DT2821_SUPCSR);
+ devpriv->supcsr = DT2821_SUPCSR_ERRINTEN |
+ DT2821_SUPCSR_DS_DA_CLK |
+ DT2821_SUPCSR_DDMA;
+ outw(devpriv->supcsr |
+ DT2821_SUPCSR_CLRDMADNE |
+ DT2821_SUPCSR_BUFFB |
+ DT2821_SUPCSR_DACINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
devpriv->nread = devpriv->ntrig;
@@ -933,11 +985,15 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->dma_dir = DMA_MODE_WRITE;
devpriv->current_dma_index = 0;
- timer = dt282x_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
- outw(timer, dev->iobase + DT2821_TMRCTR);
+ outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
+
+ /* clear all bits but the DIO direction bits */
+ devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
- devpriv->dacsr = DT2821_SSEL | DT2821_DACLK | DT2821_IDARDY;
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ devpriv->dacsr |= (DT2821_DACSR_SSEL |
+ DT2821_DACSR_DACLK |
+ DT2821_DACSR_IDARDY);
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
s->async->inttrig = dt282x_ao_inttrig;
@@ -951,11 +1007,14 @@ static int dt282x_ao_cancel(struct comedi_device *dev,
dt282x_disable_dma(dev);
- devpriv->dacsr = 0;
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ /* clear all bits but the DIO direction bits */
+ devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
+
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
devpriv->supcsr = 0;
- outw(devpriv->supcsr | DT2821_DACINIT, dev->iobase + DT2821_SUPCSR);
+ outw(devpriv->supcsr | DT2821_SUPCSR_DACINIT,
+ dev->iobase + DT2821_SUPCSR_REG);
return 0;
}
@@ -966,9 +1025,9 @@ static int dt282x_dio_insn_bits(struct comedi_device *dev,
unsigned int *data)
{
if (comedi_dio_update_state(s, data))
- outw(s->state, dev->iobase + DT2821_DIODAT);
+ outw(s->state, dev->iobase + DT2821_DIODAT_REG);
- data[1] = inw(dev->iobase + DT2821_DIODAT);
+ data[1] = inw(dev->iobase + DT2821_DIODAT_REG);
return insn->n;
}
@@ -992,13 +1051,13 @@ static int dt282x_dio_insn_config(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->dacsr &= ~(DT2821_LBOE | DT2821_HBOE);
+ devpriv->dacsr &= ~(DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
if (s->io_bits & 0x00ff)
- devpriv->dacsr |= DT2821_LBOE;
+ devpriv->dacsr |= DT2821_DACSR_LBOE;
if (s->io_bits & 0xff00)
- devpriv->dacsr |= DT2821_HBOE;
+ devpriv->dacsr |= DT2821_DACSR_HBOE;
- outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
return insn->n;
}
@@ -1021,55 +1080,18 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
if (x < 0 || x >= 2)
x = 0;
return ai_range_pgl_table[x];
- } else {
- if (x < 0 || x >= 4)
- x = 0;
- return ai_range_table[x];
}
-}
-static const struct comedi_lrange *const ao_range_table[] = {
- &range_bipolar10,
- &range_unipolar10,
- &range_bipolar5,
- &range_unipolar5,
- &range_bipolar2_5
-};
-
-static const struct comedi_lrange *opt_ao_range_lkup(int x)
-{
- if (x < 0 || x >= 5)
+ if (x < 0 || x >= 4)
x = 0;
- return ao_range_table[x];
+ return ai_range_table[x];
}
-enum { /* i/o base, irq, dma channels */
- opt_iobase = 0, opt_irq, opt_dma1, opt_dma2,
- opt_diff, /* differential */
- opt_ai_twos, opt_ao0_twos, opt_ao1_twos, /* twos comp */
- opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */
-};
-
static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
{
struct dt282x_private *devpriv = dev->private;
int ret;
- devpriv->usedma = 0;
-
- if (!dma1 && !dma2)
- return 0;
-
- if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7)
- return -EINVAL;
-
- if (dma2 < dma1) {
- int i;
- i = dma1;
- dma1 = dma2;
- dma2 = i;
- }
-
ret = request_dma(dma1, "dt282x A");
if (ret)
return -EBUSY;
@@ -1086,8 +1108,45 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
if (!devpriv->dma[0].buf || !devpriv->dma[1].buf)
return -ENOMEM;
- devpriv->usedma = 1;
+ return 0;
+}
+static void dt282x_free_dma(struct comedi_device *dev)
+{
+ struct dt282x_private *devpriv = dev->private;
+ int i;
+
+ if (!devpriv)
+ return;
+
+ for (i = 0; i < 2; i++) {
+ if (devpriv->dma[i].chan)
+ free_dma(devpriv->dma[i].chan);
+ if (devpriv->dma[i].buf)
+ free_page((unsigned long)devpriv->dma[i].buf);
+ devpriv->dma[i].chan = 0;
+ devpriv->dma[i].buf = NULL;
+ }
+}
+
+static int dt282x_initialize(struct comedi_device *dev)
+{
+ /* Initialize board */
+ outw(DT2821_SUPCSR_BDINIT, dev->iobase + DT2821_SUPCSR_REG);
+ inw(dev->iobase + DT2821_ADCSR_REG);
+
+ /*
+ * At power up, some registers are in a well-known state.
+ * Check them to see if a DT2821 series board is present.
+ */
+ if (((inw(dev->iobase + DT2821_ADCSR_REG) & 0xfff0) != 0x7c00) ||
+ ((inw(dev->iobase + DT2821_CHANCSR_REG) & 0xf0f0) != 0x70f0) ||
+ ((inw(dev->iobase + DT2821_DACSR_REG) & 0x7c93) != 0x7c90) ||
+ ((inw(dev->iobase + DT2821_SUPCSR_REG) & 0xf8ff) != 0x0000) ||
+ ((inw(dev->iobase + DT2821_TMRCTR_REG) & 0xff00) != 0xf000)) {
+ dev_err(dev->class_dev, "board not found\n");
+ return -EIO;
+ }
return 0;
}
@@ -1111,263 +1170,125 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct dt282x_private *devpriv;
struct comedi_subdevice *s;
int ret;
- int i;
- ret = comedi_request_region(dev, it->options[0], DT2821_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
- outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
- i = inw(dev->iobase + DT2821_ADCSR);
-
- if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
- != DT2821_ADCSR_VAL) ||
- ((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
- != DT2821_CHANCSR_VAL) ||
- ((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
- != DT2821_DACSR_VAL) ||
- ((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
- != DT2821_SUPCSR_VAL) ||
- ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
- != DT2821_TMRCTR_VAL)) {
- dev_err(dev->class_dev, "board not found\n");
- return -EIO;
- }
- /* should do board test */
-
- if (it->options[opt_irq] > 0) {
- ret = request_irq(it->options[opt_irq], dt282x_interrupt, 0,
- dev->board_name, dev);
- if (ret == 0)
- dev->irq = it->options[opt_irq];
- }
+ ret = dt282x_initialize(dev);
+ if (ret)
+ return ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
- if (dev->irq) {
- ret = dt282x_grab_dma(dev, it->options[opt_dma1],
- it->options[opt_dma2]);
- if (ret < 0)
- return ret;
+ /* an IRQ and 2 DMA channels are required for async command support */
+ if (it->options[1] && it->options[2] && it->options[3]) {
+ unsigned int irq = it->options[1];
+ unsigned int dma1 = it->options[2];
+ unsigned int dma2 = it->options[3];
+
+ if (dma2 < dma1) {
+ unsigned int swap;
+
+ swap = dma1;
+ dma1 = dma2;
+ dma2 = swap;
+ }
+
+ if (dma1 != dma2 &&
+ dma1 >= 5 && dma1 <= 7 &&
+ dma2 >= 5 && dma2 <= 7) {
+ ret = request_irq(irq, dt282x_interrupt, 0,
+ dev->board_name, dev);
+ if (ret == 0) {
+ dev->irq = irq;
+
+ ret = dt282x_grab_dma(dev, dma1, dma2);
+ if (ret < 0) {
+ dt282x_free_dma(dev);
+ free_irq(dev->irq, dev);
+ dev->irq = 0;
+ }
+ }
+ }
}
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
return ret;
+ /* Analog Input subdevice */
s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE;
+ if ((it->options[4] && board->adchan_di) || board->adchan_se == 0) {
+ s->subdev_flags |= SDF_DIFF;
+ s->n_chan = board->adchan_di;
+ } else {
+ s->subdev_flags |= SDF_COMMON;
+ s->n_chan = board->adchan_se;
+ }
+ s->maxdata = board->ai_maxdata;
+
+ s->range_table = opt_ai_range_lkup(board->ispgl, it->options[8]);
+ devpriv->ad_2scomp = it->options[5] ? 1 : 0;
- /* ai subdevice */
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE |
- ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
- s->n_chan =
- (it->options[opt_diff]) ? board->adchan_di : board->adchan_se;
- s->insn_read = dt282x_ai_insn_read;
- s->maxdata = (1 << board->adbits) - 1;
- s->range_table =
- opt_ai_range_lkup(board->ispgl, it->options[opt_ai_range]);
- devpriv->ad_2scomp = it->options[opt_ai_twos];
+ s->insn_read = dt282x_ai_insn_read;
if (dev->irq) {
dev->read_subdev = s;
- s->subdev_flags |= SDF_CMD_READ;
- s->len_chanlist = 16;
- s->do_cmdtest = dt282x_ai_cmdtest;
- s->do_cmd = dt282x_ai_cmd;
- s->cancel = dt282x_ai_cancel;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = dt282x_ai_cmdtest;
+ s->do_cmd = dt282x_ai_cmd;
+ s->cancel = dt282x_ai_cancel;
}
+ /* Analog Output subdevice */
s = &dev->subdevices[1];
+ if (board->dachan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = board->dachan;
+ s->maxdata = board->ao_maxdata;
- s->n_chan = board->dachan;
- if (s->n_chan) {
- /* ao subsystem */
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE;
- s->insn_read = dt282x_ao_insn_read;
- s->insn_write = dt282x_ao_insn_write;
- s->maxdata = (1 << board->dabits) - 1;
- s->range_table_list = devpriv->darangelist;
- devpriv->darangelist[0] =
- opt_ao_range_lkup(it->options[opt_ao0_range]);
- devpriv->darangelist[1] =
- opt_ao_range_lkup(it->options[opt_ao1_range]);
- devpriv->da0_2scomp = it->options[opt_ao0_twos];
- devpriv->da1_2scomp = it->options[opt_ao1_twos];
+ /* ranges are per-channel, set by jumpers on the board */
+ s->range_table = &dt282x_ao_range;
+
+ s->insn_read = dt282x_ao_insn_read;
+ s->insn_write = dt282x_ao_insn_write;
if (dev->irq) {
dev->write_subdev = s;
- s->subdev_flags |= SDF_CMD_WRITE;
- s->len_chanlist = 2;
- s->do_cmdtest = dt282x_ao_cmdtest;
- s->do_cmd = dt282x_ao_cmd;
- s->cancel = dt282x_ao_cancel;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = dt282x_ao_cmdtest;
+ s->do_cmd = dt282x_ao_cmd;
+ s->cancel = dt282x_ao_cancel;
}
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
+ /* Digital I/O subdevice */
s = &dev->subdevices[2];
- /* dio subsystem */
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 16;
- s->insn_bits = dt282x_dio_insn_bits;
- s->insn_config = dt282x_dio_insn_config;
- s->maxdata = 1;
- s->range_table = &range_digital;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dt282x_dio_insn_bits;
+ s->insn_config = dt282x_dio_insn_config;
return 0;
}
static void dt282x_detach(struct comedi_device *dev)
{
- struct dt282x_private *devpriv = dev->private;
-
- if (dev->private) {
- if (devpriv->dma[0].chan)
- free_dma(devpriv->dma[0].chan);
- if (devpriv->dma[1].chan)
- free_dma(devpriv->dma[1].chan);
- if (devpriv->dma[0].buf)
- free_page((unsigned long)devpriv->dma[0].buf);
- if (devpriv->dma[1].buf)
- free_page((unsigned long)devpriv->dma[1].buf);
- }
+ dt282x_free_dma(dev);
comedi_legacy_detach(dev);
}
-static const struct dt282x_board boardtypes[] = {
- {
- .name = "dt2821",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2821-f",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 6500,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2821-g",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 4000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2823",
- .adbits = 16,
- .adchan_se = 0,
- .adchan_di = 4,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 16,
- }, {
- .name = "dt2824-pgh",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 0,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt2824-pgl",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 1,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt2825",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 20000,
- .ispgl = 1,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2827",
- .adbits = 16,
- .adchan_se = 0,
- .adchan_di = 4,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2828",
- .adbits = 12,
- .adchan_se = 4,
- .adchan_di = 0,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt2829",
- .adbits = 16,
- .adchan_se = 8,
- .adchan_di = 0,
- .ai_speed = 33250,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 16,
- }, {
- .name = "dt21-ez",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 2,
- .dabits = 12,
- }, {
- .name = "dt23-ez",
- .adbits = 16,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt24-ez",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 0,
- .dachan = 0,
- .dabits = 0,
- }, {
- .name = "dt24-ez-pgl",
- .adbits = 12,
- .adchan_se = 16,
- .adchan_di = 8,
- .ai_speed = 10000,
- .ispgl = 1,
- .dachan = 0,
- .dabits = 0,
- },
-};
-
static struct comedi_driver dt282x_driver = {
.driver_name = "dt282x",
.module = THIS_MODULE,
@@ -1380,5 +1301,5 @@ static struct comedi_driver dt282x_driver = {
module_comedi_driver(dt282x_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Data Translation DT2821 series");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 4ab4de005924..56e21cc2dcfe 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -244,7 +244,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
#define DT3000_CHANNEL_MODE_DI 1
struct dt3k_private {
- void __iomem *io_addr;
unsigned int lock;
unsigned int ao_readback[2];
unsigned int ai_front;
@@ -255,14 +254,13 @@ struct dt3k_private {
static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
{
- struct dt3k_private *devpriv = dev->private;
int i;
unsigned int status = 0;
- writew(cmd, devpriv->io_addr + DPR_Command_Mbx);
+ writew(cmd, dev->mmio + DPR_Command_Mbx);
for (i = 0; i < TIMEOUT; i++) {
- status = readw(devpriv->io_addr + DPR_Command_Mbx);
+ status = readw(dev->mmio + DPR_Command_Mbx);
if ((status & DT3000_COMPLETION_MASK) != DT3000_NOTPROCESSED)
break;
udelay(1);
@@ -277,28 +275,24 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev,
unsigned int subsys, unsigned int chan,
unsigned int gain)
{
- struct dt3k_private *devpriv = dev->private;
-
- writew(subsys, devpriv->io_addr + DPR_SubSys);
+ writew(subsys, dev->mmio + DPR_SubSys);
- writew(chan, devpriv->io_addr + DPR_Params(0));
- writew(gain, devpriv->io_addr + DPR_Params(1));
+ writew(chan, dev->mmio + DPR_Params(0));
+ writew(gain, dev->mmio + DPR_Params(1));
dt3k_send_cmd(dev, CMD_READSINGLE);
- return readw(devpriv->io_addr + DPR_Params(2));
+ return readw(dev->mmio + DPR_Params(2));
}
static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
unsigned int chan, unsigned int data)
{
- struct dt3k_private *devpriv = dev->private;
-
- writew(subsys, devpriv->io_addr + DPR_SubSys);
+ writew(subsys, dev->mmio + DPR_SubSys);
- writew(chan, devpriv->io_addr + DPR_Params(0));
- writew(0, devpriv->io_addr + DPR_Params(1));
- writew(data, devpriv->io_addr + DPR_Params(2));
+ writew(chan, dev->mmio + DPR_Params(0));
+ writew(0, dev->mmio + DPR_Params(1));
+ writew(data, dev->mmio + DPR_Params(2));
dt3k_send_cmd(dev, CMD_WRITESINGLE);
}
@@ -313,7 +307,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
int i;
unsigned short data;
- front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
+ front = readw(dev->mmio + DPR_AD_Buf_Front);
count = front - devpriv->ai_front;
if (count < 0)
count += AI_FIFO_DEPTH;
@@ -321,7 +315,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
rear = devpriv->ai_rear;
for (i = 0; i < count; i++) {
- data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
+ data = readw(dev->mmio + DPR_ADC_buffer + rear);
comedi_buf_put(s, data);
rear++;
if (rear >= AI_FIFO_DEPTH)
@@ -329,17 +323,16 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
}
devpriv->ai_rear = rear;
- writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+ writew(rear, dev->mmio + DPR_AD_Buf_Rear);
}
-static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int dt3k_ai_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
- struct dt3k_private *devpriv = dev->private;
-
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_AI, dev->mmio + DPR_SubSys);
dt3k_send_cmd(dev, CMD_STOP);
- writew(0, devpriv->io_addr + DPR_Int_Mask);
+ writew(0, dev->mmio + DPR_Int_Mask);
return 0;
}
@@ -351,14 +344,13 @@ static int debug_n_ints;
static irqreturn_t dt3k_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct dt3k_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
if (!dev->attached)
return IRQ_NONE;
- status = readw(devpriv->io_addr + DPR_Intr_Flag);
+ status = readw(dev->mmio + DPR_Intr_Flag);
if (status & DT3000_ADFULL) {
dt3k_ai_empty_fifo(dev, s);
@@ -377,7 +369,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d)
}
static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
- unsigned int round_mode)
+ unsigned int flags)
{
int divider, base, prescale;
@@ -386,7 +378,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
for (prescale = 0; prescale < 16; prescale++) {
base = timer_base * (prescale + 1);
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (*nanosec + base / 2) / base;
@@ -467,13 +459,13 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- dt3k_ns_to_timer(100, &arg, cmd->flags & TRIG_ROUND_MASK);
+ dt3k_ns_to_timer(100, &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- dt3k_ns_to_timer(50, &arg, cmd->flags & TRIG_ROUND_MASK);
+ dt3k_ns_to_timer(50, &arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -491,7 +483,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev,
static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct dt3k_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int i;
unsigned int chan, range, aref;
@@ -503,42 +494,40 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
chan = CR_CHAN(cmd->chanlist[i]);
range = CR_RANGE(cmd->chanlist[i]);
- writew((range << 6) | chan,
- devpriv->io_addr + DPR_ADC_buffer + i);
+ writew((range << 6) | chan, dev->mmio + DPR_ADC_buffer + i);
}
aref = CR_AREF(cmd->chanlist[0]);
- writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
+ writew(cmd->scan_end_arg, dev->mmio + DPR_Params(0));
if (cmd->convert_src == TRIG_TIMER) {
- divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
- writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
- writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
+ divider = dt3k_ns_to_timer(50, &cmd->convert_arg, cmd->flags);
+ writew((divider >> 16), dev->mmio + DPR_Params(1));
+ writew((divider & 0xffff), dev->mmio + DPR_Params(2));
}
if (cmd->scan_begin_src == TRIG_TIMER) {
tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
- writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
- writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
+ cmd->flags);
+ writew((tscandiv >> 16), dev->mmio + DPR_Params(3));
+ writew((tscandiv & 0xffff), dev->mmio + DPR_Params(4));
}
mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
- writew(mode, devpriv->io_addr + DPR_Params(5));
- writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
+ writew(mode, dev->mmio + DPR_Params(5));
+ writew(aref == AREF_DIFF, dev->mmio + DPR_Params(6));
- writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
+ writew(AI_FIFO_DEPTH / 2, dev->mmio + DPR_Params(7));
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_AI, dev->mmio + DPR_SubSys);
dt3k_send_cmd(dev, CMD_CONFIG);
writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
- devpriv->io_addr + DPR_Int_Mask);
+ dev->mmio + DPR_Int_Mask);
debug_n_ints = 0;
- writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_AI, dev->mmio + DPR_SubSys);
dt3k_send_cmd(dev, CMD_START);
return 0;
@@ -594,16 +583,14 @@ static int dt3k_ao_insn_read(struct comedi_device *dev,
static void dt3k_dio_config(struct comedi_device *dev, int bits)
{
- struct dt3k_private *devpriv = dev->private;
-
/* XXX */
- writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys);
+ writew(SUBS_DOUT, dev->mmio + DPR_SubSys);
- writew(bits, devpriv->io_addr + DPR_Params(0));
+ writew(bits, dev->mmio + DPR_Params(0));
#if 0
/* don't know */
- writew(0, devpriv->io_addr + DPR_Params(1));
- writew(0, devpriv->io_addr + DPR_Params(2));
+ writew(0, dev->mmio + DPR_Params(1));
+ writew(0, dev->mmio + DPR_Params(2));
#endif
dt3k_send_cmd(dev, CMD_CONFIG);
@@ -647,20 +634,20 @@ static int dt3k_dio_insn_bits(struct comedi_device *dev,
static int dt3k_mem_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 dt3k_private *devpriv = dev->private;
unsigned int addr = CR_CHAN(insn->chanspec);
int i;
for (i = 0; i < insn->n; i++) {
- writew(SUBS_MEM, devpriv->io_addr + DPR_SubSys);
- writew(addr, devpriv->io_addr + DPR_Params(0));
- writew(1, devpriv->io_addr + DPR_Params(1));
+ writew(SUBS_MEM, dev->mmio + DPR_SubSys);
+ writew(addr, dev->mmio + DPR_Params(0));
+ writew(1, dev->mmio + DPR_Params(1));
dt3k_send_cmd(dev, CMD_READCODE);
- data[i] = readw(devpriv->io_addr + DPR_Params(2));
+ data[i] = readw(dev->mmio + DPR_Params(2));
}
return i;
@@ -690,8 +677,8 @@ static int dt3000_auto_attach(struct comedi_device *dev,
if (ret < 0)
return ret;
- devpriv->io_addr = pci_ioremap_bar(pcidev, 0);
- if (!devpriv->io_addr)
+ dev->mmio = pci_ioremap_bar(pcidev, 0);
+ if (!dev->mmio)
return -ENOMEM;
if (pcidev->irq) {
@@ -765,14 +752,10 @@ static int dt3000_auto_attach(struct comedi_device *dev,
static void dt3000_detach(struct comedi_device *dev)
{
- struct dt3k_private *devpriv = dev->private;
-
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->io_addr)
- iounmap(devpriv->io_addr);
- }
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index b3aeb6fb2ad0..bd2ca2b371e6 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -653,6 +653,7 @@ static int dt9812_find_endpoints(struct comedi_device *dev)
for (i = 0; i < host->desc.bNumEndpoints; ++i) {
int dir = -1;
+
ep = &host->endpoint[i].desc;
switch (i) {
case 0:
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 22333c1ad88c..91c1e8cf5d24 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -51,7 +51,7 @@
#include "comedi_fc.h"
/*
- * PCI BAR2 Register map (devpriv->mmio)
+ * PCI BAR2 Register map (dev->mmio)
*/
#define FIRMWARE_REV_REG 0x00
#define FEATURES_REG_PRESENT_BIT (1 << 15)
@@ -148,7 +148,6 @@ static const struct hpdi_board hpdi_boards[] = {
struct hpdi_private {
void __iomem *plx9080_mmio;
- void __iomem *mmio;
uint32_t *dio_buffer[NUM_DMA_BUFFERS]; /* dma buffers */
/* physical addresses of dma buffers */
dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
@@ -227,11 +226,11 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0)
return IRQ_NONE;
- hpdi_intr_status = readl(devpriv->mmio + INTERRUPT_STATUS_REG);
- hpdi_board_status = readl(devpriv->mmio + BOARD_STATUS_REG);
+ hpdi_intr_status = readl(dev->mmio + INTERRUPT_STATUS_REG);
+ hpdi_board_status = readl(dev->mmio + BOARD_STATUS_REG);
if (hpdi_intr_status)
- writel(hpdi_intr_status, devpriv->mmio + INTERRUPT_STATUS_REG);
+ writel(hpdi_intr_status, dev->mmio + INTERRUPT_STATUS_REG);
/* spin lock makes sure no one else changes plx dma control reg */
spin_lock_irqsave(&dev->spinlock, flags);
@@ -294,10 +293,8 @@ static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel)
static int gsc_hpdi_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct hpdi_private *devpriv = dev->private;
-
- writel(0, devpriv->mmio + BOARD_CONTROL_REG);
- writel(0, devpriv->mmio + INTERRUPT_CONTROL_REG);
+ writel(0, dev->mmio + BOARD_CONTROL_REG);
+ writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
gsc_hpdi_abort_dma(dev, 0);
@@ -316,7 +313,7 @@ static int gsc_hpdi_cmd(struct comedi_device *dev,
if (s->io_bits)
return -EINVAL;
- writel(RX_FIFO_RESET_BIT, devpriv->mmio + BOARD_CONTROL_REG);
+ writel(RX_FIFO_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
gsc_hpdi_abort_dma(dev, 0);
@@ -349,13 +346,12 @@ static int gsc_hpdi_cmd(struct comedi_device *dev,
devpriv->dio_count = 1;
/* clear over/under run status flags */
- writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
- devpriv->mmio + BOARD_STATUS_REG);
+ writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, dev->mmio + BOARD_STATUS_REG);
/* enable interrupts */
- writel(RX_FULL_INTR, devpriv->mmio + INTERRUPT_CONTROL_REG);
+ writel(RX_FULL_INTR, dev->mmio + INTERRUPT_CONTROL_REG);
- writel(RX_ENABLE_BIT, devpriv->mmio + BOARD_CONTROL_REG);
+ writel(RX_ENABLE_BIT, dev->mmio + BOARD_CONTROL_REG);
return 0;
}
@@ -517,20 +513,20 @@ static int gsc_hpdi_init(struct comedi_device *dev)
uint32_t plx_intcsr_bits;
/* wait 10usec after reset before accessing fifos */
- writel(BOARD_RESET_BIT, devpriv->mmio + BOARD_CONTROL_REG);
+ writel(BOARD_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
udelay(10);
writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
- devpriv->mmio + RX_PROG_ALMOST_REG);
+ dev->mmio + RX_PROG_ALMOST_REG);
writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
- devpriv->mmio + TX_PROG_ALMOST_REG);
+ dev->mmio + TX_PROG_ALMOST_REG);
- devpriv->tx_fifo_size = readl(devpriv->mmio + TX_FIFO_SIZE_REG) &
+ devpriv->tx_fifo_size = readl(dev->mmio + TX_FIFO_SIZE_REG) &
FIFO_SIZE_MASK;
- devpriv->rx_fifo_size = readl(devpriv->mmio + RX_FIFO_SIZE_REG) &
+ devpriv->rx_fifo_size = readl(dev->mmio + RX_FIFO_SIZE_REG) &
FIFO_SIZE_MASK;
- writel(0, devpriv->mmio + INTERRUPT_CONTROL_REG);
+ writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
/* enable interrupts */
plx_intcsr_bits =
@@ -621,8 +617,8 @@ static int gsc_hpdi_auto_attach(struct comedi_device *dev,
pci_set_master(pcidev);
devpriv->plx9080_mmio = pci_ioremap_bar(pcidev, 0);
- devpriv->mmio = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->plx9080_mmio || !devpriv->mmio) {
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!devpriv->plx9080_mmio || !dev->mmio) {
dev_warn(dev->class_dev, "failed to remap io memory\n");
return -ENOMEM;
}
@@ -696,8 +692,8 @@ static void gsc_hpdi_detach(struct comedi_device *dev)
writel(0, devpriv->plx9080_mmio + PLX_INTRCS_REG);
iounmap(devpriv->plx9080_mmio);
}
- if (devpriv->mmio)
- iounmap(devpriv->mmio);
+ if (dev->mmio)
+ iounmap(dev->mmio);
/* free pci dma buffers */
for (i = 0; i < NUM_DMA_BUFFERS; i++) {
if (devpriv->dio_buffer[i])
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 0b8b2162b76b..a98cef2106a9 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -49,8 +49,6 @@ Configuration options: not applicable, uses PCI auto config
#include "../comedidev.h"
-#define PCI_DEVICE_ID_ICP_MULTI 0x8000
-
#define ICP_MULTI_ADC_CSR 0 /* R/W: ADC command/status register */
#define ICP_MULTI_AI 2 /* R: Analogue input data */
#define ICP_MULTI_DAC_CSR 4 /* R/W: DAC command/status register */
@@ -110,7 +108,6 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
struct icp_multi_private {
char valid; /* card is usable */
- void __iomem *io_addr; /* Pointer to mapped io address */
unsigned int AdcCmdStatus; /* ADC Command/Status register */
unsigned int DacCmdStatus; /* DAC Command/Status register */
unsigned int IntEnable; /* Interrupt Enable register */
@@ -166,8 +163,7 @@ static void setup_channel_list(struct comedi_device *dev,
devpriv->AdcCmdStatus |= range;
/* Output channel, range, mode to ICP Multi */
- writew(devpriv->AdcCmdStatus,
- devpriv->io_addr + ICP_MULTI_ADC_CSR);
+ writew(devpriv->AdcCmdStatus, dev->mmio + ICP_MULTI_ADC_CSR);
}
}
@@ -176,10 +172,9 @@ static int icp_multi_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct icp_multi_private *devpriv = dev->private;
unsigned int status;
- status = readw(devpriv->io_addr + ICP_MULTI_ADC_CSR);
+ status = readw(dev->mmio + ICP_MULTI_ADC_CSR);
if ((status & ADC_BSY) == 0)
return 0;
return -EBUSY;
@@ -187,7 +182,8 @@ static int icp_multi_ai_eoc(struct comedi_device *dev,
static int icp_multi_insn_read_ai(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct icp_multi_private *devpriv = dev->private;
int ret = 0;
@@ -195,11 +191,11 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev,
/* Disable A/D conversion ready interrupt */
devpriv->IntEnable &= ~ADC_READY;
- writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
+ writew(devpriv->IntEnable, dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
- writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(devpriv->IntStatus, dev->mmio + ICP_MULTI_INT_STAT);
/* Set up appropriate channel, mode and range data, for specified ch */
setup_channel_list(dev, s, &insn->chanspec, 1);
@@ -207,8 +203,7 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev,
for (n = 0; n < insn->n; n++) {
/* Set start ADC bit */
devpriv->AdcCmdStatus |= ADC_ST;
- writew(devpriv->AdcCmdStatus,
- devpriv->io_addr + ICP_MULTI_ADC_CSR);
+ writew(devpriv->AdcCmdStatus, dev->mmio + ICP_MULTI_ADC_CSR);
devpriv->AdcCmdStatus &= ~ADC_ST;
udelay(1);
@@ -218,17 +213,16 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev,
if (ret)
break;
- data[n] =
- (readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
+ data[n] = (readw(dev->mmio + ICP_MULTI_AI) >> 4) & 0x0fff;
}
/* Disable interrupt */
devpriv->IntEnable &= ~ADC_READY;
- writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
+ writew(devpriv->IntEnable, dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
- writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(devpriv->IntStatus, dev->mmio + ICP_MULTI_INT_STAT);
return ret ? ret : n;
}
@@ -238,10 +232,9 @@ static int icp_multi_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct icp_multi_private *devpriv = dev->private;
unsigned int status;
- status = readw(devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ status = readw(dev->mmio + ICP_MULTI_DAC_CSR);
if ((status & DAC_BSY) == 0)
return 0;
return -EBUSY;
@@ -249,7 +242,8 @@ static int icp_multi_ao_eoc(struct comedi_device *dev,
static int icp_multi_insn_write_ao(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct icp_multi_private *devpriv = dev->private;
int n, chan, range;
@@ -257,11 +251,11 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
/* Disable D/A conversion ready interrupt */
devpriv->IntEnable &= ~DAC_READY;
- writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
+ writew(devpriv->IntEnable, dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
- writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(devpriv->IntStatus, dev->mmio + ICP_MULTI_INT_STAT);
/* Get channel number and range */
chan = CR_CHAN(insn->chanspec);
@@ -276,7 +270,7 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
devpriv->DacCmdStatus |= range_codes_analog[range];
devpriv->DacCmdStatus |= (chan << 8);
- writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ writew(devpriv->DacCmdStatus, dev->mmio + ICP_MULTI_DAC_CSR);
for (n = 0; n < insn->n; n++) {
/* Wait for analogue output data register to be
@@ -286,12 +280,12 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
/* Disable interrupt */
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable,
- devpriv->io_addr + ICP_MULTI_INT_EN);
+ dev->mmio + ICP_MULTI_INT_EN);
/* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus,
- devpriv->io_addr + ICP_MULTI_INT_STAT);
+ dev->mmio + ICP_MULTI_INT_STAT);
/* Clear data received */
devpriv->ao_data[chan] = 0;
@@ -300,12 +294,11 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev,
}
/* Write data to analogue output data register */
- writew(data[n], devpriv->io_addr + ICP_MULTI_AO);
+ writew(data[n], dev->mmio + ICP_MULTI_AO);
/* Set DAC_ST bit to write the data to selected channel */
devpriv->DacCmdStatus |= DAC_ST;
- writew(devpriv->DacCmdStatus,
- devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ writew(devpriv->DacCmdStatus, dev->mmio + ICP_MULTI_DAC_CSR);
devpriv->DacCmdStatus &= ~DAC_ST;
/* Save analogue output data */
@@ -334,11 +327,10 @@ static int icp_multi_insn_read_ao(struct comedi_device *dev,
static int icp_multi_insn_bits_di(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct icp_multi_private *devpriv = dev->private;
-
- data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
+ data[1] = readw(dev->mmio + ICP_MULTI_DI);
return insn->n;
}
@@ -348,12 +340,10 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct icp_multi_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writew(s->state, devpriv->io_addr + ICP_MULTI_DO);
+ writew(s->state, dev->mmio + ICP_MULTI_DO);
- data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
+ data[1] = readw(dev->mmio + ICP_MULTI_DI);
return insn->n;
}
@@ -376,11 +366,10 @@ static int icp_multi_insn_write_ctr(struct comedi_device *dev,
static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
{
struct comedi_device *dev = d;
- struct icp_multi_private *devpriv = dev->private;
int int_no;
/* Is this interrupt from our board? */
- int_no = readw(devpriv->io_addr + ICP_MULTI_INT_STAT) & Status_IRQ;
+ int_no = readw(dev->mmio + ICP_MULTI_INT_STAT) & Status_IRQ;
if (!int_no)
/* No, exit */
return IRQ_NONE;
@@ -420,7 +409,7 @@ static int check_channel_list(struct comedi_device *dev,
/* Check that we at least have one channel to check */
if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
return 0;
}
/* Check all channels */
@@ -428,14 +417,14 @@ static int check_channel_list(struct comedi_device *dev,
/* Check that channel number is < maximum */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
if (CR_CHAN(chanlist[i]) > (s->nchan / 2)) {
- comedi_error(dev,
- "Incorrect differential ai ch-nr");
+ dev_err(dev->class_dev,
+ "Incorrect differential ai ch-nr\n");
return 0;
}
} else {
if (CR_CHAN(chanlist[i]) > s->n_chan) {
- comedi_error(dev,
- "Incorrect ai channel number");
+ dev_err(dev->class_dev,
+ "Incorrect ai channel number\n");
return 0;
}
}
@@ -450,8 +439,8 @@ static int icp_multi_reset(struct comedi_device *dev)
unsigned int i;
/* Clear INT enables and requests */
- writew(0, devpriv->io_addr + ICP_MULTI_INT_EN);
- writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT);
+ writew(0, dev->mmio + ICP_MULTI_INT_EN);
+ writew(0x00ff, dev->mmio + ICP_MULTI_INT_STAT);
/* Set DACs to 0..5V range and 0V output */
for (i = 0; i < 4; i++) {
@@ -461,21 +450,20 @@ static int icp_multi_reset(struct comedi_device *dev)
devpriv->DacCmdStatus |= (i << 8);
/* Output 0V */
- writew(0, devpriv->io_addr + ICP_MULTI_AO);
+ writew(0, dev->mmio + ICP_MULTI_AO);
/* Set start conversion bit */
devpriv->DacCmdStatus |= DAC_ST;
/* Output to command / status register */
- writew(devpriv->DacCmdStatus,
- devpriv->io_addr + ICP_MULTI_DAC_CSR);
+ writew(devpriv->DacCmdStatus, dev->mmio + ICP_MULTI_DAC_CSR);
/* Delay to allow DAC time to recover */
udelay(1);
}
/* Digital outputs to 0 */
- writew(0, devpriv->io_addr + ICP_MULTI_DO);
+ writew(0, dev->mmio + ICP_MULTI_DO);
return 0;
}
@@ -496,8 +484,8 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->io_addr = pci_ioremap_bar(pcidev, 2);
- if (!devpriv->io_addr)
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!dev->mmio)
return -ENOMEM;
ret = comedi_alloc_subdevices(dev, 5);
@@ -575,8 +563,8 @@ static void icp_multi_detach(struct comedi_device *dev)
icp_multi_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv && devpriv->io_addr)
- iounmap(devpriv->io_addr);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
@@ -594,7 +582,7 @@ static int icp_multi_pci_probe(struct pci_dev *dev,
}
static const struct pci_device_id icp_multi_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ICP, PCI_DEVICE_ID_ICP_MULTI) },
+ { PCI_DEVICE(PCI_VENDOR_ID_ICP, 0x8000) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, icp_multi_pci_table);
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 2516ce834839..687db433e131 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -33,6 +33,7 @@
/*
* Register I/O map
*/
+#define II20K_SIZE 0x400
#define II20K_MOD_OFFSET 0x100
#define II20K_ID_REG 0x00
#define II20K_ID_MOD1_EMPTY (1 << 7)
@@ -135,16 +136,10 @@ struct ii20k_ao_private {
unsigned int last_data[2];
};
-struct ii20k_private {
- void __iomem *ioaddr;
-};
-
static void __iomem *ii20k_module_iobase(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ii20k_private *devpriv = dev->private;
-
- return devpriv->ioaddr + (s->index + 1) * II20K_MOD_OFFSET;
+ return dev->mmio + (s->index + 1) * II20K_MOD_OFFSET;
}
static int ii20k_ao_insn_read(struct comedi_device *dev,
@@ -281,7 +276,6 @@ static int ii20k_ai_insn_read(struct comedi_device *dev,
static void ii20k_dio_config(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ii20k_private *devpriv = dev->private;
unsigned char ctrl01 = 0;
unsigned char ctrl23 = 0;
unsigned char dir_ena = 0;
@@ -338,9 +332,9 @@ static void ii20k_dio_config(struct comedi_device *dev,
ctrl23 |= II20K_CTRL23_SET;
/* order is important */
- writeb(ctrl01, devpriv->ioaddr + II20K_CTRL01_REG);
- writeb(ctrl23, devpriv->ioaddr + II20K_CTRL23_REG);
- writeb(dir_ena, devpriv->ioaddr + II20K_DIR_ENA_REG);
+ writeb(ctrl01, dev->mmio + II20K_CTRL01_REG);
+ writeb(ctrl23, dev->mmio + II20K_CTRL23_REG);
+ writeb(dir_ena, dev->mmio + II20K_DIR_ENA_REG);
}
static int ii20k_dio_insn_config(struct comedi_device *dev,
@@ -375,29 +369,28 @@ static int ii20k_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ii20k_private *devpriv = dev->private;
unsigned int mask;
mask = comedi_dio_update_state(s, data);
if (mask) {
if (mask & 0x000000ff)
writeb((s->state >> 0) & 0xff,
- devpriv->ioaddr + II20K_DIO0_REG);
+ dev->mmio + II20K_DIO0_REG);
if (mask & 0x0000ff00)
writeb((s->state >> 8) & 0xff,
- devpriv->ioaddr + II20K_DIO1_REG);
+ dev->mmio + II20K_DIO1_REG);
if (mask & 0x00ff0000)
writeb((s->state >> 16) & 0xff,
- devpriv->ioaddr + II20K_DIO2_REG);
+ dev->mmio + II20K_DIO2_REG);
if (mask & 0xff000000)
writeb((s->state >> 24) & 0xff,
- devpriv->ioaddr + II20K_DIO3_REG);
+ dev->mmio + II20K_DIO3_REG);
}
- data[1] = readb(devpriv->ioaddr + II20K_DIO0_REG);
- data[1] |= readb(devpriv->ioaddr + II20K_DIO1_REG) << 8;
- data[1] |= readb(devpriv->ioaddr + II20K_DIO2_REG) << 16;
- data[1] |= readb(devpriv->ioaddr + II20K_DIO3_REG) << 24;
+ data[1] = readb(dev->mmio + II20K_DIO0_REG);
+ data[1] |= readb(dev->mmio + II20K_DIO1_REG) << 8;
+ data[1] |= readb(dev->mmio + II20K_DIO2_REG) << 16;
+ data[1] |= readb(dev->mmio + II20K_DIO3_REG) << 24;
return insn->n;
}
@@ -446,19 +439,32 @@ static int ii20k_init_module(struct comedi_device *dev,
static int ii20k_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
- struct ii20k_private *devpriv;
struct comedi_subdevice *s;
+ unsigned int membase;
unsigned char id;
bool has_dio;
int ret;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
+ membase = it->options[0];
+ if (!membase || (membase & ~(0x100000 - II20K_SIZE))) {
+ dev_warn(dev->class_dev,
+ "%s: invalid memory address specified\n",
+ dev->board_name);
+ return -EINVAL;
+ }
- devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0];
+ if (!request_mem_region(membase, II20K_SIZE, dev->board_name)) {
+ dev_warn(dev->class_dev, "%s: I/O mem conflict (%#x,%u)\n",
+ dev->board_name, membase, II20K_SIZE);
+ return -EIO;
+ }
+ dev->iobase = membase; /* actually, a memory address */
- id = readb(devpriv->ioaddr + II20K_ID_REG);
+ dev->mmio = ioremap(membase, II20K_SIZE);
+ if (!dev->mmio)
+ return -ENOMEM;
+
+ id = readb(dev->mmio + II20K_ID_REG);
switch (id & II20K_ID_MASK) {
case II20K_ID_PCI20001C_1A:
has_dio = false;
@@ -521,11 +527,19 @@ static int ii20k_attach(struct comedi_device *dev,
return 0;
}
+static void ii20k_detach(struct comedi_device *dev)
+{
+ if (dev->mmio)
+ iounmap(dev->mmio);
+ if (dev->iobase) /* actually, a memory address */
+ release_mem_region(dev->iobase, II20K_SIZE);
+}
+
static struct comedi_driver ii20k_driver = {
.driver_name = "ii_pci20kc",
.module = THIS_MODULE,
.attach = ii20k_attach,
- .detach = comedi_legacy_detach,
+ .detach = ii20k_detach,
};
module_comedi_driver(ii20k_driver);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index a8db9d86aadc..7b20e19ecbf7 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -196,6 +196,7 @@ static struct six_axis_t get_min_full_scales(struct jr3_channel __iomem
*channel)
{
struct six_axis_t result;
+
result.fx = get_s16(&channel->min_full_scale.fx);
result.fy = get_s16(&channel->min_full_scale.fy);
result.fz = get_s16(&channel->min_full_scale.fz);
@@ -209,6 +210,7 @@ static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem
*channel)
{
struct six_axis_t result;
+
result.fx = get_s16(&channel->max_full_scale.fx);
result.fy = get_s16(&channel->max_full_scale.fy);
result.fz = get_s16(&channel->max_full_scale.fz);
@@ -319,6 +321,8 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
unsigned int *val)
{
int result = 0;
+ int value;
+
if (pos && val) {
/* Skip over non hex */
for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
@@ -326,7 +330,6 @@ static int read_idm_word(const u8 *data, size_t size, int *pos,
/* Collect value */
*val = 0;
for (; *pos < size; (*pos)++) {
- int value;
value = hex_to_bin(data[*pos]);
if (value >= 0) {
result = 1;
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index ec43c38958de..f46722c2648f 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -93,6 +93,67 @@ static int ke_counter_insn_read(struct comedi_device *dev,
return insn->n;
}
+static void ke_counter_reset(struct comedi_device *dev)
+{
+ unsigned int chan;
+
+ for (chan = 0; chan < 3; chan++)
+ outb(0, dev->iobase + KE_RESET_REG(chan));
+}
+
+static int ke_counter_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned char src;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ switch (data[1]) {
+ case KE_CLK_20MHZ: /* default */
+ src = KE_OSC_SEL_20MHZ;
+ break;
+ case KE_CLK_4MHZ: /* option */
+ src = KE_OSC_SEL_4MHZ;
+ break;
+ case KE_CLK_EXT: /* Pin 21 on D-sub */
+ src = KE_OSC_SEL_EXT;
+ break;
+ default:
+ return -EINVAL;
+ }
+ outb(src, dev->iobase + KE_OSC_SEL_REG);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ src = inb(dev->iobase + KE_OSC_SEL_REG);
+ switch (src) {
+ case KE_OSC_SEL_20MHZ:
+ data[1] = KE_CLK_20MHZ;
+ data[2] = 50; /* 50ns */
+ break;
+ case KE_OSC_SEL_4MHZ:
+ data[1] = KE_CLK_4MHZ;
+ data[2] = 250; /* 250ns */
+ break;
+ case KE_OSC_SEL_EXT:
+ data[1] = KE_CLK_EXT;
+ data[2] = 0; /* Unknown */
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case INSN_CONFIG_RESET:
+ ke_counter_reset(dev);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return insn->n;
+}
+
static int ke_counter_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -130,6 +191,7 @@ static int ke_counter_auto_attach(struct comedi_device *dev,
s->range_table = &range_unknown;
s->insn_read = ke_counter_insn_read;
s->insn_write = ke_counter_insn_write;
+ s->insn_config = ke_counter_insn_config;
s = &dev->subdevices[1];
s->type = COMEDI_SUBD_DO;
@@ -141,9 +203,7 @@ static int ke_counter_auto_attach(struct comedi_device *dev,
outb(KE_OSC_SEL_20MHZ, dev->iobase + KE_OSC_SEL_REG);
- outb(0, dev->iobase + KE_RESET_REG(0));
- outb(0, dev->iobase + KE_RESET_REG(1));
- outb(0, dev->iobase + KE_RESET_REG(2));
+ ke_counter_reset(dev);
return 0;
}
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 25ce2f78db81..9a5c535451a1 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -170,7 +170,6 @@ broken.
#define ME4000_AI_MIN_TICKS 66
#define ME4000_AI_MIN_SAMPLE_TIME 2000
-#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
#define ME4000_AI_CHANNEL_LIST_COUNT 1024
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 0ff126b1fdfd..37a6fa92c656 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -167,7 +167,6 @@ static const struct me_board me_boards[] = {
struct me_private_data {
void __iomem *plx_regbase; /* PLX configuration base address */
- void __iomem *me_regbase; /* Base address of the Meilhaus card */
unsigned short control_1; /* Mirror of CONTROL_1 register */
unsigned short control_2; /* Mirror of CONTROL_2 register */
@@ -209,7 +208,7 @@ static int me_dio_insn_config(struct comedi_device *dev,
else
devpriv->control_2 &= ~ENABLE_PORT_B;
- writew(devpriv->control_2, devpriv->me_regbase + ME_CONTROL_2);
+ writew(devpriv->control_2, dev->mmio + ME_CONTROL_2);
return insn->n;
}
@@ -219,9 +218,8 @@ static int me_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct me_private_data *dev_private = dev->private;
- void __iomem *mmio_porta = dev_private->me_regbase + ME_DIO_PORT_A;
- void __iomem *mmio_portb = dev_private->me_regbase + ME_DIO_PORT_B;
+ void __iomem *mmio_porta = dev->mmio + ME_DIO_PORT_A;
+ void __iomem *mmio_portb = dev->mmio + ME_DIO_PORT_B;
unsigned int mask;
unsigned int val;
@@ -253,10 +251,9 @@ static int me_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct me_private_data *dev_private = dev->private;
unsigned int status;
- status = readw(dev_private->me_regbase + ME_STATUS);
+ status = readw(dev->mmio + ME_STATUS);
if ((status & 0x0004) == 0)
return 0;
return -EBUSY;
@@ -276,32 +273,32 @@ static int me_ai_insn_read(struct comedi_device *dev,
/* stop any running conversion */
dev_private->control_1 &= 0xFFFC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
+ writew(dev_private->control_1, dev->mmio + ME_CONTROL_1);
/* clear chanlist and ad fifo */
dev_private->control_2 &= ~(ENABLE_ADFIFO | ENABLE_CHANLIST);
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* reset any pending interrupt */
- writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);
+ writew(0x00, dev->mmio + ME_RESET_INTERRUPT);
/* enable the chanlist and ADC fifo */
dev_private->control_2 |= (ENABLE_ADFIFO | ENABLE_CHANLIST);
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* write to channel list fifo */
val = chan & 0x0f; /* b3:b0 channel */
val |= (rang & 0x03) << 4; /* b5:b4 gain */
val |= (rang & 0x04) << 4; /* b6 polarity */
val |= ((aref & AREF_DIFF) ? 0x80 : 0); /* b7 differential */
- writew(val & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST);
+ writew(val & 0xff, dev->mmio + ME_CHANNEL_LIST);
/* set ADC mode to software trigger */
dev_private->control_1 |= SOFTWARE_TRIGGERED_ADC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
+ writew(dev_private->control_1, dev->mmio + ME_CONTROL_1);
/* start conversion by reading from ADC_START */
- readw(dev_private->me_regbase + ME_ADC_START);
+ readw(dev->mmio + ME_ADC_START);
/* wait for ADC fifo not empty flag */
ret = comedi_timeout(dev, s, insn, me_ai_eoc, 0);
@@ -309,13 +306,13 @@ static int me_ai_insn_read(struct comedi_device *dev,
return ret;
/* get value from ADC fifo */
- val = readw(dev_private->me_regbase + ME_READ_AD_FIFO);
+ val = readw(dev->mmio + ME_READ_AD_FIFO);
val = (val ^ 0x800) & 0x0fff;
data[0] = val;
/* stop any running conversion */
dev_private->control_1 &= 0xFFFC;
- writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1);
+ writew(dev_private->control_1, dev->mmio + ME_CONTROL_1);
return 1;
}
@@ -332,11 +329,11 @@ static int me_ao_insn_write(struct comedi_device *dev,
/* Enable all DAC */
dev_private->control_2 |= ENABLE_DAC;
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* and set DAC to "buffered" mode */
dev_private->control_2 |= BUFFERED_DAC;
- writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+ writew(dev_private->control_2, dev->mmio + ME_CONTROL_2);
/* Set dac-control register */
for (i = 0; i < insn->n; i++) {
@@ -349,21 +346,20 @@ static int me_ao_insn_write(struct comedi_device *dev,
dev_private->dac_control |=
((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
}
- writew(dev_private->dac_control,
- dev_private->me_regbase + ME_DAC_CONTROL);
+ writew(dev_private->dac_control, dev->mmio + ME_DAC_CONTROL);
/* Update dac-control register */
- readw(dev_private->me_regbase + ME_DAC_CONTROL_UPDATE);
+ readw(dev->mmio + ME_DAC_CONTROL_UPDATE);
/* Set data register */
for (i = 0; i < insn->n; i++) {
writew((data[0] & s->maxdata),
- dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
+ dev->mmio + ME_DAC_DATA_A + (chan << 1));
dev_private->ao_readback[chan] = (data[0] & s->maxdata);
}
/* Update dac with data registers */
- readw(dev_private->me_regbase + ME_DAC_UPDATE);
+ readw(dev->mmio + ME_DAC_UPDATE);
return insn->n;
}
@@ -396,13 +392,13 @@ static int me2600_xilinx_download(struct comedi_device *dev,
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);
+ value = readw(dev->mmio + XILINX_DOWNLOAD_RESET);
/* Wait until reset is over */
sleep(1);
/* Write a dummy value to Xilinx */
- writeb(0x00, dev_private->me_regbase + 0x0);
+ writeb(0x00, dev->mmio + 0x0);
sleep(1);
/*
@@ -426,12 +422,11 @@ static int me2600_xilinx_download(struct comedi_device *dev,
* Firmware data start at offset 16
*/
for (i = 0; i < file_length; i++)
- writeb((data[16 + i] & 0xff),
- dev_private->me_regbase + 0x0);
+ writeb((data[16 + i] & 0xff), dev->mmio + 0x0);
/* Write 5 dummy values to xilinx */
for (i = 0; i < 5; i++)
- writeb(0x00, dev_private->me_regbase + 0x0);
+ writeb(0x00, dev->mmio + 0x0);
/* Test if there was an error during download -> INTB was thrown */
value = readl(dev_private->plx_regbase + PLX9052_INTCSR);
@@ -459,10 +454,10 @@ static int me_reset(struct comedi_device *dev)
struct me_private_data *dev_private = dev->private;
/* Reset board */
- writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
- writew(0x00, dev_private->me_regbase + ME_CONTROL_2);
- writew(0x00, dev_private->me_regbase + ME_RESET_INTERRUPT);
- writew(0x00, dev_private->me_regbase + ME_DAC_CONTROL);
+ writew(0x00, dev->mmio + ME_CONTROL_1);
+ writew(0x00, dev->mmio + ME_CONTROL_2);
+ writew(0x00, dev->mmio + ME_RESET_INTERRUPT);
+ writew(0x00, dev->mmio + ME_DAC_CONTROL);
/* Save values in the board context */
dev_private->dac_control = 0;
@@ -500,8 +495,8 @@ static int me_auto_attach(struct comedi_device *dev,
if (!dev_private->plx_regbase)
return -ENOMEM;
- dev_private->me_regbase = pci_ioremap_bar(pcidev, 2);
- if (!dev_private->me_regbase)
+ dev->mmio = pci_ioremap_bar(pcidev, 2);
+ if (!dev->mmio)
return -ENOMEM;
/* Download firmware and reset card */
@@ -559,9 +554,9 @@ static void me_detach(struct comedi_device *dev)
struct me_private_data *dev_private = dev->private;
if (dev_private) {
- if (dev_private->me_regbase) {
+ if (dev->mmio) {
me_reset(dev);
- iounmap(dev_private->me_regbase);
+ iounmap(dev->mmio);
}
if (dev_private->plx_regbase)
iounmap(dev_private->plx_regbase);
diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c
index a4f7d6f138df..464f4b4745c7 100644
--- a/drivers/staging/comedi/drivers/mf6x4.c
+++ b/drivers/staging/comedi/drivers/mf6x4.c
@@ -93,7 +93,6 @@ struct mf6x4_private {
* and MF634 yet we will call them 0, 1, 2
*/
void __iomem *bar0_mem;
- void __iomem *bar1_mem;
void __iomem *bar2_mem;
/*
@@ -108,25 +107,22 @@ struct mf6x4_private {
};
static int mf6x4_di_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct mf6x4_private *devpriv = dev->private;
-
- data[1] = ioread16(devpriv->bar1_mem + MF6X4_DIN_R) & MF6X4_DIN_M;
+ data[1] = ioread16(dev->mmio + MF6X4_DIN_R) & MF6X4_DIN_M;
return insn->n;
}
static int mf6x4_do_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- struct mf6x4_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- iowrite16(s->state & MF6X4_DOUT_M,
- devpriv->bar1_mem + MF6X4_DOUT_R);
+ iowrite16(s->state & MF6X4_DOUT_M, dev->mmio + MF6X4_DOUT_R);
data[1] = s->state;
@@ -149,40 +145,40 @@ static int mf6x4_ai_eoc(struct comedi_device *dev,
static int mf6x4_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 mf6x4_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec);
int ret;
int i;
int d;
/* Set the ADC channel number in the scan list */
- iowrite16((1 << chan) & MF6X4_ADCTRL_M,
- devpriv->bar1_mem + MF6X4_ADCTRL_R);
+ iowrite16((1 << chan) & MF6X4_ADCTRL_M, dev->mmio + MF6X4_ADCTRL_R);
for (i = 0; i < insn->n; i++) {
/* Trigger ADC conversion by reading ADSTART */
- ioread16(devpriv->bar1_mem + MF6X4_ADSTART_R);
+ ioread16(dev->mmio + MF6X4_ADSTART_R);
ret = comedi_timeout(dev, s, insn, mf6x4_ai_eoc, 0);
if (ret)
return ret;
/* Read the actual value */
- d = ioread16(devpriv->bar1_mem + MF6X4_ADDATA_R);
+ d = ioread16(dev->mmio + MF6X4_ADDATA_R);
d &= s->maxdata;
data[i] = d;
}
- iowrite16(0x0, devpriv->bar1_mem + MF6X4_ADCTRL_R);
+ iowrite16(0x0, dev->mmio + MF6X4_ADCTRL_R);
return insn->n;
}
static int mf6x4_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 mf6x4_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
@@ -195,8 +191,7 @@ static int mf6x4_ao_insn_write(struct comedi_device *dev,
devpriv->gpioc_R);
for (i = 0; i < insn->n; i++) {
- iowrite16(data[i] & MF6X4_DA_M,
- devpriv->bar1_mem + MF6X4_DAC_R(chan));
+ iowrite16(data[i] & MF6X4_DA_M, dev->mmio + MF6X4_DAC_R(chan));
devpriv->ao_readback[chan] = data[i];
}
@@ -246,8 +241,8 @@ static int mf6x4_auto_attach(struct comedi_device *dev, unsigned long context)
if (!devpriv->bar0_mem)
return -ENODEV;
- devpriv->bar1_mem = pci_ioremap_bar(pcidev, board->bar_nums[1]);
- if (!devpriv->bar1_mem)
+ dev->mmio = pci_ioremap_bar(pcidev, board->bar_nums[1]);
+ if (!dev->mmio)
return -ENODEV;
devpriv->bar2_mem = pci_ioremap_bar(pcidev, board->bar_nums[2]);
@@ -310,8 +305,8 @@ static void mf6x4_detach(struct comedi_device *dev)
if (devpriv->bar0_mem)
iounmap(devpriv->bar0_mem);
- if (devpriv->bar1_mem)
- iounmap(devpriv->bar1_mem);
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (devpriv->bar2_mem)
iounmap(devpriv->bar2_mem);
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 19c029acbc99..4f7829010a99 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -90,10 +90,12 @@ static unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
unsigned fcr_bits = readl(mite->mite_io_addr + MITE_FCR(channel));
unsigned empty_count = (fcr_bits >> 16) & 0xff;
unsigned full_count = fcr_bits & 0xff;
+
return empty_count + full_count;
}
-int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
+int mite_setup2(struct comedi_device *dev,
+ struct mite_struct *mite, bool use_win1)
{
unsigned long length;
int i;
@@ -104,24 +106,24 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
mite->mite_io_addr = pci_ioremap_bar(mite->pcidev, 0);
if (!mite->mite_io_addr) {
- dev_err(&mite->pcidev->dev,
+ dev_err(dev->class_dev,
"Failed to remap mite io memory address\n");
return -ENOMEM;
}
mite->mite_phys_addr = pci_resource_start(mite->pcidev, 0);
- mite->daq_io_addr = pci_ioremap_bar(mite->pcidev, 1);
- if (!mite->daq_io_addr) {
- dev_err(&mite->pcidev->dev,
+ dev->mmio = pci_ioremap_bar(mite->pcidev, 1);
+ if (!dev->mmio) {
+ dev_err(dev->class_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) {
+ if (use_win1) {
writel(0, mite->mite_io_addr + MITE_IODWBSR);
- dev_info(&mite->pcidev->dev,
+ dev_info(dev->class_dev,
"using I/O Window Base Size register 1\n");
writel(mite->daq_phys_addr | WENAB |
MITE_IODWBSR_1_WSIZE_bits(length),
@@ -147,7 +149,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
mite->num_channels = mite_csigr_dmac(csigr_bits);
if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
- dev_warn(&mite->pcidev->dev,
+ dev_warn(dev->class_dev,
"mite: bug? chip claims to have %i dma channels. Setting to %i.\n",
mite->num_channels, MAX_MITE_DMA_CHANNELS);
mite->num_channels = MAX_MITE_DMA_CHANNELS;
@@ -162,36 +164,22 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
mite->mite_io_addr + MITE_CHCR(i));
}
mite->fifo_size = mite_fifo_size(mite, 0);
- dev_info(&mite->pcidev->dev, "fifo size is %i.\n", mite->fifo_size);
+ dev_info(dev->class_dev, "fifo size is %i.\n", mite->fifo_size);
return 0;
}
EXPORT_SYMBOL_GPL(mite_setup2);
-int mite_setup(struct mite_struct *mite)
+void mite_detach(struct mite_struct *mite)
{
- return mite_setup2(mite, 0);
-}
-EXPORT_SYMBOL_GPL(mite_setup);
-
-void mite_unsetup(struct mite_struct *mite)
-{
- /* unsigned long offset, start, length; */
-
if (!mite)
return;
- if (mite->mite_io_addr) {
+ if (mite->mite_io_addr)
iounmap(mite->mite_io_addr);
- mite->mite_io_addr = NULL;
- }
- if (mite->daq_io_addr) {
- iounmap(mite->daq_io_addr);
- mite->daq_io_addr = NULL;
- }
- if (mite->mite_phys_addr)
- mite->mite_phys_addr = 0;
+
+ kfree(mite);
}
-EXPORT_SYMBOL_GPL(mite_unsetup);
+EXPORT_SYMBOL_GPL(mite_detach);
struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite)
{
@@ -450,12 +438,14 @@ EXPORT_SYMBOL_GPL(mite_prep_dma);
static u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
{
struct mite_struct *mite = mite_chan->mite;
+
return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
}
u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
{
struct mite_struct *mite = mite_chan->mite;
+
return readl(mite->mite_io_addr +
MITE_FCR(mite_chan->channel)) & 0x000000FF;
}
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index e6e58e989b73..b2b12045b3a5 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -55,7 +55,6 @@ struct mite_struct {
resource_size_t mite_phys_addr;
void __iomem *mite_io_addr;
resource_size_t daq_phys_addr;
- void __iomem *daq_io_addr;
struct mite_channel channels[MAX_MITE_DMA_CHANNELS];
short channel_allocated[MAX_MITE_DMA_CHANNELS];
int num_channels;
@@ -65,24 +64,15 @@ struct mite_struct {
struct mite_struct *mite_alloc(struct pci_dev *pcidev);
-static inline void mite_free(struct mite_struct *mite)
-{
- kfree(mite);
-}
-
-static inline unsigned int mite_irq(struct mite_struct *mite)
-{
- return mite->pcidev->irq;
-};
+int mite_setup2(struct comedi_device *, struct mite_struct *, bool use_win1);
-static inline unsigned int mite_device_id(struct mite_struct *mite)
+static inline int mite_setup(struct comedi_device *dev,
+ struct mite_struct *mite)
{
- return mite->pcidev->device;
-};
+ return mite_setup2(dev, mite, false);
+}
-int mite_setup(struct mite_struct *mite);
-int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1);
-void mite_unsetup(struct mite_struct *mite);
+void mite_detach(struct mite_struct *mite);
struct mite_dma_descriptor_ring *mite_alloc_ring(struct mite_struct *mite);
void mite_free_ring(struct mite_dma_descriptor_ring *ring);
struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
@@ -122,11 +112,6 @@ void mite_prep_dma(struct mite_channel *mite_chan,
int mite_buf_change(struct mite_dma_descriptor_ring *ring,
struct comedi_subdevice *s);
-static inline int CHAN_OFFSET(int channel)
-{
- return 0x500 + 0x100 * channel;
-};
-
enum mite_registers {
/* The bits 0x90180700 in MITE_UNKNOWN_DMA_BURST_REG can be
written and read back. The bits 0x1f always read as 1.
@@ -138,90 +123,25 @@ enum mite_registers {
MITE_PCI_CONFIG_OFFSET = 0x300,
MITE_CSIGR = 0x460 /* chip signature */
};
-static inline int MITE_CHOR(int channel)
-{ /* channel operation */
- return CHAN_OFFSET(channel) + 0x0;
-};
-static inline int MITE_CHCR(int channel)
-{ /* channel control */
- return CHAN_OFFSET(channel) + 0x4;
-};
-
-static inline int MITE_TCR(int channel)
-{ /* transfer count */
- return CHAN_OFFSET(channel) + 0x8;
-};
-
-static inline int MITE_MCR(int channel)
-{ /* memory configuration */
- return CHAN_OFFSET(channel) + 0xc;
-};
-
-static inline int MITE_MAR(int channel)
-{ /* memory address */
- return CHAN_OFFSET(channel) + 0x10;
-};
-
-static inline int MITE_DCR(int channel)
-{ /* device configuration */
- return CHAN_OFFSET(channel) + 0x14;
-};
-
-static inline int MITE_DAR(int channel)
-{ /* device address */
- return CHAN_OFFSET(channel) + 0x18;
-};
-
-static inline int MITE_LKCR(int channel)
-{ /* link configuration */
- return CHAN_OFFSET(channel) + 0x1c;
-};
-
-static inline int MITE_LKAR(int channel)
-{ /* link address */
- return CHAN_OFFSET(channel) + 0x20;
-};
-
-static inline int MITE_LLKAR(int channel)
-{ /* see mite section of tnt5002 manual */
- return CHAN_OFFSET(channel) + 0x24;
-};
-
-static inline int MITE_BAR(int channel)
-{ /* base address */
- return CHAN_OFFSET(channel) + 0x28;
-};
-
-static inline int MITE_BCR(int channel)
-{ /* base count */
- return CHAN_OFFSET(channel) + 0x2c;
-};
-
-static inline int MITE_SAR(int channel)
-{ /* ? address */
- return CHAN_OFFSET(channel) + 0x30;
-};
-
-static inline int MITE_WSCR(int channel)
-{ /* ? */
- return CHAN_OFFSET(channel) + 0x34;
-};
-
-static inline int MITE_WSER(int channel)
-{ /* ? */
- return CHAN_OFFSET(channel) + 0x38;
-};
-
-static inline int MITE_CHSR(int channel)
-{ /* channel status */
- return CHAN_OFFSET(channel) + 0x3c;
-};
-
-static inline int MITE_FCR(int channel)
-{ /* fifo count */
- return CHAN_OFFSET(channel) + 0x40;
-};
+#define MITE_CHAN(x) (0x500 + 0x100 * (x))
+#define MITE_CHOR(x) (0x00 + MITE_CHAN(x)) /* channel operation */
+#define MITE_CHCR(x) (0x04 + MITE_CHAN(x)) /* channel control */
+#define MITE_TCR(x) (0x08 + MITE_CHAN(x)) /* transfer count */
+#define MITE_MCR(x) (0x0c + MITE_CHAN(x)) /* memory configuration */
+#define MITE_MAR(x) (0x10 + MITE_CHAN(x)) /* memory address */
+#define MITE_DCR(x) (0x14 + MITE_CHAN(x)) /* device configuration */
+#define MITE_DAR(x) (0x18 + MITE_CHAN(x)) /* device address */
+#define MITE_LKCR(x) (0x1c + MITE_CHAN(x)) /* link configuration */
+#define MITE_LKAR(x) (0x20 + MITE_CHAN(x)) /* link address */
+#define MITE_LLKAR(x) (0x24 + MITE_CHAN(x)) /* see tnt5002 manual */
+#define MITE_BAR(x) (0x28 + MITE_CHAN(x)) /* base address */
+#define MITE_BCR(x) (0x2c + MITE_CHAN(x)) /* base count */
+#define MITE_SAR(x) (0x30 + MITE_CHAN(x)) /* ? address */
+#define MITE_WSCR(x) (0x34 + MITE_CHAN(x)) /* ? */
+#define MITE_WSER(x) (0x38 + MITE_CHAN(x)) /* ? */
+#define MITE_CHSR(x) (0x3c + MITE_CHAN(x)) /* channel status */
+#define MITE_FCR(x) (0x40 + MITE_CHAN(x)) /* fifo count */
enum MITE_IODWBSR_bits {
WENAB = 0x80, /* window enable */
@@ -269,11 +189,9 @@ static inline int mite_csigr_dmac(u32 csigr_bits)
static inline int mite_csigr_wpdep(u32 csigr_bits)
{ /* write post fifo depth */
unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
- if (wpdep_bits == 0)
- return 0;
- else
- return 1 << (wpdep_bits - 1);
-};
+
+ return (wpdep_bits) ? (1 << (wpdep_bits - 1)) : 0;
+}
static inline int mite_csigr_wins(u32 csigr_bits)
{
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index f770400a0e81..1241f9987cab 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -56,9 +56,6 @@ Configuration Options:
#include <linux/delay.h>
-/* Consecutive I/O port addresses */
-#define MPC624_SIZE 16
-
/* Offsets of different ports */
#define MPC624_MASTER_CONTROL 0 /* not used */
#define MPC624_GNMUXCH 1 /* Gain, Mux, Channel of ADC */
@@ -279,7 +276,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], MPC624_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
index b74b9e9bfd4a..e841a5a3ec4f 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -28,8 +28,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3)
#include <linux/interrupt.h>
#include "../comedidev.h"
-#define MULTIQ3_SIZE 16
-
/*
* MULTIQ-3 port offsets
*/
@@ -189,12 +187,12 @@ static int multiq3_encoder_insn_read(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- int n;
int chan = CR_CHAN(insn->chanspec);
int control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+ int value;
+ int n;
for (n = 0; n < insn->n; n++) {
- int value;
outw(control, dev->iobase + MULTIQ3_CONTROL);
outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
outb(MULTIQ3_TRSFRCNTR_OL, dev->iobase + MULTIQ3_ENC_CONTROL);
@@ -233,7 +231,7 @@ static int multiq3_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], MULTIQ3_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index c8b1fa793a37..e84dac2bf3b2 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -90,7 +90,6 @@ static const struct ni6527_board ni6527_boards[] = {
};
struct ni6527_private {
- void __iomem *mmio_base;
unsigned int filter_interval;
unsigned int filter_enable;
};
@@ -99,14 +98,15 @@ static void ni6527_set_filter_interval(struct comedi_device *dev,
unsigned int val)
{
struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
if (val != devpriv->filter_interval) {
- writeb(val & 0xff, mmio + NI6527_FILT_INTERVAL_REG(0));
- writeb((val >> 8) & 0xff, mmio + NI6527_FILT_INTERVAL_REG(1));
- writeb((val >> 16) & 0x0f, mmio + NI6527_FILT_INTERVAL_REG(2));
+ writeb(val & 0xff, dev->mmio + NI6527_FILT_INTERVAL_REG(0));
+ writeb((val >> 8) & 0xff,
+ dev->mmio + NI6527_FILT_INTERVAL_REG(1));
+ writeb((val >> 16) & 0x0f,
+ dev->mmio + NI6527_FILT_INTERVAL_REG(2));
- writeb(NI6527_CLR_INTERVAL, mmio + NI6527_CLR_REG);
+ writeb(NI6527_CLR_INTERVAL, dev->mmio + NI6527_CLR_REG);
devpriv->filter_interval = val;
}
@@ -115,12 +115,9 @@ static void ni6527_set_filter_interval(struct comedi_device *dev,
static void ni6527_set_filter_enable(struct comedi_device *dev,
unsigned int val)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- writeb(val & 0xff, mmio + NI6527_FILT_ENA_REG(0));
- writeb((val >> 8) & 0xff, mmio + NI6527_FILT_ENA_REG(1));
- writeb((val >> 16) & 0xff, mmio + NI6527_FILT_ENA_REG(2));
+ writeb(val & 0xff, dev->mmio + NI6527_FILT_ENA_REG(0));
+ writeb((val >> 8) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(1));
+ writeb((val >> 16) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(2));
}
static int ni6527_di_insn_config(struct comedi_device *dev,
@@ -162,13 +159,11 @@ static int ni6527_di_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
unsigned int val;
- val = readb(mmio + NI6527_DI_REG(0));
- val |= (readb(mmio + NI6527_DI_REG(1)) << 8);
- val |= (readb(mmio + NI6527_DI_REG(2)) << 16);
+ val = readb(dev->mmio + NI6527_DI_REG(0));
+ val |= (readb(dev->mmio + NI6527_DI_REG(1)) << 8);
+ val |= (readb(dev->mmio + NI6527_DI_REG(2)) << 16);
data[1] = val;
@@ -180,8 +175,6 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
unsigned int mask;
mask = comedi_dio_update_state(s, data);
@@ -190,11 +183,13 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
unsigned int val = s->state ^ 0xffffff;
if (mask & 0x0000ff)
- writeb(val & 0xff, mmio + NI6527_DO_REG(0));
+ writeb(val & 0xff, dev->mmio + NI6527_DO_REG(0));
if (mask & 0x00ff00)
- writeb((val >> 8) & 0xff, mmio + NI6527_DO_REG(1));
+ writeb((val >> 8) & 0xff,
+ dev->mmio + NI6527_DO_REG(1));
if (mask & 0xff0000)
- writeb((val >> 16) & 0xff, mmio + NI6527_DO_REG(2));
+ writeb((val >> 16) & 0xff,
+ dev->mmio + NI6527_DO_REG(2));
}
data[1] = s->state;
@@ -205,12 +200,10 @@ static int ni6527_do_insn_bits(struct comedi_device *dev,
static irqreturn_t ni6527_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct ni6527_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
- void __iomem *mmio = devpriv->mmio_base;
unsigned int status;
- status = readb(mmio + NI6527_STATUS_REG);
+ status = readb(dev->mmio + NI6527_STATUS_REG);
if (!(status & NI6527_STATUS_IRQ))
return IRQ_NONE;
@@ -220,7 +213,7 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
comedi_event(dev, s);
}
- writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
+ writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
return IRQ_HANDLED;
}
@@ -270,11 +263,8 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev,
static int ni6527_intr_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
- writeb(NI6527_CTRL_ENABLE_IRQS, mmio + NI6527_CTRL_REG);
+ writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
+ writeb(NI6527_CTRL_ENABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
return 0;
}
@@ -282,10 +272,7 @@ static int ni6527_intr_cmd(struct comedi_device *dev,
static int ni6527_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
+ writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
return 0;
}
@@ -299,21 +286,37 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev,
}
static void ni6527_set_edge_detection(struct comedi_device *dev,
+ unsigned int mask,
unsigned int rising,
unsigned int falling)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
- /* enable rising-edge detection channels */
- writeb(rising & 0xff, mmio + NI6527_RISING_EDGE_REG(0));
- writeb((rising >> 8) & 0xff, mmio + NI6527_RISING_EDGE_REG(1));
- writeb((rising >> 16) & 0xff, mmio + NI6527_RISING_EDGE_REG(2));
-
- /* enable falling-edge detection channels */
- writeb(falling & 0xff, mmio + NI6527_FALLING_EDGE_REG(0));
- writeb((falling >> 8) & 0xff, mmio + NI6527_FALLING_EDGE_REG(1));
- writeb((falling >> 16) & 0xff, mmio + NI6527_FALLING_EDGE_REG(2));
+ unsigned int i;
+
+ rising &= mask;
+ falling &= mask;
+ for (i = 0; i < 2; i++) {
+ if (mask & 0xff) {
+ if (~mask & 0xff) {
+ /* preserve rising-edge detection channels */
+ rising |= readb(dev->mmio +
+ NI6527_RISING_EDGE_REG(i)) &
+ (~mask & 0xff);
+ /* preserve falling-edge detection channels */
+ falling |= readb(dev->mmio +
+ NI6527_FALLING_EDGE_REG(i)) &
+ (~mask & 0xff);
+ }
+ /* update rising-edge detection channels */
+ writeb(rising & 0xff,
+ dev->mmio + NI6527_RISING_EDGE_REG(i));
+ /* update falling-edge detection channels */
+ writeb(falling & 0xff,
+ dev->mmio + NI6527_FALLING_EDGE_REG(i));
+ }
+ rising >>= 8;
+ falling >>= 8;
+ mask >>= 8;
+ }
}
static int ni6527_intr_insn_config(struct comedi_device *dev,
@@ -321,12 +324,45 @@ static int ni6527_intr_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
+ unsigned int mask = 0xffffffff;
+ unsigned int rising, falling, shift;
+
switch (data[0]) {
case INSN_CONFIG_CHANGE_NOTIFY:
/* check_insn_config_length() does not check this instruction */
if (insn->n != 3)
return -EINVAL;
- ni6527_set_edge_detection(dev, data[1], data[2]);
+ rising = data[1];
+ falling = data[2];
+ ni6527_set_edge_detection(dev, mask, rising, falling);
+ break;
+ case INSN_CONFIG_DIGITAL_TRIG:
+ /* check trigger number */
+ if (data[1] != 0)
+ return -EINVAL;
+ /* check digital trigger operation */
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ rising = 0;
+ falling = 0;
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ /* check shift amount */
+ shift = data[3];
+ if (shift >= s->n_chan) {
+ mask = 0;
+ rising = 0;
+ falling = 0;
+ } else {
+ mask <<= shift;
+ rising = data[4] << shift;
+ falling = data[5] << shift;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ ni6527_set_edge_detection(dev, mask, rising, falling);
break;
default:
return -EINVAL;
@@ -337,15 +373,15 @@ static int ni6527_intr_insn_config(struct comedi_device *dev,
static void ni6527_reset(struct comedi_device *dev)
{
- struct ni6527_private *devpriv = dev->private;
- void __iomem *mmio = devpriv->mmio_base;
-
/* disable deglitch filters on all channels */
ni6527_set_filter_enable(dev, 0);
+ /* disable edge detection */
+ ni6527_set_edge_detection(dev, 0xffffffff, 0, 0);
+
writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
- mmio + NI6527_CLR_REG);
- writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
+ dev->mmio + NI6527_CLR_REG);
+ writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
}
static int ni6527_auto_attach(struct comedi_device *dev,
@@ -372,12 +408,12 @@ static int ni6527_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->mmio_base = pci_ioremap_bar(pcidev, 1);
- if (!devpriv->mmio_base)
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
return -ENOMEM;
/* make sure this is actually a 6527 device */
- if (readb(devpriv->mmio_base + NI6527_ID_REG) != 0x27)
+ if (readb(dev->mmio + NI6527_ID_REG) != 0x27)
return -ENODEV;
ni6527_reset(dev);
@@ -434,12 +470,12 @@ static int ni6527_auto_attach(struct comedi_device *dev,
static void ni6527_detach(struct comedi_device *dev)
{
- struct ni6527_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mmio_base)
+ if (dev->mmio)
ni6527_reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index 9a139d6b8ef4..873941be56cb 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -1,46 +1,73 @@
/*
- comedi/drivers/ni_6514.c
- driver for National Instruments PCI-6514
-
- Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
- Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
-
- COMEDI - Linux Control and Measurement Device Interface
- Copyright (C) 1999,2002,2003 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.
+ * ni_65xx.c
+ * Comedi driver for National Instruments PCI-65xx static dio boards
+ *
+ * Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
+ * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1999,2002,2003 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.
+ */
- 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.
-*/
/*
-Driver: ni_65xx
-Description: National Instruments 65xx static dio boards
-Author: Jon Grierson <jd@renko.co.uk>,
- Frank Mori Hess <fmhess@users.sourceforge.net>
-Status: testing
-Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510,
- PCI-6511, PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514,
- PXI-6514, PCI-6515, PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519,
- PCI-6520, PCI-6521, PXI-6521, PCI-6528, PXI-6528
-Updated: Wed Oct 18 08:59:11 EDT 2006
-
-Based on the PCI-6527 driver by ds.
-The interrupt subdevice (subdevice 3) is probably broken for all boards
-except maybe the 6514.
-
-*/
+ * Driver: ni_65xx
+ * Description: National Instruments 65xx static dio boards
+ * Author: Jon Grierson <jd@renko.co.uk>,
+ * Frank Mori Hess <fmhess@users.sourceforge.net>
+ * Status: testing
+ * Devices: (National Instruments) PCI-6509 [ni_65xx]
+ * (National Instruments) PXI-6509 [ni_65xx]
+ * (National Instruments) PCI-6510 [ni_65xx]
+ * (National Instruments) PCI-6511 [ni_65xx]
+ * (National Instruments) PXI-6511 [ni_65xx]
+ * (National Instruments) PCI-6512 [ni_65xx]
+ * (National Instruments) PXI-6512 [ni_65xx]
+ * (National Instruments) PCI-6513 [ni_65xx]
+ * (National Instruments) PXI-6513 [ni_65xx]
+ * (National Instruments) PCI-6514 [ni_65xx]
+ * (National Instruments) PXI-6514 [ni_65xx]
+ * (National Instruments) PCI-6515 [ni_65xx]
+ * (National Instruments) PXI-6515 [ni_65xx]
+ * (National Instruments) PCI-6516 [ni_65xx]
+ * (National Instruments) PCI-6517 [ni_65xx]
+ * (National Instruments) PCI-6518 [ni_65xx]
+ * (National Instruments) PCI-6519 [ni_65xx]
+ * (National Instruments) PCI-6520 [ni_65xx]
+ * (National Instruments) PCI-6521 [ni_65xx]
+ * (National Instruments) PXI-6521 [ni_65xx]
+ * (National Instruments) PCI-6528 [ni_65xx]
+ * (National Instruments) PXI-6528 [ni_65xx]
+ * Updated: Mon, 21 Jul 2014 12:49:58 +0000
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ *
+ * Based on the PCI-6527 driver by ds.
+ * The interrupt subdevice (subdevice 3) is probably broken for all
+ * boards except maybe the 6514.
+ *
+ * This driver previously inverted the outputs on PCI-6513 through to
+ * PCI-6519 and on PXI-6513 through to PXI-6515. It no longer inverts
+ * outputs on those cards by default as it didn't make much sense. If
+ * you require the outputs to be inverted on those cards for legacy
+ * reasons, set the module parameter "legacy_invert_outputs=true" when
+ * loading the module, or set "ni_65xx.legacy_invert_outputs=true" on
+ * the kernel command line if the driver is built in to the kernel.
+ */
/*
- Manuals (available from ftp://ftp.natinst.com/support/manuals)
-
- 370106b.pdf 6514 Register Level Programmer Manual
-
+ * Manuals (available from ftp://ftp.natinst.com/support/manuals)
+ *
+ * 370106b.pdf 6514 Register Level Programmer Manual
*/
#include <linux/module.h>
@@ -50,59 +77,69 @@ except maybe the 6514.
#include "../comedidev.h"
#include "comedi_fc.h"
-#include "mite.h"
-
-#define NI6514_DIO_SIZE 4096
-#define NI6514_MITE_SIZE 4096
-
-#define NI_65XX_MAX_NUM_PORTS 12
-static const unsigned ni_65xx_channels_per_port = 8;
-static const unsigned ni_65xx_port_offset = 0x10;
-
-static inline unsigned Port_Data(unsigned port)
-{
- return 0x40 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Port_Select(unsigned port)
-{
- return 0x41 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Rising_Edge_Detection_Enable(unsigned port)
-{
- return 0x42 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Falling_Edge_Detection_Enable(unsigned port)
-{
- return 0x43 + port * ni_65xx_port_offset;
-}
-
-static inline unsigned Filter_Enable(unsigned port)
-{
- return 0x44 + port * ni_65xx_port_offset;
-}
-
-#define ID_Register 0x00
-
-#define Clear_Register 0x01
-#define ClrEdge 0x08
-#define ClrOverflow 0x04
-#define Filter_Interval 0x08
-
-#define Change_Status 0x02
-#define MasterInterruptStatus 0x04
-#define Overflow 0x02
-#define EdgeStatus 0x01
+/*
+ * PCI BAR1 Register Map
+ */
-#define Master_Interrupt_Control 0x03
-#define FallingEdgeIntEnable 0x10
-#define RisingEdgeIntEnable 0x08
-#define MasterInterruptEnable 0x04
-#define OverflowIntEnable 0x02
-#define EdgeIntEnable 0x01
+/* Non-recurring Registers (8-bit except where noted) */
+#define NI_65XX_ID_REG 0x00
+#define NI_65XX_CLR_REG 0x01
+#define NI_65XX_CLR_WDOG_INT (1 << 6)
+#define NI_65XX_CLR_WDOG_PING (1 << 5)
+#define NI_65XX_CLR_WDOG_EXP (1 << 4)
+#define NI_65XX_CLR_EDGE_INT (1 << 3)
+#define NI_65XX_CLR_OVERFLOW_INT (1 << 2)
+#define NI_65XX_STATUS_REG 0x02
+#define NI_65XX_STATUS_WDOG_INT (1 << 5)
+#define NI_65XX_STATUS_FALL_EDGE (1 << 4)
+#define NI_65XX_STATUS_RISE_EDGE (1 << 3)
+#define NI_65XX_STATUS_INT (1 << 2)
+#define NI_65XX_STATUS_OVERFLOW_INT (1 << 1)
+#define NI_65XX_STATUS_EDGE_INT (1 << 0)
+#define NI_65XX_CTRL_REG 0x03
+#define NI_65XX_CTRL_WDOG_ENA (1 << 5)
+#define NI_65XX_CTRL_FALL_EDGE_ENA (1 << 4)
+#define NI_65XX_CTRL_RISE_EDGE_ENA (1 << 3)
+#define NI_65XX_CTRL_INT_ENA (1 << 2)
+#define NI_65XX_CTRL_OVERFLOW_ENA (1 << 1)
+#define NI_65XX_CTRL_EDGE_ENA (1 << 0)
+#define NI_65XX_REV_REG 0x04 /* 32-bit */
+#define NI_65XX_FILTER_REG 0x08 /* 32-bit */
+#define NI_65XX_RTSI_ROUTE_REG 0x0c /* 16-bit */
+#define NI_65XX_RTSI_EDGE_REG 0x0e /* 16-bit */
+#define NI_65XX_RTSI_WDOG_REG 0x10 /* 16-bit */
+#define NI_65XX_RTSI_TRIG_REG 0x12 /* 16-bit */
+#define NI_65XX_AUTO_CLK_SEL_REG 0x14 /* PXI-6528 only */
+#define NI_65XX_AUTO_CLK_SEL_STATUS (1 << 1)
+#define NI_65XX_AUTO_CLK_SEL_DISABLE (1 << 0)
+#define NI_65XX_WDOG_CTRL_REG 0x15
+#define NI_65XX_WDOG_CTRL_ENA (1 << 0)
+#define NI_65XX_RTSI_CFG_REG 0x16
+#define NI_65XX_RTSI_CFG_RISE_SENSE (1 << 2)
+#define NI_65XX_RTSI_CFG_FALL_SENSE (1 << 1)
+#define NI_65XX_RTSI_CFG_SYNC_DETECT (1 << 0)
+#define NI_65XX_WDOG_STATUS_REG 0x17
+#define NI_65XX_WDOG_STATUS_EXP (1 << 0)
+#define NI_65XX_WDOG_INTERVAL_REG 0x18 /* 32-bit */
+
+/* Recurring port registers (8-bit) */
+#define NI_65XX_PORT(x) ((x) * 0x10)
+#define NI_65XX_IO_DATA_REG(x) (0x40 + NI_65XX_PORT(x))
+#define NI_65XX_IO_SEL_REG(x) (0x41 + NI_65XX_PORT(x))
+#define NI_65XX_IO_SEL_OUTPUT (0 << 0)
+#define NI_65XX_IO_SEL_INPUT (1 << 0)
+#define NI_65XX_RISE_EDGE_ENA_REG(x) (0x42 + NI_65XX_PORT(x))
+#define NI_65XX_FALL_EDGE_ENA_REG(x) (0x43 + NI_65XX_PORT(x))
+#define NI_65XX_FILTER_ENA(x) (0x44 + NI_65XX_PORT(x))
+#define NI_65XX_WDOG_HIZ_REG(x) (0x46 + NI_65XX_PORT(x))
+#define NI_65XX_WDOG_ENA(x) (0x47 + NI_65XX_PORT(x))
+#define NI_65XX_WDOG_HI_LO_REG(x) (0x48 + NI_65XX_PORT(x))
+#define NI_65XX_RTSI_ENA(x) (0x49 + NI_65XX_PORT(x))
+
+#define NI_65XX_PORT_TO_CHAN(x) ((x) * 8)
+#define NI_65XX_CHAN_TO_PORT(x) ((x) / 8)
+#define NI_65XX_CHAN_TO_MASK(x) (1 << ((x) % 8))
enum ni_65xx_boardid {
BOARD_PCI6509,
@@ -134,7 +171,7 @@ struct ni_65xx_board {
unsigned num_dio_ports;
unsigned num_di_ports;
unsigned num_do_ports;
- unsigned invert_outputs:1;
+ unsigned legacy_invert:1;
};
static const struct ni_65xx_board ni_65xx_boards[] = {
@@ -169,58 +206,58 @@ static const struct ni_65xx_board ni_65xx_boards[] = {
[BOARD_PCI6513] = {
.name = "pci-6513",
.num_do_ports = 8,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PXI6513] = {
.name = "pxi-6513",
.num_do_ports = 8,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6514] = {
.name = "pci-6514",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PXI6514] = {
.name = "pxi-6514",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6515] = {
.name = "pci-6515",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PXI6515] = {
.name = "pxi-6515",
.num_di_ports = 4,
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6516] = {
.name = "pci-6516",
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6517] = {
.name = "pci-6517",
.num_do_ports = 4,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6518] = {
.name = "pci-6518",
.num_di_ports = 2,
.num_do_ports = 2,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6519] = {
.name = "pci-6519",
.num_di_ports = 2,
.num_do_ports = 2,
- .invert_outputs = 1,
+ .legacy_invert = 1,
},
[BOARD_PCI6520] = {
.name = "pci-6520",
@@ -249,135 +286,174 @@ static const struct ni_65xx_board ni_65xx_boards[] = {
},
};
-static inline unsigned ni_65xx_port_by_channel(unsigned channel)
-{
- return channel / ni_65xx_channels_per_port;
-}
+static bool ni_65xx_legacy_invert_outputs;
+module_param_named(legacy_invert_outputs, ni_65xx_legacy_invert_outputs,
+ bool, 0444);
+MODULE_PARM_DESC(legacy_invert_outputs,
+ "invert outputs of PCI/PXI-6513/6514/6515/6516/6517/6518/6519 for compatibility with old user code");
-static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board
- *board)
+static unsigned int ni_65xx_num_ports(struct comedi_device *dev)
{
+ const struct ni_65xx_board *board = comedi_board(dev);
+
return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
}
-struct ni_65xx_private {
- struct mite_struct *mite;
- unsigned int filter_interval;
- unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS];
- unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
- unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
-};
+static void ni_65xx_disable_input_filters(struct comedi_device *dev)
+{
+ unsigned int num_ports = ni_65xx_num_ports(dev);
+ int i;
-struct ni_65xx_subdevice_private {
- unsigned base_port;
-};
+ /* disable input filtering on all ports */
+ for (i = 0; i < num_ports; ++i)
+ writeb(0x00, dev->mmio + NI_65XX_FILTER_ENA(i));
-static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice
- *subdev)
-{
- return subdev->private;
+ /* set filter interval to 0 (32bit reg) */
+ writel(0x00000000, dev->mmio + NI_65XX_FILTER_REG);
}
-static int ni_65xx_config_filter(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+/* updates edge detection for base_chan to base_chan+31 */
+static void ni_65xx_update_edge_detection(struct comedi_device *dev,
+ unsigned int base_chan,
+ unsigned int rising,
+ unsigned int falling)
{
- struct ni_65xx_private *devpriv = dev->private;
- const unsigned chan = CR_CHAN(insn->chanspec);
- const unsigned port =
- sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
+ unsigned int num_ports = ni_65xx_num_ports(dev);
+ unsigned int port;
- if (data[0] != INSN_CONFIG_FILTER)
- return -EINVAL;
- if (data[1]) {
- static const unsigned filter_resolution_ns = 200;
- static const unsigned max_filter_interval = 0xfffff;
- unsigned interval =
- (data[1] +
- (filter_resolution_ns / 2)) / filter_resolution_ns;
- if (interval > max_filter_interval)
- interval = max_filter_interval;
- data[1] = interval * filter_resolution_ns;
-
- if (interval != devpriv->filter_interval) {
- writeb(interval,
- devpriv->mite->daq_io_addr +
- Filter_Interval);
- devpriv->filter_interval = interval;
- }
+ if (base_chan >= NI_65XX_PORT_TO_CHAN(num_ports))
+ return;
- devpriv->filter_enable[port] |=
- 1 << (chan % ni_65xx_channels_per_port);
- } else {
- devpriv->filter_enable[port] &=
- ~(1 << (chan % ni_65xx_channels_per_port));
- }
+ for (port = NI_65XX_CHAN_TO_PORT(base_chan); port < num_ports; port++) {
+ int bitshift = (int)(NI_65XX_PORT_TO_CHAN(port) - base_chan);
+ unsigned int port_mask, port_rising, port_falling;
- writeb(devpriv->filter_enable[port],
- devpriv->mite->daq_io_addr + Filter_Enable(port));
+ if (bitshift >= 32)
+ break;
- return 2;
+ if (bitshift >= 0) {
+ port_mask = ~0U >> bitshift;
+ port_rising = rising >> bitshift;
+ port_falling = falling >> bitshift;
+ } else {
+ port_mask = ~0U << -bitshift;
+ port_rising = rising << -bitshift;
+ port_falling = falling << -bitshift;
+ }
+ if (port_mask & 0xff) {
+ if (~port_mask & 0xff) {
+ port_rising |=
+ readb(dev->mmio +
+ NI_65XX_RISE_EDGE_ENA_REG(port)) &
+ ~port_mask;
+ port_falling |=
+ readb(dev->mmio +
+ NI_65XX_FALL_EDGE_ENA_REG(port)) &
+ ~port_mask;
+ }
+ writeb(port_rising & 0xff,
+ dev->mmio + NI_65XX_RISE_EDGE_ENA_REG(port));
+ writeb(port_falling & 0xff,
+ dev->mmio + NI_65XX_FALL_EDGE_ENA_REG(port));
+ }
+ }
+}
+
+static void ni_65xx_disable_edge_detection(struct comedi_device *dev)
+{
+ /* clear edge detection for channels 0 to 31 */
+ ni_65xx_update_edge_detection(dev, 0, 0, 0);
+ /* clear edge detection for channels 32 to 63 */
+ ni_65xx_update_edge_detection(dev, 32, 0, 0);
+ /* clear edge detection for channels 64 to 95 */
+ ni_65xx_update_edge_detection(dev, 64, 0, 0);
}
static int ni_65xx_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 ni_65xx_private *devpriv = dev->private;
- unsigned port;
+ unsigned long base_port = (unsigned long)s->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int chan_mask = NI_65XX_CHAN_TO_MASK(chan);
+ unsigned port = base_port + NI_65XX_CHAN_TO_PORT(chan);
+ unsigned int interval;
+ unsigned int val;
- if (insn->n < 1)
- return -EINVAL;
- port = sprivate(s)->base_port +
- ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
switch (data[0]) {
case INSN_CONFIG_FILTER:
- return ni_65xx_config_filter(dev, s, insn, data);
+ /*
+ * The deglitch filter interval is specified in nanoseconds.
+ * The hardware supports intervals in 200ns increments. Round
+ * the user values up and return the actual interval.
+ */
+ interval = (data[1] + 100) / 200;
+ if (interval > 0xfffff)
+ interval = 0xfffff;
+ data[1] = interval * 200;
+
+ /*
+ * Enable/disable the channel for deglitch filtering. Note
+ * that the filter interval is never set to '0'. This is done
+ * because other channels might still be enabled for filtering.
+ */
+ val = readb(dev->mmio + NI_65XX_FILTER_ENA(port));
+ if (interval) {
+ writel(interval, dev->mmio + NI_65XX_FILTER_REG);
+ val |= chan_mask;
+ } else {
+ val &= ~chan_mask;
+ }
+ writeb(val, dev->mmio + NI_65XX_FILTER_ENA(port));
break;
+
case INSN_CONFIG_DIO_OUTPUT:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- devpriv->dio_direction[port] = COMEDI_OUTPUT;
- writeb(0, devpriv->mite->daq_io_addr + Port_Select(port));
- return 1;
+ writeb(NI_65XX_IO_SEL_OUTPUT,
+ dev->mmio + NI_65XX_IO_SEL_REG(port));
break;
+
case INSN_CONFIG_DIO_INPUT:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- devpriv->dio_direction[port] = COMEDI_INPUT;
- writeb(1, devpriv->mite->daq_io_addr + Port_Select(port));
- return 1;
+ writeb(NI_65XX_IO_SEL_INPUT,
+ dev->mmio + NI_65XX_IO_SEL_REG(port));
break;
+
case INSN_CONFIG_DIO_QUERY:
if (s->type != COMEDI_SUBD_DIO)
return -EINVAL;
- data[1] = devpriv->dio_direction[port];
- return insn->n;
+ val = readb(dev->mmio + NI_65XX_IO_SEL_REG(port));
+ data[1] = (val == NI_65XX_IO_SEL_INPUT) ? COMEDI_INPUT
+ : COMEDI_OUTPUT;
break;
+
default:
- break;
+ return -EINVAL;
}
- return -EINVAL;
+
+ return insn->n;
}
static int ni_65xx_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)
{
- const struct ni_65xx_board *board = comedi_board(dev);
- struct ni_65xx_private *devpriv = dev->private;
- int base_bitfield_channel;
+ unsigned long base_port = (unsigned long)s->private;
+ unsigned int base_chan = CR_CHAN(insn->chanspec);
+ int last_port_offset = NI_65XX_CHAN_TO_PORT(s->n_chan - 1);
unsigned read_bits = 0;
- int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1);
int port_offset;
- base_bitfield_channel = CR_CHAN(insn->chanspec);
- for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel);
+ for (port_offset = NI_65XX_CHAN_TO_PORT(base_chan);
port_offset <= last_port_offset; port_offset++) {
- unsigned port = sprivate(s)->base_port + port_offset;
- int base_port_channel = port_offset * ni_65xx_channels_per_port;
- unsigned port_mask, port_data, port_read_bits;
- int bitshift = base_port_channel - base_bitfield_channel;
+ unsigned port = base_port + port_offset;
+ int base_port_channel = NI_65XX_PORT_TO_CHAN(port_offset);
+ unsigned port_mask, port_data, bits;
+ int bitshift = base_port_channel - base_chan;
if (bitshift >= 32)
break;
@@ -392,32 +468,26 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
}
port_mask &= 0xff;
port_data &= 0xff;
+
+ /* update the outputs */
if (port_mask) {
- unsigned bits;
- devpriv->output_bits[port] &= ~port_mask;
- devpriv->output_bits[port] |=
- port_data & port_mask;
- bits = devpriv->output_bits[port];
- if (board->invert_outputs)
- bits = ~bits;
- writeb(bits,
- devpriv->mite->daq_io_addr +
- Port_Data(port));
- }
- port_read_bits =
- readb(devpriv->mite->daq_io_addr + Port_Data(port));
- 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.) */
- port_read_bits ^= 0xFF;
+ bits = readb(dev->mmio + NI_65XX_IO_DATA_REG(port));
+ bits ^= s->io_bits; /* invert if necessary */
+ bits &= ~port_mask;
+ bits |= (port_data & port_mask);
+ bits ^= s->io_bits; /* invert back */
+ writeb(bits, dev->mmio + NI_65XX_IO_DATA_REG(port));
}
+
+ /* read back the actual state */
+ bits = readb(dev->mmio + NI_65XX_IO_DATA_REG(port));
+ bits ^= s->io_bits; /* invert if necessary */
if (bitshift > 0)
- port_read_bits <<= bitshift;
+ bits <<= bitshift;
else
- port_read_bits >>= -bitshift;
+ bits >>= -bitshift;
- read_bits |= port_read_bits;
+ read_bits |= bits;
}
data[1] = read_bits;
return insn->n;
@@ -426,18 +496,17 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
static irqreturn_t ni_65xx_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
- struct ni_65xx_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
- status = readb(devpriv->mite->daq_io_addr + Change_Status);
- if ((status & MasterInterruptStatus) == 0)
+ status = readb(dev->mmio + NI_65XX_STATUS_REG);
+ if ((status & NI_65XX_STATUS_INT) == 0)
return IRQ_NONE;
- if ((status & EdgeStatus) == 0)
+ if ((status & NI_65XX_STATUS_EDGE_INT) == 0)
return IRQ_NONE;
- writeb(ClrEdge | ClrOverflow,
- devpriv->mite->daq_io_addr + Clear_Register);
+ writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
+ dev->mmio + NI_65XX_CLR_REG);
comedi_buf_put(s, 0);
s->async->events |= COMEDI_CB_EOS;
@@ -490,13 +559,11 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
static int ni_65xx_intr_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni_65xx_private *devpriv = dev->private;
-
- writeb(ClrEdge | ClrOverflow,
- devpriv->mite->daq_io_addr + Clear_Register);
- writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
- MasterInterruptEnable | EdgeIntEnable,
- devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+ writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
+ dev->mmio + NI_65XX_CLR_REG);
+ writeb(NI_65XX_CTRL_FALL_EDGE_ENA | NI_65XX_CTRL_RISE_EDGE_ENA |
+ NI_65XX_CTRL_INT_ENA | NI_65XX_CTRL_EDGE_ENA,
+ dev->mmio + NI_65XX_CTRL_REG);
return 0;
}
@@ -504,16 +571,15 @@ static int ni_65xx_intr_cmd(struct comedi_device *dev,
static int ni_65xx_intr_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct ni_65xx_private *devpriv = dev->private;
-
- writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+ writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
return 0;
}
static int ni_65xx_intr_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] = 0;
return insn->n;
@@ -524,40 +590,68 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_65xx_private *devpriv = dev->private;
+ switch (data[0]) {
+ case INSN_CONFIG_CHANGE_NOTIFY:
+ /* add instruction to check_insn_config_length() */
+ if (insn->n != 3)
+ return -EINVAL;
- if (insn->n < 1)
- return -EINVAL;
- if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+ /* update edge detection for channels 0 to 31 */
+ ni_65xx_update_edge_detection(dev, 0, data[1], data[2]);
+ /* clear edge detection for channels 32 to 63 */
+ ni_65xx_update_edge_detection(dev, 32, 0, 0);
+ /* clear edge detection for channels 64 to 95 */
+ ni_65xx_update_edge_detection(dev, 64, 0, 0);
+ break;
+ case INSN_CONFIG_DIGITAL_TRIG:
+ /* check trigger number */
+ if (data[1] != 0)
+ return -EINVAL;
+ /* check digital trigger operation */
+ switch (data[2]) {
+ case COMEDI_DIGITAL_TRIG_DISABLE:
+ ni_65xx_disable_edge_detection(dev);
+ break;
+ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+ /*
+ * update edge detection for channels data[3]
+ * to (data[3] + 31)
+ */
+ ni_65xx_update_edge_detection(dev, data[3],
+ data[4], data[5]);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
return -EINVAL;
+ }
+
+ return insn->n;
+}
+
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
+
+static int ni_65xx_mite_init(struct pci_dev *pcidev)
+{
+ void __iomem *mite_base;
+ u32 main_phys_addr;
+
+ /* ioremap the MITE registers (BAR 0) temporarily */
+ mite_base = pci_ioremap_bar(pcidev, 0);
+ if (!mite_base)
+ return -ENOMEM;
+
+ /* set data window to main registers (BAR 1) */
+ main_phys_addr = pci_resource_start(pcidev, 1);
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
- writeb(data[1],
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0));
- writeb(data[1] >> 8,
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0x10));
- writeb(data[1] >> 16,
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0x20));
- writeb(data[1] >> 24,
- devpriv->mite->daq_io_addr +
- Rising_Edge_Detection_Enable(0x30));
-
- writeb(data[2],
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0));
- writeb(data[2] >> 8,
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0x10));
- writeb(data[2] >> 16,
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0x20));
- writeb(data[2] >> 24,
- devpriv->mite->daq_io_addr +
- Falling_Edge_Detection_Enable(0x30));
-
- return 2;
+ /* finished with MITE registers */
+ iounmap(mite_base);
+ return 0;
}
static int ni_65xx_auto_attach(struct comedi_device *dev,
@@ -565,8 +659,6 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct ni_65xx_board *board = NULL;
- struct ni_65xx_private *devpriv;
- struct ni_65xx_subdevice_private *spriv;
struct comedi_subdevice *s;
unsigned i;
int ret;
@@ -582,23 +674,27 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
+ ret = ni_65xx_mite_init(pcidev);
+ if (ret)
+ return ret;
- devpriv->mite = mite_alloc(pcidev);
- if (!devpriv->mite)
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
return -ENOMEM;
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
- return ret;
+ writeb(NI_65XX_CLR_EDGE_INT | NI_65XX_CLR_OVERFLOW_INT,
+ dev->mmio + NI_65XX_CLR_REG);
+ writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
+
+ if (pcidev->irq) {
+ ret = request_irq(pcidev->irq, ni_65xx_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
+ if (ret == 0)
+ dev->irq = pcidev->irq;
}
- 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));
+ readb(dev->mmio + NI_65XX_ID_REG));
ret = comedi_alloc_subdevices(dev, 4);
if (ret)
@@ -606,130 +702,111 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[0];
if (board->num_di_ports) {
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE;
- s->n_chan =
- 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;
- s->insn_bits = ni_65xx_dio_insn_bits;
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
- spriv->base_port = 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_di_ports);
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->insn_config = ni_65xx_dio_insn_config;
+
+ /* the input ports always start at port 0 */
+ s->private = (void *)0;
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[1];
if (board->num_do_ports) {
- s->type = COMEDI_SUBD_DO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan =
- 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;
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
- spriv->base_port = board->num_di_ports;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_do_ports);
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+
+ /* the output ports always start after the input ports */
+ s->private = (void *)(unsigned long)board->num_di_ports;
+
+ /*
+ * Use the io_bits to handle the inverted outputs. Inverted
+ * outputs are only supported if the "legacy_invert_outputs"
+ * module parameter is set to "true".
+ */
+ if (ni_65xx_legacy_invert_outputs && board->legacy_invert)
+ s->io_bits = 0xff;
+
+ /* reset all output ports to comedi '0' */
+ for (i = 0; i < board->num_do_ports; ++i) {
+ writeb(s->io_bits, /* inverted if necessary */
+ dev->mmio +
+ NI_65XX_IO_DATA_REG(board->num_di_ports + i));
+ }
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[2];
if (board->num_dio_ports) {
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan =
- 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;
- s->insn_bits = ni_65xx_dio_insn_bits;
- spriv = comedi_alloc_spriv(s, sizeof(*spriv));
- if (!spriv)
- return -ENOMEM;
- spriv->base_port = 0;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = NI_65XX_PORT_TO_CHAN(board->num_dio_ports);
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->insn_config = ni_65xx_dio_insn_config;
+
+ /* the input/output ports always start at port 0 */
+ s->private = (void *)0;
+
+ /* configure all ports for input */
for (i = 0; i < board->num_dio_ports; ++i) {
- /* configure all ports for input */
- writeb(0x1,
- devpriv->mite->daq_io_addr +
- Port_Select(i));
+ writeb(NI_65XX_IO_SEL_INPUT,
+ dev->mmio + NI_65XX_IO_SEL_REG(i));
}
} else {
- s->type = COMEDI_SUBD_UNUSED;
+ s->type = COMEDI_SUBD_UNUSED;
}
s = &dev->subdevices[3];
- dev->read_subdev = s;
- s->type = COMEDI_SUBD_DI;
- s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
- s->n_chan = 1;
- s->range_table = &range_unknown;
- s->maxdata = 1;
- s->len_chanlist = 1;
- s->do_cmdtest = ni_65xx_intr_cmdtest;
- s->do_cmd = ni_65xx_intr_cmd;
- s->cancel = ni_65xx_intr_cancel;
- 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); ++i) {
- writeb(0x00,
- devpriv->mite->daq_io_addr + Filter_Enable(i));
- if (board->invert_outputs)
- writeb(0x01,
- devpriv->mite->daq_io_addr + Port_Data(i));
- else
- writeb(0x00,
- devpriv->mite->daq_io_addr + Port_Data(i));
- }
- writeb(ClrEdge | ClrOverflow,
- devpriv->mite->daq_io_addr + Clear_Register);
- writeb(0x00,
- devpriv->mite->daq_io_addr + Master_Interrupt_Control);
-
- /* Set filter interval to 0 (32bit reg) */
- writeb(0x00000000, devpriv->mite->daq_io_addr + Filter_Interval);
-
- ret = request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED,
- "ni_65xx", dev);
- if (ret < 0) {
- dev->irq = 0;
- dev_warn(dev->class_dev, "irq not available\n");
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_65xx_intr_insn_bits;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = 1;
+ s->insn_config = ni_65xx_intr_insn_config;
+ s->do_cmdtest = ni_65xx_intr_cmdtest;
+ s->do_cmd = ni_65xx_intr_cmd;
+ s->cancel = ni_65xx_intr_cancel;
}
+ ni_65xx_disable_input_filters(dev);
+ ni_65xx_disable_edge_detection(dev);
+
return 0;
}
static void ni_65xx_detach(struct comedi_device *dev)
{
- struct ni_65xx_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
- writeb(0x00,
- devpriv->mite->daq_io_addr +
- Master_Interrupt_Control);
+ if (dev->mmio) {
+ writeb(0x00, dev->mmio + NI_65XX_CTRL_REG);
+ iounmap(dev->mmio);
}
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv) {
- if (devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
- }
comedi_pci_disable(dev);
}
static struct comedi_driver ni_65xx_driver = {
- .driver_name = "ni_65xx",
- .module = THIS_MODULE,
- .auto_attach = ni_65xx_auto_attach,
- .detach = ni_65xx_detach,
+ .driver_name = "ni_65xx",
+ .module = THIS_MODULE,
+ .auto_attach = ni_65xx_auto_attach,
+ .detach = ni_65xx_detach,
};
static int ni_65xx_pci_probe(struct pci_dev *dev,
@@ -774,5 +851,5 @@ static struct pci_driver ni_65xx_pci_driver = {
module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for NI PCI-65xx static dio boards");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index 634cde83a02b..b0b03d4d6081 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -28,7 +28,7 @@
*
* 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)
@@ -161,6 +161,7 @@ enum ni_660x_register {
static inline unsigned IOConfigReg(unsigned pfi_channel)
{
unsigned reg = NI660X_IO_CFG_0_1 + pfi_channel / 2;
+
BUG_ON(reg > NI660X_IO_CFG_38_39);
return reg;
}
@@ -310,10 +311,7 @@ enum clock_config_register_bits {
/* ioconfigreg */
static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
{
- if (pfi_channel % 2)
- return 0;
- else
- return 8;
+ return (pfi_channel % 2) ? 0 : 8;
}
static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
@@ -589,17 +587,14 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
unsigned chip, unsigned bits,
enum ni_660x_register reg)
{
- struct ni_660x_private *devpriv = dev->private;
- void __iomem *write_address =
- devpriv->mite->daq_io_addr + GPCT_OFFSET[chip] +
- registerData[reg].offset;
+ unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset;
switch (registerData[reg].size) {
case DATA_2B:
- writew(bits, write_address);
+ writew(bits, dev->mmio + addr);
break;
case DATA_4B:
- writel(bits, write_address);
+ writel(bits, dev->mmio + addr);
break;
default:
BUG();
@@ -611,18 +606,13 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
unsigned chip,
enum ni_660x_register reg)
{
- struct ni_660x_private *devpriv = dev->private;
- void __iomem *read_address =
- devpriv->mite->daq_io_addr + GPCT_OFFSET[chip] +
- registerData[reg].offset;
+ unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset;
switch (registerData[reg].size) {
case DATA_2B:
- return readw(read_address);
- break;
+ return readw(dev->mmio + addr);
case DATA_4B:
- return readl(read_address);
- break;
+ return readl(dev->mmio + addr);
default:
BUG();
break;
@@ -714,8 +704,8 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
mite_ring(devpriv, counter));
if (mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for counter.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for counter\n");
return -EBUSY;
}
mite_chan->dir = direction;
@@ -749,11 +739,11 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
if (retval) {
- comedi_error(dev,
- "no dma channel available for use by counter");
+ dev_err(dev->class_dev,
+ "no dma channel available for use by counter\n");
return retval;
}
- ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+ ni_tio_acknowledge(counter);
return ni_tio_cmd(dev, s);
}
@@ -829,8 +819,7 @@ static int ni_660x_input_poll(struct comedi_device *dev,
}
static int ni_660x_buf_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size)
+ struct comedi_subdevice *s)
{
struct ni_660x_private *devpriv = dev->private;
struct ni_gpct *counter = s->private;
@@ -1083,11 +1072,9 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
if (!devpriv->mite)
return -ENOMEM;
- ret = mite_setup2(devpriv->mite, 1);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
+ ret = mite_setup2(dev, devpriv->mite, true);
+ if (ret < 0)
return ret;
- }
ret = ni_660x_alloc_mite_rings(dev);
if (ret < 0)
@@ -1126,9 +1113,8 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
if (i < ni_660x_num_counters(dev)) {
s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags =
- SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
- SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
+ SDF_LSAMPL | SDF_CMD_READ;
s->n_chan = 3;
s->maxdata = 0xffffffff;
s->insn_read = ni_tio_insn_read;
@@ -1170,13 +1156,13 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
for (i = 0; i < board->n_chips; ++i)
set_tio_counterswap(dev, i);
- ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt,
- IRQF_SHARED, "ni_660x", dev);
+ ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
+ dev->board_name, dev);
if (ret < 0) {
dev_warn(dev->class_dev, " irq not available\n");
return ret;
}
- dev->irq = mite_irq(devpriv->mite);
+ dev->irq = pcidev->irq;
global_interrupt_config_bits = Global_Int_Enable_Bit;
if (board->n_chips > 1)
global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
@@ -1195,12 +1181,11 @@ static void ni_660x_detach(struct comedi_device *dev)
if (devpriv) {
if (devpriv->counter_dev)
ni_gpct_device_destroy(devpriv->counter_dev);
- if (devpriv->mite) {
- ni_660x_free_mite_rings(dev);
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ ni_660x_free_mite_rings(dev);
+ mite_detach(devpriv->mite);
}
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 1002ceacfdcc..f5caefad0b59 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -39,11 +39,10 @@ Commands are not supported.
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include "../comedidev.h"
-#include "mite.h"
-
#define AO_VALUE_OFFSET 0x00
#define AO_CHAN_OFFSET 0x0c
#define AO_STATUS_OFFSET 0x10
@@ -82,8 +81,6 @@ static const struct ni_670x_board ni_670x_boards[] = {
};
struct ni_670x_private {
-
- struct mite_struct *mite;
int boardtype;
int dio;
unsigned int ao_readback[32];
@@ -111,9 +108,9 @@ static int ni_670x_ao_winsn(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) {
/* First write in channel register which channel to use */
writel(((chan & 15) << 1) | ((chan & 16) >> 4),
- devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);
+ dev->mmio + AO_CHAN_OFFSET);
/* write channel value */
- writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);
+ writel(data[i], dev->mmio + AO_VALUE_OFFSET);
devpriv->ao_readback[chan] = data[i];
}
@@ -139,14 +136,10 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_670x_private *devpriv = dev->private;
- void __iomem *io_addr = devpriv->mite->daq_io_addr +
- DIO_PORT0_DATA_OFFSET;
-
if (comedi_dio_update_state(s, data))
- writel(s->state, io_addr);
+ writel(s->state, dev->mmio + DIO_PORT0_DATA_OFFSET);
- data[1] = readl(io_addr);
+ data[1] = readl(dev->mmio + DIO_PORT0_DATA_OFFSET);
return insn->n;
}
@@ -156,18 +149,40 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_670x_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
+ writel(s->io_bits, dev->mmio + DIO_PORT0_DIR_OFFSET);
return insn->n;
}
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
+
+static int ni_670x_mite_init(struct pci_dev *pcidev)
+{
+ void __iomem *mite_base;
+ u32 main_phys_addr;
+
+ /* ioremap the MITE registers (BAR 0) temporarily */
+ mite_base = pci_ioremap_bar(pcidev, 0);
+ if (!mite_base)
+ return -ENOMEM;
+
+ /* set data window to main registers (BAR 1) */
+ main_phys_addr = pci_resource_start(pcidev, 1);
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
+
+ /* finished with MITE registers */
+ iounmap(mite_base);
+ return 0;
+}
+
static int ni_670x_auto_attach(struct comedi_device *dev,
unsigned long context)
{
@@ -193,15 +208,13 @@ static int ni_670x_auto_attach(struct comedi_device *dev,
if (!devpriv)
return -ENOMEM;
- devpriv->mite = mite_alloc(pcidev);
- if (!devpriv->mite)
- return -ENOMEM;
-
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
+ ret = ni_670x_mite_init(pcidev);
+ if (ret)
return ret;
- }
+
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
+ return -ENOMEM;
ret = comedi_alloc_subdevices(dev, 2);
if (ret)
@@ -242,16 +255,15 @@ static int ni_670x_auto_attach(struct comedi_device *dev,
s->insn_config = ni_670x_dio_insn_config;
/* Config of misc registers */
- writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);
+ writel(0x10, dev->mmio + MISC_CONTROL_OFFSET);
/* Config of ao registers */
- writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);
+ writel(0x00, dev->mmio + AO_CONTROL_OFFSET);
return 0;
}
static void ni_670x_detach(struct comedi_device *dev)
{
- struct ni_670x_private *devpriv = dev->private;
struct comedi_subdevice *s;
if (dev->n_subdevices) {
@@ -259,10 +271,8 @@ static void ni_670x_detach(struct comedi_device *dev)
if (s)
kfree(s->range_table_list);
}
- if (devpriv && devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 5bd19494dbf6..de67161f6185 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -71,7 +71,6 @@ TRIG_WAKE_EOS
#include "8253.h"
#include "comedi_fc.h"
-#define A2150_SIZE 28
#define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
/* Registers and bits */
@@ -156,13 +155,6 @@ struct a2150_private {
int config_bits; /* config register bits */
};
-static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-
-static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
- int flags);
-static int a2150_set_chanlist(struct comedi_device *dev,
- unsigned int start_channel,
- unsigned int num_channels);
/* interrupt service routine */
static irqreturn_t a2150_interrupt(int irq, void *d)
{
@@ -179,7 +171,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
static const int sample_size = sizeof(devpriv->dma_buffer[0]);
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
/* initialize async here to make sure s is not NULL */
@@ -189,18 +181,19 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
status = inw(dev->iobase + STATUS_REG);
if ((status & INTR_BIT) == 0) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_NONE;
}
if (status & OVFL_BIT) {
- comedi_error(dev, "fifo overflow");
+ dev_err(dev->class_dev, "fifo overflow\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
}
if ((status & DMA_TC_BIT) == 0) {
- comedi_error(dev, "caught non-dma interrupt? Aborting.");
+ dev_err(dev->class_dev,
+ "caught non-dma interrupt? Aborting.\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
return IRQ_HANDLED;
@@ -287,6 +280,117 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
+/*
+ * sets bits in devpriv->clock_bits to nearest approximation of requested
+ * period, adjusts requested period to actual timing.
+ */
+static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
+ unsigned 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;
+ int i, j;
+
+ /* initialize greatest lower and least upper bounds */
+ lub_divisor_shift = 3;
+ lub_index = 0;
+ lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
+ glb_divisor_shift = 0;
+ glb_index = thisboard->num_clocks - 1;
+ glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
+
+ /* make sure period is in available range */
+ if (*period < glb)
+ *period = glb;
+ if (*period > lub)
+ *period = lub;
+
+ /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
+ for (i = 0; i < 4; i++) {
+ /* there are a maximum of 4 master clocks */
+ for (j = 0; j < thisboard->num_clocks; j++) {
+ /* temp is the period in nanosec we are evaluating */
+ temp = thisboard->clock[j] * (1 << i);
+ /* if it is the best match yet */
+ if (temp < lub && temp >= *period) {
+ lub_divisor_shift = i;
+ lub_index = j;
+ lub = temp;
+ }
+ if (temp > glb && temp <= *period) {
+ glb_divisor_shift = i;
+ glb_index = j;
+ glb = temp;
+ }
+ }
+ }
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ /* if least upper bound is better approximation */
+ if (lub - *period < *period - glb)
+ *period = lub;
+ else
+ *period = glb;
+ break;
+ case TRIG_ROUND_UP:
+ *period = lub;
+ break;
+ case TRIG_ROUND_DOWN:
+ *period = glb;
+ break;
+ }
+
+ /* set clock bits for config register appropriately */
+ devpriv->config_bits &= ~CLOCK_MASK;
+ if (*period == lub) {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(lub_index) |
+ CLOCK_DIVISOR_BITS(lub_divisor_shift);
+ } else {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(glb_index) |
+ CLOCK_DIVISOR_BITS(glb_divisor_shift);
+ }
+
+ return 0;
+}
+
+static int a2150_set_chanlist(struct comedi_device *dev,
+ unsigned int start_channel,
+ unsigned int num_channels)
+{
+ struct a2150_private *devpriv = dev->private;
+
+ if (start_channel + num_channels > 4)
+ return -1;
+
+ devpriv->config_bits &= ~CHANNEL_MASK;
+
+ switch (num_channels) {
+ case 1:
+ devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
+ break;
+ case 2:
+ if (start_channel == 0)
+ devpriv->config_bits |= CHANNEL_BITS(0x2);
+ else if (start_channel == 2)
+ devpriv->config_bits |= CHANNEL_BITS(0x3);
+ else
+ return -1;
+ break;
+ case 4:
+ devpriv->config_bits |= CHANNEL_BITS(0x1);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
static int a2150_ai_check_chanlist(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
@@ -408,8 +512,8 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned int trigger_bits;
if (cmd->flags & TRIG_RT) {
- comedi_error(dev,
- " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
+ dev_err(dev->class_dev,
+ "dma incompatible with hard real-time interrupt (TRIG_RT), aborting\n");
return -1;
}
/* clear fifo and reset triggering circuitry */
@@ -490,7 +594,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
trigger_bits |= HW_TRIG_EN;
} else if (cmd->start_src == TRIG_OTHER) {
/* XXX add support for level/slope start trigger using TRIG_OTHER */
- comedi_error(dev, "you shouldn't see this?");
+ dev_err(dev->class_dev, "you shouldn't see this?\n");
}
/* send trigger config bits */
outw(trigger_bits, dev->iobase + TRIGGER_REG);
@@ -574,123 +678,11 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
return n;
}
-/*
- * sets bits in devpriv->clock_bits to nearest approximation of requested
- * period, adjusts requested period to actual timing.
- */
-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;
- int i, j;
-
- /* initialize greatest lower and least upper bounds */
- lub_divisor_shift = 3;
- lub_index = 0;
- lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
- glb_divisor_shift = 0;
- glb_index = thisboard->num_clocks - 1;
- glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
-
- /* make sure period is in available range */
- if (*period < glb)
- *period = glb;
- if (*period > lub)
- *period = lub;
-
- /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
- for (i = 0; i < 4; i++) {
- /* there are a maximum of 4 master clocks */
- for (j = 0; j < thisboard->num_clocks; j++) {
- /* temp is the period in nanosec we are evaluating */
- temp = thisboard->clock[j] * (1 << i);
- /* if it is the best match yet */
- if (temp < lub && temp >= *period) {
- lub_divisor_shift = i;
- lub_index = j;
- lub = temp;
- }
- if (temp > glb && temp <= *period) {
- glb_divisor_shift = i;
- glb_index = j;
- glb = temp;
- }
- }
- }
- flags &= TRIG_ROUND_MASK;
- switch (flags) {
- case TRIG_ROUND_NEAREST:
- default:
- /* if least upper bound is better approximation */
- if (lub - *period < *period - glb)
- *period = lub;
- else
- *period = glb;
- break;
- case TRIG_ROUND_UP:
- *period = lub;
- break;
- case TRIG_ROUND_DOWN:
- *period = glb;
- break;
- }
-
- /* set clock bits for config register appropriately */
- devpriv->config_bits &= ~CLOCK_MASK;
- if (*period == lub) {
- devpriv->config_bits |=
- CLOCK_SELECT_BITS(lub_index) |
- CLOCK_DIVISOR_BITS(lub_divisor_shift);
- } else {
- devpriv->config_bits |=
- CLOCK_SELECT_BITS(glb_index) |
- CLOCK_DIVISOR_BITS(glb_divisor_shift);
- }
-
- return 0;
-}
-
-static int a2150_set_chanlist(struct comedi_device *dev,
- unsigned int start_channel,
- unsigned int num_channels)
-{
- struct a2150_private *devpriv = dev->private;
-
- if (start_channel + num_channels > 4)
- return -1;
-
- devpriv->config_bits &= ~CHANNEL_MASK;
-
- switch (num_channels) {
- case 1:
- devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
- break;
- case 2:
- if (start_channel == 0)
- devpriv->config_bits |= CHANNEL_BITS(0x2);
- else if (start_channel == 2)
- devpriv->config_bits |= CHANNEL_BITS(0x3);
- else
- return -1;
- break;
- case 4:
- devpriv->config_bits |= CHANNEL_BITS(0x1);
- break;
- default:
- return -1;
- break;
- }
-
- return 0;
-}
-
/* probes board type, returns offset */
static int a2150_probe(struct comedi_device *dev)
{
int status = inw(dev->iobase + STATUS_REG);
+
return ID_BITS(status);
}
@@ -709,7 +701,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], A2150_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x1c);
if (ret)
return ret;
@@ -784,8 +776,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
udelay(1000);
}
if (i == timeout) {
- printk
- (" timed out waiting for offset calibration to complete\n");
+ dev_err(dev->class_dev,
+ "timed out waiting for offset calibration to complete\n");
return -ETIME;
}
devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index d03935257b97..2bd9f692a7ae 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -98,233 +98,135 @@ are not supported.
#include "ni_stc.h"
#include "8255.h"
-#define ATMIO 1
-#undef PCIMIO
-
/*
* AT specific setup
*/
-#define NI_SIZE 0x20
-
-#define MAX_N_CALDACS 32
-
static const struct ni_board_struct ni_boards[] = {
- {.device_id = 44,
- .isapnp_id = 0x0000, /* XXX unknown */
- .name = "at-mio-16e-1",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 8192,
- .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,
- .has_8255 = 0,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341},
- },
- {.device_id = 25,
- .isapnp_id = 0x1900,
- .name = "at-mio-16e-2",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 2048,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .has_8255 = 0,
- .num_p0_dio_channels = 8,
- .caldac = {mb88341},
- },
- {.device_id = 36,
- .isapnp_id = 0x2400,
- .name = "at-mio-16e-10",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 0,
- },
- {.device_id = 37,
- .isapnp_id = 0x2500,
- .name = "at-mio-16de-10",
- .n_adchan = 16,
- .adbits = 12,
- .ai_fifo_depth = 512,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 10000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 0,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 10000,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- .has_8255 = 1,
- },
- {.device_id = 38,
- .isapnp_id = 0x2600,
- .name = "at-mio-64e-3",
- .n_adchan = 64,
- .adbits = 12,
- .ai_fifo_depth = 2048,
- .alwaysdither = 0,
- .gainlkup = ai_gain_16,
- .ai_speed = 2000,
- .n_aochan = 2,
- .aobits = 12,
- .ao_fifo_depth = 2048,
- .ao_range_table = &range_ni_E_ao_ext,
- .ao_unipolar = 1,
- .ao_speed = 1000,
- .has_8255 = 0,
- .num_p0_dio_channels = 8,
- .caldac = {ad8804_debug},
- },
- {.device_id = 39,
- .isapnp_id = 0x2700,
- .name = "at-mio-16xe-50",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .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 = 50,
- .isapnp_id = 0x0000, /* XXX unknown */
- .name = "at-mio-16xe-10",
- .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 = 1000,
- .num_p0_dio_channels = 8,
- .caldac = {dac8800, dac8043, ad8522},
- .has_8255 = 0,
- },
- {.device_id = 51,
- .isapnp_id = 0x0000, /* XXX unknown */
- .name = "at-ai-16xe-10",
- .n_adchan = 16,
- .adbits = 16,
- .ai_fifo_depth = 512,
- .alwaysdither = 1, /* unknown */
- .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,
- }
+ {
+ .name = "at-mio-16e-1",
+ .device_id = 44,
+ .isapnp_id = 0x0000, /* XXX unknown */
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 8192,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { mb88341 },
+ }, {
+ .name = "at-mio-16e-2",
+ .device_id = 25,
+ .isapnp_id = 0x1900,
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 2048,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { mb88341 },
+ }, {
+ .name = "at-mio-16e-10",
+ .device_id = 36,
+ .isapnp_id = 0x2400,
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 10000,
+ .caldac = { ad8804_debug },
+ }, {
+ .name = "at-mio-16de-10",
+ .device_id = 37,
+ .isapnp_id = 0x2500,
+ .n_adchan = 16,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 512,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 10000,
+ .caldac = { ad8804_debug },
+ .has_8255 = 1,
+ }, {
+ .name = "at-mio-64e-3",
+ .device_id = 38,
+ .isapnp_id = 0x2600,
+ .n_adchan = 64,
+ .ai_maxdata = 0x0fff,
+ .ai_fifo_depth = 2048,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { ad8804_debug },
+ }, {
+ .name = "at-mio-16xe-50",
+ .device_id = 39,
+ .isapnp_id = 0x2700,
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_8,
+ .ai_speed = 50000,
+ .n_aochan = 2,
+ .ao_maxdata = 0x0fff,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 50000,
+ .caldac = { dac8800, dac8043 },
+ }, {
+ .name = "at-mio-16xe-10",
+ .device_id = 50,
+ .isapnp_id = 0x0000, /* XXX unknown */
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 1000,
+ .caldac = { dac8800, dac8043, ad8522 },
+ }, {
+ .name = "at-ai-16xe-10",
+ .device_id = 51,
+ .isapnp_id = 0x0000, /* XXX unknown */
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1, /* unknown */
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .caldac = { dac8800, dac8043, ad8522 },
+ },
};
static const int ni_irqpin[] = {
-1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7
};
-#define interrupt_pin(a) (ni_irqpin[(a)])
-
-#define IRQ_POLARITY 0
-
-#define NI_E_IRQ_FLAGS 0
-
-struct ni_private {
- struct pnp_dev *isapnp_dev;
- NI_PRIVATE_COMMON
-
-};
-
-/* How we access registers */
-
-#define ni_writel(a, b) (outl((a), (b)+dev->iobase))
-#define ni_readl(a) (inl((a)+dev->iobase))
-#define ni_writew(a, b) (outw((a), (b)+dev->iobase))
-#define ni_readw(a) (inw((a)+dev->iobase))
-#define ni_writeb(a, b) (outb((a), (b)+dev->iobase))
-#define ni_readb(a) (inb((a)+dev->iobase))
-
-/* How we access windowed registers */
-
-/* We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board. The
- * AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
-
-static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if ((addr) < 8) {
- ni_writew(data, addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ni_writew(data, Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-}
-
-static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
- uint16_t ret;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (addr < 8) {
- ret = ni_readw(addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ret = ni_readw(Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-
- return ret;
-}
+#include "ni_mio_common.c"
static struct pnp_device_id device_ids[] = {
{.id = "NIC1900", .driver_data = 0},
@@ -337,8 +239,6 @@ static struct pnp_device_id device_ids[] = {
MODULE_DEVICE_TABLE(pnp, device_ids);
-#include "ni_mio_common.c"
-
static int ni_isapnp_find_board(struct pnp_dev **dev)
{
struct pnp_dev *isapnp_dev = NULL;
@@ -353,20 +253,17 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
if (isapnp_dev == NULL || isapnp_dev->card == NULL)
continue;
- if (pnp_device_attach(isapnp_dev) < 0) {
- printk
- ("ni_atmio: %s found but already active, skipping.\n",
- ni_boards[i].name);
+ if (pnp_device_attach(isapnp_dev) < 0)
continue;
- }
+
if (pnp_activate_dev(isapnp_dev) < 0) {
pnp_device_detach(isapnp_dev);
return -EAGAIN;
}
- if (!pnp_port_valid(isapnp_dev, 0)
- || !pnp_irq_valid(isapnp_dev, 0)) {
+
+ if (!pnp_port_valid(isapnp_dev, 0) ||
+ !pnp_irq_valid(isapnp_dev, 0)) {
pnp_device_detach(isapnp_dev);
- printk("ni_atmio: pnp invalid port or irq, aborting\n");
return -ENOMEM;
}
break;
@@ -388,11 +285,13 @@ static int ni_getboardtype(struct comedi_device *dev)
}
if (device_id == 255)
- printk(" can't find board\n");
+ dev_err(dev->class_dev, "can't find board\n");
else if (device_id == 0)
- printk(" EEPROM read error (?) or device not found\n");
+ dev_err(dev->class_dev,
+ "EEPROM read error (?) or device not found\n");
else
- printk(" unknown device ID %d -- contact author\n", device_id);
+ dev_err(dev->class_dev,
+ "unknown device ID %d -- contact author\n", device_id);
return -1;
}
@@ -413,11 +312,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
return ret;
devpriv = dev->private;
- devpriv->stc_writew = &ni_atmio_win_out;
- devpriv->stc_readw = &ni_atmio_win_in;
- devpriv->stc_writel = &win_out2;
- devpriv->stc_readl = &win_in2;
-
iobase = it->options[0];
irq = it->options[1];
isapnp_dev = NULL;
@@ -428,10 +322,10 @@ static int ni_atmio_attach(struct comedi_device *dev,
iobase = pnp_port_start(isapnp_dev, 0);
irq = pnp_irq(isapnp_dev, 0);
- devpriv->isapnp_dev = isapnp_dev;
+ comedi_set_hw_dev(dev, &isapnp_dev->dev);
}
- ret = comedi_request_region(dev, iobase, NI_SIZE);
+ ret = comedi_request_region(dev, iobase, 0x20);
if (ret)
return ret;
@@ -443,31 +337,23 @@ static int ni_atmio_attach(struct comedi_device *dev,
dev->board_ptr = ni_boards + board;
boardtype = comedi_board(dev);
-
- printk(" %s", boardtype->name);
dev->board_name = boardtype->name;
/* irq stuff */
if (irq != 0) {
- if (irq > 15 || ni_irqpin[irq] == -1) {
- printk(" invalid irq %u\n", irq);
+ if (irq > 15 || ni_irqpin[irq] == -1)
return -EINVAL;
- }
- printk(" ( irq = %u )", irq);
- ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
- "ni_atmio", dev);
-
- if (ret < 0) {
- printk(" irq not available\n");
+ ret = request_irq(irq, ni_E_interrupt, 0,
+ dev->board_name, dev);
+ if (ret < 0)
return -EINVAL;
- }
dev->irq = irq;
}
/* generic E series stuff in ni_mio_common.c */
- ret = ni_E_init(dev);
+ ret = ni_E_init(dev, ni_irqpin[dev->irq], 0);
if (ret < 0)
return ret;
@@ -477,12 +363,14 @@ static int ni_atmio_attach(struct comedi_device *dev,
static void ni_atmio_detach(struct comedi_device *dev)
{
- struct ni_private *devpriv = dev->private;
+ struct pnp_dev *isapnp_dev;
mio_common_detach(dev);
comedi_legacy_detach(dev);
- if (devpriv->isapnp_dev)
- pnp_device_detach(devpriv->isapnp_dev);
+
+ isapnp_dev = dev->hw_dev ? to_pnp_dev(dev->hw_dev) : NULL;
+ if (isapnp_dev)
+ pnp_device_detach(isapnp_dev);
}
static struct comedi_driver ni_atmio_driver = {
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index 6ad27f50c6ec..9c08da9508f4 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -94,8 +94,6 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
#define CLOCK_10_KHZ 0x8D25
#define CLOCK_1_KHZ 0x8E25
#define CLOCK_100_HZ 0x8F25
-/* Other miscellaneous defines */
-#define ATMIO16D_SIZE 32 /* bus address range */
struct atmio16_board_t {
@@ -335,12 +333,9 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
} else if (cmd->convert_arg < 655360000) {
base_clock = CLOCK_100_KHZ;
timer = cmd->convert_arg / 10000;
- } else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */) {
+ } else /* cmd->convert_arg < 6553600000 */ {
base_clock = CLOCK_10_KHZ;
timer = cmd->convert_arg / 100000;
- } else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */) {
- base_clock = CLOCK_1_KHZ;
- timer = cmd->convert_arg / 1000000;
}
outw(0xFF03, dev->iobase + AM9513A_COM_REG);
outw(base_clock, dev->iobase + AM9513A_DATA_REG);
@@ -403,12 +398,9 @@ static int atmio16d_ai_cmd(struct comedi_device *dev,
} else if (cmd->scan_begin_arg < 655360000) {
base_clock = CLOCK_100_KHZ;
timer = cmd->scan_begin_arg / 10000;
- } else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */) {
+ } else /* cmd->scan_begin_arg < 6553600000 */ {
base_clock = CLOCK_10_KHZ;
timer = cmd->scan_begin_arg / 100000;
- } else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */) {
- base_clock = CLOCK_1_KHZ;
- timer = cmd->scan_begin_arg / 1000000;
}
outw(0xFF02, dev->iobase + AM9513A_COM_REG);
outw(base_clock, dev->iobase + AM9513A_DATA_REG);
@@ -630,7 +622,7 @@ static int atmio16d_attach(struct comedi_device *dev,
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], ATMIO16D_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x20);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 728bf7f14f7b..5e472cb7fbd7 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -18,32 +18,34 @@
*/
/*
-Driver: ni_daq_700
-Description: National Instruments PCMCIA DAQCard-700 DIO only
-Author: Fred Brooks <nsaspook@nsaspook.com>,
- based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
-Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
-Status: works
-Updated: Wed, 19 Sep 2012 12:07:20 +0000
-
-The daqcard-700 appears in Comedi as a digital I/O subdevice (0) with
-16 channels and a analog input subdevice (1) with 16 single-ended channels.
-
-Digital: The channel 0 corresponds to the daqcard-700's output
-port, bit 0; channel 8 corresponds to the input port, bit 0.
-
-Digital direction configuration: channels 0-7 output, 8-15 input (8225 device
-emu as port A output, port B input, port C N/A).
-
-Analog: The input range is 0 to 4095 for -10 to +10 volts
-IRQ is assigned but not used.
-
-Version 0.1 Original DIO only driver
-Version 0.2 DIO and basic AI analog input support on 16 se channels
-
-Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf
- User Manual: http://www.ni.com/pdf/manuals/320676d.pdf
-*/
+ * Driver: ni_daq_700
+ * Description: National Instruments PCMCIA DAQCard-700
+ * Author: Fred Brooks <nsaspook@nsaspook.com>,
+ * based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
+ * Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
+ * Status: works
+ * Updated: Wed, 21 May 2014 12:07:20 +0000
+ *
+ * The daqcard-700 appears in Comedi as a digital I/O subdevice (0) with
+ * 16 channels and a analog input subdevice (1) with 16 single-ended channels
+ * or 8 differential channels, and three input ranges.
+ *
+ * Digital: The channel 0 corresponds to the daqcard-700's output
+ * port, bit 0; channel 8 corresponds to the input port, bit 0.
+ *
+ * Digital direction configuration: channels 0-7 output, 8-15 input.
+ *
+ * Analog: The input range is 0 to 4095 with a default of -10 to +10 volts.
+ * Valid ranges:
+ * 0 for -10 to 10V bipolar
+ * 1 for -5 to 5V bipolar
+ * 2 for -2.5 to 2.5V bipolar
+ *
+ * IRQ is assigned but not used.
+ *
+ * Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf
+ * User Manual: http://www.ni.com/pdf/manuals/320676d.pdf
+ */
#include <linux/module.h>
#include <linux/delay.h>
@@ -69,6 +71,17 @@ Manuals: Register level: http://www.ni.com/pdf/manuals/340698.pdf
#define CDA_R2 0x0A /* RW 8bit */
#define CMO_R 0x0B /* RO 8bit */
#define TIC_R 0x06 /* WO 8bit */
+/* daqcard700 modes */
+#define CMD_R3_DIFF 0x04 /* diff mode */
+
+static const struct comedi_lrange range_daq700_ai = {
+ 3,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5)
+ }
+};
static int daq700_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
@@ -131,11 +144,22 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- int n, chan;
+ int n;
int d;
int ret;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int aref = CR_AREF(insn->chanspec);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ unsigned int r3_bits = 0;
+
+ /* set channel input modes */
+ if (aref == AREF_DIFF)
+ r3_bits |= CMD_R3_DIFF;
+ /* write channel mode/range */
+ if (range >= 1)
+ range++; /* convert range to hardware value */
+ outb(r3_bits | (range & 0x03), dev->iobase + CMD_R3);
- chan = CR_CHAN(insn->chanspec);
/* write channel to multiplexer */
/* set mask scan bit high to disable scanning */
outb(chan | 0x80, dev->iobase + CMD_R1);
@@ -147,6 +171,9 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
/* trigger conversion with out0 L to H */
outb(0x00, dev->iobase + CMD_R2); /* enable ADC conversions */
outb(0x30, dev->iobase + CMO_R); /* mode 0 out0 L, from H */
+ outb(0x00, dev->iobase + ADCLEAR_R); /* clear the ADC FIFO */
+ /* read 16bit junk from FIFO to clear */
+ inw(dev->iobase + ADFIFO_R);
/* mode 1 out0 H, L to H, start conversion */
outb(0x32, dev->iobase + CMO_R);
@@ -222,11 +249,10 @@ static int daq700_auto_attach(struct comedi_device *dev,
/* DAQCard-700 ai */
s = &dev->subdevices[1];
s->type = COMEDI_SUBD_AI;
- /* we support single-ended (ground) */
- s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
s->n_chan = 16;
s->maxdata = (1 << 12) - 1;
- s->range_table = &range_bipolar10;
+ s->range_table = &range_daq700_ai;
s->insn_read = daq700_ai_rinsn;
daq700_ai_config(dev, s);
@@ -263,5 +289,4 @@ module_comedi_pcmcia_driver(daq700_driver, daq700_cs_driver);
MODULE_AUTHOR("Fred Brooks <nsaspook@nsaspook.com>");
MODULE_DESCRIPTION(
"Comedi driver for National Instruments PCMCIA DAQCard-700 DIO/AI");
-MODULE_VERSION("0.2.00");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 3e3f940fa57c..126d65cb39f2 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -72,8 +72,6 @@
#include "ni_labpc_regs.h"
#include "ni_labpc_isadma.h"
-#define LABPC_SIZE 0x20 /* size of ISA io region */
-
enum scan_mode {
MODE_SINGLE_CHAN,
MODE_SINGLE_CHAN_INTERVAL,
@@ -130,24 +128,26 @@ static const struct comedi_lrange range_labpc_ao = {
/* functions that do inb/outb and readb/writeb so we can use
* function pointers to decide which to use */
-static inline unsigned int labpc_inb(unsigned long address)
+static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg)
{
- return inb(address);
+ return inb(dev->iobase + reg);
}
-static inline void labpc_outb(unsigned int byte, unsigned long address)
+static void labpc_outb(struct comedi_device *dev,
+ unsigned int byte, unsigned long reg)
{
- outb(byte, address);
+ outb(byte, dev->iobase + reg);
}
-static inline unsigned int labpc_readb(unsigned long address)
+static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg)
{
- return readb((void __iomem *)address);
+ return readb(dev->mmio + reg);
}
-static inline void labpc_writeb(unsigned int byte, unsigned long address)
+static void labpc_writeb(struct comedi_device *dev,
+ unsigned int byte, unsigned long reg)
{
- writeb(byte, (void __iomem *)address);
+ writeb(byte, dev->mmio + reg);
}
#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISA)
@@ -172,38 +172,29 @@ static const struct labpc_boardinfo labpc_boards[] = {
#endif
static void labpc_counter_load(struct comedi_device *dev,
- unsigned long base_address,
+ unsigned long reg,
unsigned int counter_number,
unsigned int count,
unsigned int mode)
{
- const struct labpc_boardinfo *board = comedi_board(dev);
-
- if (board->has_mmio) {
- void __iomem *mmio_base = (void __iomem *)base_address;
-
- i8254_mm_set_mode(mmio_base, 0, counter_number, mode);
- i8254_mm_write(mmio_base, 0, counter_number, count);
+ if (dev->mmio) {
+ i8254_mm_set_mode(dev->mmio + reg, 0, counter_number, mode);
+ i8254_mm_write(dev->mmio + reg, 0, counter_number, count);
} else {
- i8254_set_mode(base_address, 0, counter_number, mode);
- i8254_write(base_address, 0, counter_number, count);
+ i8254_set_mode(dev->iobase + reg, 0, counter_number, mode);
+ i8254_write(dev->iobase + reg, 0, counter_number, count);
}
}
static void labpc_counter_set_mode(struct comedi_device *dev,
- unsigned long base_address,
+ unsigned long reg,
unsigned int counter_number,
unsigned int mode)
{
- const struct labpc_boardinfo *board = comedi_board(dev);
-
- if (board->has_mmio) {
- void __iomem *mmio_base = (void __iomem *)base_address;
-
- i8254_mm_set_mode(mmio_base, 0, counter_number, mode);
- } else {
- i8254_set_mode(base_address, 0, counter_number, mode);
- }
+ if (dev->mmio)
+ i8254_mm_set_mode(dev->mmio + reg, 0, counter_number, mode);
+ else
+ i8254_set_mode(dev->iobase + reg, 0, counter_number, mode);
}
static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -213,11 +204,11 @@ static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
spin_lock_irqsave(&dev->spinlock, flags);
devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
devpriv->cmd3 = 0;
- devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
+ devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
return 0;
}
@@ -247,7 +238,7 @@ static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
devpriv->cmd1 = CMD1_MA(chan);
devpriv->cmd1 |= CMD1_GAIN(range);
- devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
+ devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
}
static void labpc_setup_cmd6_reg(struct comedi_device *dev,
@@ -294,14 +285,14 @@ static void labpc_setup_cmd6_reg(struct comedi_device *dev,
else
devpriv->cmd6 &= ~CMD6_SCANUP;
- devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}
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);
+ unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG);
+ unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG);
return (msb << 8) | lsb;
}
@@ -310,7 +301,7 @@ 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);
+ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
labpc_read_adc_fifo(dev);
}
@@ -321,7 +312,7 @@ static int labpc_ai_eoc(struct comedi_device *dev,
{
struct labpc_private *devpriv = dev->private;
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
if (devpriv->stat1 & STAT1_DAVAIL)
return 0;
return -EBUSY;
@@ -353,17 +344,16 @@ static int labpc_ai_insn_read(struct comedi_device *dev,
/* single-ended/differential */
if (aref == AREF_DIFF)
devpriv->cmd4 |= CMD4_SEDIFF;
- devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+ devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
/* initialize pacer counter to prevent any problems */
- labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, I8254_MODE2);
+ labpc_counter_set_mode(dev, COUNTER_A_BASE_REG, 0, I8254_MODE2);
labpc_clear_adc_fifo(dev);
for (i = 0; i < insn->n; i++) {
/* trigger conversion */
- devpriv->write_byte(0x1, dev->iobase + ADC_START_CONVERT_REG);
+ devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG);
ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0);
if (ret)
@@ -531,24 +521,26 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
{
+ unsigned int chan0;
+ unsigned int chan1;
+
if (cmd->chanlist_len == 1)
return MODE_SINGLE_CHAN;
- /* chanlist may be NULL during cmdtest. */
+ /* chanlist may be NULL during cmdtest */
if (cmd->chanlist == NULL)
return MODE_MULT_CHAN_UP;
- if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
- return MODE_SINGLE_CHAN_INTERVAL;
+ chan0 = CR_CHAN(cmd->chanlist[0]);
+ chan1 = CR_CHAN(cmd->chanlist[1]);
- if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
+ if (chan0 < chan1)
return MODE_MULT_CHAN_UP;
- if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
+ if (chan0 > chan1)
return MODE_MULT_CHAN_DOWN;
- pr_err("ni_labpc: bug! cannot determine AI scan mode\n");
- return 0;
+ return MODE_SINGLE_CHAN_INTERVAL;
}
static int labpc_ai_check_chanlist(struct comedi_device *dev,
@@ -749,12 +741,11 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* load counter a1 with count of 3
* (pc+ manual says this is minimum allowed) using mode 0
*/
- labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ labpc_counter_load(dev, COUNTER_A_BASE_REG,
1, 3, I8254_MODE0);
} else {
/* just put counter a1 in mode 0 to set its output low */
- labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 1, I8254_MODE0);
+ labpc_counter_set_mode(dev, COUNTER_A_BASE_REG, 1, I8254_MODE0);
}
/* figure out what method we will use to transfer data */
@@ -786,37 +777,35 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* list will get screwed when you switch
* between scan up to scan down mode - dunno why */
udelay(1);
- devpriv->write_byte(devpriv->cmd1, dev->iobase + CMD1_REG);
+ devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
}
- devpriv->write_byte(cmd->chanlist_len,
- dev->iobase + INTERVAL_COUNT_REG);
+ devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
/* load count */
- devpriv->write_byte(0x1, dev->iobase + INTERVAL_STROBE_REG);
+ devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);
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 */
- labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ labpc_counter_load(dev, COUNTER_B_BASE_REG,
0, devpriv->divisor_b0, I8254_MODE3);
}
/* set up conversion pacing */
if (labpc_ai_convert_period(cmd, mode)) {
/* load counter a0 in mode 2 */
- labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ labpc_counter_load(dev, COUNTER_A_BASE_REG,
0, devpriv->divisor_a0, I8254_MODE2);
} else {
/* initialize pacer counter to prevent any problems */
- labpc_counter_set_mode(dev, dev->iobase + COUNTER_A_BASE_REG,
- 0, I8254_MODE2);
+ labpc_counter_set_mode(dev, COUNTER_A_BASE_REG, 0, I8254_MODE2);
}
/* set up scan pacing */
if (labpc_ai_scan_period(cmd, mode)) {
/* load counter b1 in mode 2 */
- labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ labpc_counter_load(dev, COUNTER_B_BASE_REG,
1, devpriv->divisor_b1, I8254_MODE2);
}
@@ -830,7 +819,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* enable fifo not empty interrupt? */
if (xfer == fifo_not_empty_transfer)
devpriv->cmd3 |= CMD3_FIFOINTEN;
- devpriv->write_byte(devpriv->cmd3, dev->iobase + CMD3_REG);
+ devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
/* setup any external triggering/pacing (cmd4 register) */
devpriv->cmd4 = 0;
@@ -846,7 +835,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* single-ended/differential */
if (aref == AREF_DIFF)
devpriv->cmd4 |= CMD4_SEDIFF;
- devpriv->write_byte(devpriv->cmd4, dev->iobase + CMD4_REG);
+ devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
/* startup acquisition */
@@ -863,7 +852,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (cmd->stop_src == TRIG_EXT)
devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -880,7 +869,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
const int timeout = 10000;
unsigned int i;
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
i++) {
@@ -892,10 +881,10 @@ static int labpc_drain_fifo(struct comedi_device *dev)
}
data = labpc_read_adc_fifo(dev);
cfc_write_to_buffer(dev->read_subdev, data);
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
}
if (i == timeout) {
- comedi_error(dev, "ai timeout, fifo never empties");
+ dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
return -1;
}
@@ -926,7 +915,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
struct comedi_cmd *cmd;
if (!dev->attached) {
- comedi_error(dev, "premature interrupt");
+ dev_err(dev->class_dev, "premature interrupt\n");
return IRQ_HANDLED;
}
@@ -934,9 +923,9 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
cmd = &async->cmd;
/* read board status */
- devpriv->stat1 = devpriv->read_byte(dev->iobase + STAT1_REG);
+ devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
if (board->is_labpc1200)
- devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
+ devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
STAT1_OVERRUN | STAT1_DAVAIL)) == 0
@@ -947,10 +936,10 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
if (devpriv->stat1 & STAT1_OVERRUN) {
/* clear error interrupt */
- devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
- comedi_error(dev, "overrun");
+ dev_err(dev->class_dev, "overrun\n");
return IRQ_HANDLED;
}
@@ -960,17 +949,17 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
labpc_drain_fifo(dev);
if (devpriv->stat1 & STAT1_CNTINT) {
- comedi_error(dev, "handled timer interrupt?");
+ dev_err(dev->class_dev, "handled timer interrupt?\n");
/* clear it */
- devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
}
if (devpriv->stat1 & STAT1_OVERFLOW) {
/* clear error interrupt */
- devpriv->write_byte(0x1, dev->iobase + ADC_FIFO_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
cfc_handle_events(dev, s);
- comedi_error(dev, "overflow");
+ dev_err(dev->class_dev, "overflow\n");
return IRQ_HANDLED;
}
/* handle external stop trigger */
@@ -1009,7 +998,7 @@ static int labpc_ao_insn_write(struct comedi_device *dev,
* be independently enabled/disabled for its the two channels */
spin_lock_irqsave(&dev->spinlock, flags);
devpriv->cmd2 &= ~CMD2_LDAC(channel);
- devpriv->write_byte(devpriv->cmd2, dev->iobase + CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
spin_unlock_irqrestore(&dev->spinlock, flags);
/* set range */
@@ -1020,13 +1009,13 @@ static int labpc_ao_insn_write(struct comedi_device *dev,
else
devpriv->cmd6 &= ~CMD6_DACUNI(channel);
/* write to register */
- devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}
/* send data */
lsb = data[0] & 0xff;
msb = (data[0] >> 8) & 0xff;
- devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
- devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
+ devpriv->write_byte(dev, lsb, DAC_LSB_REG(channel));
+ devpriv->write_byte(dev, msb, DAC_MSB_REG(channel));
/* remember value for readback */
devpriv->ao_value[channel] = data[0];
@@ -1046,14 +1035,16 @@ static int labpc_ao_insn_read(struct comedi_device *dev,
return 1;
}
-static int labpc_8255_mmio(int dir, int port, int data, unsigned long iobase)
+static int labpc_8255_mmio(int dir, int port, int data, unsigned long arg)
{
+ struct comedi_device *dev = (struct comedi_device *)arg;
+
if (dir) {
- writeb(data, (void __iomem *)(iobase + port));
+ writeb(data, dev->mmio + DIO_BASE_REG + port);
return 0;
- } else {
- return readb((void __iomem *)(iobase + port));
}
+
+ return readb(dev->mmio + DIO_BASE_REG + port);
}
/* lowlevel write to eeprom/dac */
@@ -1072,11 +1063,11 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
else
devpriv->cmd5 &= ~CMD5_SDATA;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* set clock to load bit */
devpriv->cmd5 |= CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
}
}
@@ -1092,14 +1083,14 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
/* set serial clock */
devpriv->cmd5 |= CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* clear clock bit */
devpriv->cmd5 &= ~CMD5_SCLK;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* read bits most significant bit first */
udelay(1);
- devpriv->stat2 = devpriv->read_byte(dev->iobase + STAT2_REG);
+ devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
if (devpriv->stat2 & STAT2_PROMOUT)
value |= 1 << (value_width - i);
}
@@ -1120,10 +1111,10 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
/* enable read/write to eeprom */
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send read instruction */
labpc_serial_out(dev, read_instruction, write_length);
@@ -1135,7 +1126,7 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev,
/* disable read/write to eeprom */
devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
return value;
}
@@ -1150,10 +1141,10 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
/* enable read/write to eeprom */
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send read status instruction */
labpc_serial_out(dev, read_status_instruction, write_length);
@@ -1163,7 +1154,7 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
/* disable read/write to eeprom */
devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
return value;
}
@@ -1186,7 +1177,7 @@ static int labpc_eeprom_write(struct comedi_device *dev,
break;
}
if (i == timeout) {
- comedi_error(dev, "eeprom write timed out");
+ dev_err(dev->class_dev, "eeprom write timed out\n");
return -ETIME;
}
/* update software copy of eeprom */
@@ -1195,21 +1186,21 @@ static int labpc_eeprom_write(struct comedi_device *dev,
/* enable read/write to eeprom */
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send write_enable instruction */
labpc_serial_out(dev, write_enable_instruction, write_length);
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* send write instruction */
devpriv->cmd5 |= CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
labpc_serial_out(dev, write_instruction, write_length);
/* send 8 bit address to write to */
labpc_serial_out(dev, address, write_length);
@@ -1217,12 +1208,12 @@ static int labpc_eeprom_write(struct comedi_device *dev,
labpc_serial_out(dev, value, write_length);
devpriv->cmd5 &= ~CMD5_EEPROMCS;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* disable read/write to eeprom */
devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
return 0;
}
@@ -1240,7 +1231,7 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
/* clear caldac load bit and make sure we don't write to eeprom */
devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
/* write 4 bit channel */
labpc_serial_out(dev, channel, 4);
@@ -1250,10 +1241,10 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
/* set and clear caldac bit to load caldac value */
devpriv->cmd5 |= CMD5_CALDACLD;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
devpriv->cmd5 &= ~CMD5_CALDACLD;
udelay(1);
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
}
static int labpc_calib_insn_write(struct comedi_device *dev,
@@ -1337,7 +1328,7 @@ int labpc_common_attach(struct comedi_device *dev,
int ret;
int i;
- if (board->has_mmio) {
+ if (dev->mmio) {
devpriv->read_byte = labpc_readb;
devpriv->write_byte = labpc_writeb;
} else {
@@ -1346,13 +1337,13 @@ int labpc_common_attach(struct comedi_device *dev,
}
/* 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);
+ devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
+ devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
+ devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
+ devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
if (board->is_labpc1200) {
- devpriv->write_byte(devpriv->cmd5, dev->iobase + CMD5_REG);
- devpriv->write_byte(devpriv->cmd6, dev->iobase + CMD6_REG);
+ devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
+ devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}
if (irq) {
@@ -1402,8 +1393,8 @@ int labpc_common_attach(struct comedi_device *dev,
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));
+ devpriv->write_byte(dev, lsb, DAC_LSB_REG(i));
+ devpriv->write_byte(dev, msb, DAC_MSB_REG(i));
}
} else {
s->type = COMEDI_SUBD_UNUSED;
@@ -1411,9 +1402,13 @@ int labpc_common_attach(struct comedi_device *dev,
/* 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 (dev->mmio) {
+ ret = subdev_8255_init(dev, s, labpc_8255_mmio,
+ (unsigned long)dev);
+ } else {
+ ret = subdev_8255_init(dev, s, NULL,
+ dev->iobase + DIO_BASE_REG);
+ }
if (ret)
return ret;
@@ -1463,7 +1458,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (!devpriv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], LABPC_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x20);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index 486589fa6fd8..f6e5cd15a409 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -32,11 +32,9 @@ struct labpc_boardinfo {
unsigned ai_scan_up:1; /* can auto scan up in ai channels */
unsigned has_ao:1; /* has analog outputs */
unsigned is_labpc1200:1; /* has extra regs compared to pc+ */
- unsigned has_mmio:1; /* uses memory mapped io */
};
struct labpc_private {
- struct mite_struct *mite; /* for mite chip on pci-1200 */
/* number of data points left to be taken */
unsigned long long count;
/* software copy of analog output values */
@@ -80,8 +78,9 @@ struct labpc_private {
* function pointers so we can use inb/outb or readb/writeb as
* appropriate
*/
- unsigned int (*read_byte) (unsigned long address);
- void (*write_byte) (unsigned int byte, unsigned long address);
+ unsigned int (*read_byte)(struct comedi_device *, unsigned long reg);
+ void (*write_byte)(struct comedi_device *,
+ unsigned int byte, unsigned long reg);
};
int labpc_common_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
index d9f25fdbb728..cb7d1c952cf2 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
@@ -147,7 +147,7 @@ static void handle_isa_dma(struct comedi_device *dev)
enable_dma(devpriv->dma_chan);
/* clear dma tc interrupt */
- devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
+ devpriv->write_byte(dev, 0x1, DMATC_CLEAR_REG);
}
void labpc_handle_dma_status(struct comedi_device *dev)
diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c
index 739597068297..65984ea0a3ee 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_pci.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c
@@ -35,7 +35,6 @@
#include "../comedidev.h"
-#include "mite.h"
#include "ni_labpc.h"
enum labpc_pci_boardid {
@@ -49,10 +48,32 @@ static const struct labpc_boardinfo labpc_pci_boards[] = {
.ai_scan_up = 1,
.has_ao = 1,
.is_labpc1200 = 1,
- .has_mmio = 1,
},
};
+/* ripped from mite.h and mite_setup2() to avoid mite dependancy */
+#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
+#define WENAB (1 << 7) /* window enable */
+
+static int labpc_pci_mite_init(struct pci_dev *pcidev)
+{
+ void __iomem *mite_base;
+ u32 main_phys_addr;
+
+ /* ioremap the MITE registers (BAR 0) temporarily */
+ mite_base = pci_ioremap_bar(pcidev, 0);
+ if (!mite_base)
+ return -ENOMEM;
+
+ /* set data window to main registers (BAR 1) */
+ main_phys_addr = pci_resource_start(pcidev, 1);
+ writel(main_phys_addr | WENAB, mite_base + MITE_IODWBSR);
+
+ /* finished with MITE registers */
+ iounmap(mite_base);
+ return 0;
+}
+
static int labpc_pci_auto_attach(struct comedi_device *dev,
unsigned long context)
{
@@ -72,29 +93,25 @@ static int labpc_pci_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
+ ret = labpc_pci_mite_init(pcidev);
+ if (ret)
+ return ret;
+
+ dev->mmio = pci_ioremap_bar(pcidev, 1);
+ if (!dev->mmio)
return -ENOMEM;
- devpriv->mite = mite_alloc(pcidev);
- if (!devpriv->mite)
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
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);
+ return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED);
}
static void labpc_pci_detach(struct comedi_device *dev)
{
- struct labpc_private *devpriv = dev->private;
-
- if (devpriv && devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (dev->irq)
free_irq(dev->irq, dev);
comedi_pci_disable(dev);
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 7ffdcc07ef92..297c95d2e0a3 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -194,113 +194,6 @@ static const struct comedi_lrange *const ni_range_lkup[] = {
[ai_gain_6143] = &range_bipolar5
};
-static int ni_dio_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_dio_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_cdio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_cdio_cancel(struct comedi_device *dev,
- struct comedi_subdevice *s);
-static void handle_cdio_interrupt(struct comedi_device *dev);
-static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum);
-
-static int ni_serial_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_serial_hw_readwrite8(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char data_out,
- unsigned char *data_in);
-static int ni_serial_sw_readwrite8(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned char data_out,
- unsigned char *data_in);
-
-static int ni_calib_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-static int ni_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
-static int ni_pfi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_pfi_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static unsigned ni_old_get_pfi_routing(struct comedi_device *dev,
- unsigned chan);
-
-static void ni_rtsi_init(struct comedi_device *dev);
-static int ni_rtsi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_rtsi_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_read_eeprom(struct comedi_device *dev, int addr);
-
-#ifndef PCIDMA
-static void ni_handle_fifo_half_full(struct comedi_device *dev);
-static int ni_ao_fifo_half_empty(struct comedi_device *dev,
- struct comedi_subdevice *s);
-#endif
-static void ni_handle_fifo_dregs(struct comedi_device *dev);
-static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum);
-static void ni_load_channelgain_list(struct comedi_device *dev,
- unsigned int n_chan, unsigned int *list);
-static void shutdown_ai_command(struct comedi_device *dev);
-
-static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
- unsigned int trignum);
-
-static int ni_8255_callback(int dir, int port, int data, unsigned long arg);
-
-#ifdef PCIDMA
-static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-#endif
-static void handle_gpct_interrupt(struct comedi_device *dev,
- unsigned short counter_index);
-
-static int init_cs5529(struct comedi_device *dev);
-static int cs5529_do_conversion(struct comedi_device *dev,
- unsigned short *data);
-static int cs5529_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
- unsigned int reg_select_bits);
-
-static int ni_m_series_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-static int ni_6143_pwm_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data);
-
-static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
- unsigned period_ns);
-static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status);
-static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status);
-
enum aimodes {
AIMODE_NONE = 0,
AIMODE_HALF_FULL = 1,
@@ -330,10 +223,8 @@ static inline unsigned NI_GPCT_SUBDEV(unsigned counter_index)
switch (counter_index) {
case 0:
return NI_GPCT0_SUBDEV;
- break;
case 1:
return NI_GPCT1_SUBDEV;
- break;
default:
break;
}
@@ -353,12 +244,394 @@ enum timebase_nanoseconds {
static const int num_adc_stages_611x = 3;
-static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
- unsigned ai_mite_status);
-static void handle_b_interrupt(struct comedi_device *dev, unsigned short status,
- unsigned ao_mite_status);
-static void get_last_sample_611x(struct comedi_device *dev);
-static void get_last_sample_6143(struct comedi_device *dev);
+static void ni_writel(struct comedi_device *dev, uint32_t data, int reg)
+{
+ if (dev->mmio)
+ writel(data, dev->mmio + reg);
+
+ outl(data, dev->iobase + reg);
+}
+
+static void ni_writew(struct comedi_device *dev, uint16_t data, int reg)
+{
+ if (dev->mmio)
+ writew(data, dev->mmio + reg);
+
+ outw(data, dev->iobase + reg);
+}
+
+static void ni_writeb(struct comedi_device *dev, uint8_t data, int reg)
+{
+ if (dev->mmio)
+ writeb(data, dev->mmio + reg);
+
+ outb(data, dev->iobase + reg);
+}
+
+static uint32_t ni_readl(struct comedi_device *dev, int reg)
+{
+ if (dev->mmio)
+ return readl(dev->mmio + reg);
+
+ return inl(dev->iobase + reg);
+}
+
+static uint16_t ni_readw(struct comedi_device *dev, int reg)
+{
+ if (dev->mmio)
+ return readw(dev->mmio + reg);
+
+ return inw(dev->iobase + reg);
+}
+
+static uint8_t ni_readb(struct comedi_device *dev, int reg)
+{
+ if (dev->mmio)
+ return readb(dev->mmio + reg);
+
+ return inb(dev->iobase + reg);
+}
+
+/*
+ * We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board.
+ *
+ * The AT-MIO and DAQCard devices map the low 8 STC registers to
+ * iobase+reg*2.
+ *
+ * Most PCIMIO devices also map the low 8 STC registers but the
+ * 611x devices map the read registers to iobase+(addr-1)*2.
+ * For now non-windowed STC access is disabled if a PCIMIO device
+ * is detected (devpriv->mite has been initialized).
+ *
+ * The M series devices do not used windowed registers for the
+ * STC registers. The functions below handle the mapping of the
+ * windowed STC registers to the m series register offsets.
+ */
+
+static void m_series_stc_writel(struct comedi_device *dev,
+ uint32_t data, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case AI_SC_Load_A_Registers:
+ offset = M_Offset_AI_SC_Load_A;
+ break;
+ case AI_SI_Load_A_Registers:
+ offset = M_Offset_AI_SI_Load_A;
+ break;
+ case AO_BC_Load_A_Register:
+ offset = M_Offset_AO_BC_Load_A;
+ break;
+ case AO_UC_Load_A_Register:
+ offset = M_Offset_AO_UC_Load_A;
+ break;
+ case AO_UI_Load_A_Register:
+ offset = M_Offset_AO_UI_Load_A;
+ break;
+ case G_Load_A_Register(0):
+ offset = M_Offset_G0_Load_A;
+ break;
+ case G_Load_A_Register(1):
+ offset = M_Offset_G1_Load_A;
+ break;
+ case G_Load_B_Register(0):
+ offset = M_Offset_G0_Load_B;
+ break;
+ case G_Load_B_Register(1):
+ offset = M_Offset_G1_Load_B;
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return;
+ }
+ ni_writel(dev, data, offset);
+}
+
+static void m_series_stc_writew(struct comedi_device *dev,
+ uint16_t data, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case ADC_FIFO_Clear:
+ offset = M_Offset_AI_FIFO_Clear;
+ break;
+ case AI_Command_1_Register:
+ offset = M_Offset_AI_Command_1;
+ break;
+ case AI_Command_2_Register:
+ offset = M_Offset_AI_Command_2;
+ break;
+ case AI_Mode_1_Register:
+ offset = M_Offset_AI_Mode_1;
+ break;
+ case AI_Mode_2_Register:
+ offset = M_Offset_AI_Mode_2;
+ break;
+ case AI_Mode_3_Register:
+ offset = M_Offset_AI_Mode_3;
+ break;
+ case AI_Output_Control_Register:
+ offset = M_Offset_AI_Output_Control;
+ break;
+ case AI_Personal_Register:
+ offset = M_Offset_AI_Personal;
+ break;
+ case AI_SI2_Load_A_Register:
+ /* this is a 32 bit register on m series boards */
+ ni_writel(dev, data, M_Offset_AI_SI2_Load_A);
+ return;
+ case AI_SI2_Load_B_Register:
+ /* this is a 32 bit register on m series boards */
+ ni_writel(dev, data, M_Offset_AI_SI2_Load_B);
+ return;
+ case AI_START_STOP_Select_Register:
+ offset = M_Offset_AI_START_STOP_Select;
+ break;
+ case AI_Trigger_Select_Register:
+ offset = M_Offset_AI_Trigger_Select;
+ break;
+ case Analog_Trigger_Etc_Register:
+ offset = M_Offset_Analog_Trigger_Etc;
+ break;
+ case AO_Command_1_Register:
+ offset = M_Offset_AO_Command_1;
+ break;
+ case AO_Command_2_Register:
+ offset = M_Offset_AO_Command_2;
+ break;
+ case AO_Mode_1_Register:
+ offset = M_Offset_AO_Mode_1;
+ break;
+ case AO_Mode_2_Register:
+ offset = M_Offset_AO_Mode_2;
+ break;
+ case AO_Mode_3_Register:
+ offset = M_Offset_AO_Mode_3;
+ break;
+ case AO_Output_Control_Register:
+ offset = M_Offset_AO_Output_Control;
+ break;
+ case AO_Personal_Register:
+ offset = M_Offset_AO_Personal;
+ break;
+ case AO_Start_Select_Register:
+ offset = M_Offset_AO_Start_Select;
+ break;
+ case AO_Trigger_Select_Register:
+ offset = M_Offset_AO_Trigger_Select;
+ break;
+ case Clock_and_FOUT_Register:
+ offset = M_Offset_Clock_and_FOUT;
+ break;
+ case Configuration_Memory_Clear:
+ offset = M_Offset_Configuration_Memory_Clear;
+ break;
+ case DAC_FIFO_Clear:
+ offset = M_Offset_AO_FIFO_Clear;
+ break;
+ case DIO_Control_Register:
+ dev_dbg(dev->class_dev,
+ "%s: FIXME: register 0x%x does not map cleanly on to m-series boards\n",
+ __func__, reg);
+ return;
+ case G_Autoincrement_Register(0):
+ offset = M_Offset_G0_Autoincrement;
+ break;
+ case G_Autoincrement_Register(1):
+ offset = M_Offset_G1_Autoincrement;
+ break;
+ case G_Command_Register(0):
+ offset = M_Offset_G0_Command;
+ break;
+ case G_Command_Register(1):
+ offset = M_Offset_G1_Command;
+ break;
+ case G_Input_Select_Register(0):
+ offset = M_Offset_G0_Input_Select;
+ break;
+ case G_Input_Select_Register(1):
+ offset = M_Offset_G1_Input_Select;
+ break;
+ case G_Mode_Register(0):
+ offset = M_Offset_G0_Mode;
+ break;
+ case G_Mode_Register(1):
+ offset = M_Offset_G1_Mode;
+ break;
+ case Interrupt_A_Ack_Register:
+ offset = M_Offset_Interrupt_A_Ack;
+ break;
+ case Interrupt_A_Enable_Register:
+ offset = M_Offset_Interrupt_A_Enable;
+ break;
+ case Interrupt_B_Ack_Register:
+ offset = M_Offset_Interrupt_B_Ack;
+ break;
+ case Interrupt_B_Enable_Register:
+ offset = M_Offset_Interrupt_B_Enable;
+ break;
+ case Interrupt_Control_Register:
+ offset = M_Offset_Interrupt_Control;
+ break;
+ case IO_Bidirection_Pin_Register:
+ offset = M_Offset_IO_Bidirection_Pin;
+ break;
+ case Joint_Reset_Register:
+ offset = M_Offset_Joint_Reset;
+ break;
+ case RTSI_Trig_A_Output_Register:
+ offset = M_Offset_RTSI_Trig_A_Output;
+ break;
+ case RTSI_Trig_B_Output_Register:
+ offset = M_Offset_RTSI_Trig_B_Output;
+ break;
+ case RTSI_Trig_Direction_Register:
+ offset = M_Offset_RTSI_Trig_Direction;
+ break;
+ /*
+ * FIXME: DIO_Output_Register (16 bit reg) is replaced by
+ * M_Offset_Static_Digital_Output (32 bit) and
+ * M_Offset_SCXI_Serial_Data_Out (8 bit)
+ */
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return;
+ }
+ ni_writew(dev, data, offset);
+}
+
+static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case G_HW_Save_Register(0):
+ offset = M_Offset_G0_HW_Save;
+ break;
+ case G_HW_Save_Register(1):
+ offset = M_Offset_G1_HW_Save;
+ break;
+ case G_Save_Register(0):
+ offset = M_Offset_G0_Save;
+ break;
+ case G_Save_Register(1):
+ offset = M_Offset_G1_Save;
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return 0;
+ }
+ return ni_readl(dev, offset);
+}
+
+static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
+{
+ unsigned offset;
+
+ switch (reg) {
+ case AI_Status_1_Register:
+ offset = M_Offset_AI_Status_1;
+ break;
+ case AO_Status_1_Register:
+ offset = M_Offset_AO_Status_1;
+ break;
+ case AO_Status_2_Register:
+ offset = M_Offset_AO_Status_2;
+ break;
+ case DIO_Serial_Input_Register:
+ return ni_readb(dev, M_Offset_SCXI_Serial_Data_In);
+ case Joint_Status_1_Register:
+ offset = M_Offset_Joint_Status_1;
+ break;
+ case Joint_Status_2_Register:
+ offset = M_Offset_Joint_Status_2;
+ break;
+ case G_Status_Register:
+ offset = M_Offset_G01_Status;
+ break;
+ default:
+ dev_warn(dev->class_dev,
+ "%s: bug! unhandled register=0x%x in switch\n",
+ __func__, reg);
+ return 0;
+ }
+ return ni_readw(dev, offset);
+}
+
+static void ni_stc_writew(struct comedi_device *dev, uint16_t data, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+ unsigned long flags;
+
+ if (devpriv->is_m_series) {
+ m_series_stc_writew(dev, data, reg);
+ } else {
+ spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (!devpriv->mite && reg < 8) {
+ ni_writew(dev, data, reg * 2);
+ } else {
+ ni_writew(dev, reg, Window_Address);
+ ni_writew(dev, data, Window_Data);
+ }
+ spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ }
+}
+
+static void ni_stc_writel(struct comedi_device *dev, uint32_t data, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+
+ if (devpriv->is_m_series) {
+ m_series_stc_writel(dev, data, reg);
+ } else {
+ ni_stc_writew(dev, data >> 16, reg);
+ ni_stc_writew(dev, data & 0xffff, reg + 1);
+ }
+}
+
+static uint16_t ni_stc_readw(struct comedi_device *dev, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+ unsigned long flags;
+ uint16_t val;
+
+ if (devpriv->is_m_series) {
+ val = m_series_stc_readw(dev, reg);
+ } else {
+ spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (!devpriv->mite && reg < 8) {
+ val = ni_readw(dev, reg * 2);
+ } else {
+ ni_writew(dev, reg, Window_Address);
+ val = ni_readw(dev, Window_Data);
+ }
+ spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ }
+ return val;
+}
+
+static uint32_t ni_stc_readl(struct comedi_device *dev, int reg)
+{
+ struct ni_private *devpriv = dev->private;
+ uint32_t val;
+
+ if (devpriv->is_m_series) {
+ val = m_series_stc_readl(dev, reg);
+ } else {
+ val = ni_stc_readw(dev, reg) << 16;
+ val |= ni_stc_readw(dev, reg + 1);
+ }
+ return val;
+}
static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
unsigned bit_mask, unsigned bit_values)
@@ -371,34 +644,34 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
case Interrupt_A_Enable_Register:
devpriv->int_a_enable_reg &= ~bit_mask;
devpriv->int_a_enable_reg |= bit_values & bit_mask;
- devpriv->stc_writew(dev, devpriv->int_a_enable_reg,
- Interrupt_A_Enable_Register);
+ ni_stc_writew(dev, devpriv->int_a_enable_reg,
+ Interrupt_A_Enable_Register);
break;
case Interrupt_B_Enable_Register:
devpriv->int_b_enable_reg &= ~bit_mask;
devpriv->int_b_enable_reg |= bit_values & bit_mask;
- devpriv->stc_writew(dev, devpriv->int_b_enable_reg,
- Interrupt_B_Enable_Register);
+ ni_stc_writew(dev, devpriv->int_b_enable_reg,
+ Interrupt_B_Enable_Register);
break;
case IO_Bidirection_Pin_Register:
devpriv->io_bidirection_pin_reg &= ~bit_mask;
devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
- devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg,
- IO_Bidirection_Pin_Register);
+ ni_stc_writew(dev, devpriv->io_bidirection_pin_reg,
+ IO_Bidirection_Pin_Register);
break;
case AI_AO_Select:
devpriv->ai_ao_select_reg &= ~bit_mask;
devpriv->ai_ao_select_reg |= bit_values & bit_mask;
- ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+ ni_writeb(dev, devpriv->ai_ao_select_reg, AI_AO_Select);
break;
case G0_G1_Select:
devpriv->g0_g1_select_reg &= ~bit_mask;
devpriv->g0_g1_select_reg |= bit_values & bit_mask;
- ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+ ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select);
break;
default:
- printk("Warning %s() called with invalid register\n", __func__);
- printk("reg is %d\n", reg);
+ dev_err(dev->class_dev,
+ "%s called with invalid register %d\n", __func__, reg);
break;
}
mmiowb();
@@ -406,8 +679,6 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
}
#ifdef PCIDMA
-static int ni_ai_drain_dma(struct comedi_device *dev);
-
/* DMA channel setup */
/* negative channel means no channel */
@@ -472,7 +743,7 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
(ni_stc_dma_channel_select_bitfield(mite_channel) <<
CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask;
}
- ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
+ ni_writeb(dev, devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
mmiowb();
spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
}
@@ -488,8 +759,8 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev)
mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
if (devpriv->ai_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for analog input.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for analog input\n");
return -EBUSY;
}
devpriv->ai_mite_chan->dir = COMEDI_INPUT;
@@ -509,8 +780,8 @@ static int ni_request_ao_mite_channel(struct comedi_device *dev)
mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
if (devpriv->ao_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for analog outut.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for analog outut\n");
return -EBUSY;
}
devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
@@ -535,8 +806,8 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
devpriv->gpct_mite_ring[gpct_index]);
if (mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for counter.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for counter\n");
return -EBUSY;
}
mite_chan->dir = direction;
@@ -561,8 +832,8 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev)
mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
if (devpriv->cdo_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev,
- "failed to reserve mite dma channel for correlated digital outut.");
+ dev_err(dev->class_dev,
+ "failed to reserve mite dma channel for correlated digital output\n");
return -EBUSY;
}
devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
@@ -643,100 +914,71 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev)
#endif /* PCIDMA */
}
-/* e-series boards use the second irq signals to generate dma requests for their counters */
#ifdef PCIDMA
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;
+ uint16_t val = 0;
+ int reg;
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series || gpct_index > 1)
return;
- switch (gpct_index) {
- case 0:
- if (enable) {
- devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
- Second_IRQ_A_Enable_Register);
- } else {
- devpriv->stc_writew(dev, 0,
- Second_IRQ_A_Enable_Register);
- }
- break;
- case 1:
- if (enable) {
- devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
- Second_IRQ_B_Enable_Register);
- } else {
- devpriv->stc_writew(dev, 0,
- Second_IRQ_B_Enable_Register);
- }
- break;
- default:
- BUG();
- break;
+
+ /*
+ * e-series boards use the second irq signals to generate
+ * dma requests for their counters
+ */
+ if (gpct_index == 0) {
+ reg = Second_IRQ_A_Enable_Register;
+ if (enable)
+ val = G0_Gate_Second_Irq_Enable;
+ } else {
+ reg = Second_IRQ_B_Enable_Register;
+ if (enable)
+ val = G1_Gate_Second_Irq_Enable;
}
+ ni_stc_writew(dev, val, reg);
}
#endif /* PCIDMA */
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;
static const int timeout = 10000;
int i;
- if (board->reg_type == ni_reg_6143) {
+ if (devpriv->is_6143) {
/* Flush the 6143 data FIFO */
- ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */
- ni_writel(0x00, AIFIFO_Control_6143); /* Flush fifo */
+ ni_writel(dev, 0x10, AIFIFO_Control_6143);
+ ni_writel(dev, 0x00, AIFIFO_Control_6143);
/* Wait for complete */
for (i = 0; i < timeout; i++) {
- if (!(ni_readl(AIFIFO_Status_6143) & 0x10))
+ if (!(ni_readl(dev, AIFIFO_Status_6143) & 0x10))
break;
udelay(1);
}
- if (i == timeout) {
- comedi_error(dev, "FIFO flush timeout.");
- }
+ if (i == timeout)
+ dev_err(dev->class_dev, "FIFO flush timeout\n");
} else {
- devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
- 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));
+ ni_stc_writew(dev, 1, ADC_FIFO_Clear);
+ if (devpriv->is_625x) {
+ ni_writeb(dev, 0, M_Offset_Static_AI_Control(0));
+ ni_writeb(dev, 1, M_Offset_Static_AI_Control(0));
#if 0
/* the NI example code does 3 convert pulses for 625x boards,
but that appears to be wrong in practice. */
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
#endif
}
}
}
-static void win_out2(struct comedi_device *dev, uint32_t data, int reg)
-{
- struct ni_private *devpriv = dev->private;
-
- devpriv->stc_writew(dev, data >> 16, reg);
- devpriv->stc_writew(dev, data & 0xffff, reg + 1);
-}
-
-static uint32_t win_in2(struct comedi_device *dev, int reg)
-{
- struct ni_private *devpriv = dev->private;
- uint32_t bits;
-
- bits = devpriv->stc_readw(dev, reg) << 16;
- bits |= devpriv->stc_readw(dev, reg + 1);
- return bits;
-}
-
-#define ao_win_out(data, addr) ni_ao_win_outw(dev, data, addr)
static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
int addr)
{
@@ -744,8 +986,8 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(addr, AO_Window_Address_611x);
- ni_writew(data, AO_Window_Data_611x);
+ ni_writew(dev, addr, AO_Window_Address_611x);
+ ni_writew(dev, data, AO_Window_Data_611x);
spin_unlock_irqrestore(&devpriv->window_lock, flags);
}
@@ -756,8 +998,8 @@ static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data,
unsigned long flags;
spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(addr, AO_Window_Address_611x);
- ni_writel(data, AO_Window_Data_611x);
+ ni_writew(dev, addr, AO_Window_Address_611x);
+ ni_writel(dev, data, AO_Window_Data_611x);
spin_unlock_irqrestore(&devpriv->window_lock, flags);
}
@@ -768,8 +1010,8 @@ static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
unsigned short data;
spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(addr, AO_Window_Address_611x);
- data = ni_readw(AO_Window_Data_611x);
+ ni_writew(dev, addr, AO_Window_Address_611x);
+ data = ni_readw(dev, AO_Window_Data_611x);
spin_unlock_irqrestore(&devpriv->window_lock, flags);
return data;
}
@@ -796,83 +1038,58 @@ static inline void ni_set_bits(struct comedi_device *dev, int reg,
ni_set_bitfield(dev, reg, bits, bit_values);
}
-static irqreturn_t ni_E_interrupt(int irq, void *d)
+#ifdef PCIDMA
+static void ni_sync_ai_dma(struct comedi_device *dev)
{
- struct comedi_device *dev = d;
struct ni_private *devpriv = dev->private;
- unsigned short a_status;
- unsigned short b_status;
- unsigned int ai_mite_status = 0;
- unsigned int ao_mite_status = 0;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned long flags;
-#ifdef PCIDMA
- struct mite_struct *mite = devpriv->mite;
-#endif
-
- if (!dev->attached)
- return IRQ_NONE;
- smp_mb(); /* make sure dev->attached is checked before handler does anything else. */
-
- /* lock to avoid race with comedi_poll */
- spin_lock_irqsave(&dev->spinlock, flags);
- a_status = devpriv->stc_readw(dev, AI_Status_1_Register);
- b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
-#ifdef PCIDMA
- if (mite) {
- unsigned long flags_too;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
- if (devpriv->ai_mite_chan) {
- ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
- if (ai_mite_status & CHSR_LINKC)
- writel(CHOR_CLRLC,
- devpriv->mite->mite_io_addr +
- MITE_CHOR(devpriv->
- ai_mite_chan->channel));
- }
- if (devpriv->ao_mite_chan) {
- ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
- if (ao_mite_status & CHSR_LINKC)
- writel(CHOR_CLRLC,
- mite->mite_io_addr +
- MITE_CHOR(devpriv->
- ao_mite_chan->channel));
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
- }
-#endif
- ack_a_interrupt(dev, a_status);
- ack_b_interrupt(dev, b_status);
- if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
- handle_a_interrupt(dev, a_status, ai_mite_status);
- if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
- handle_b_interrupt(dev, b_status, ao_mite_status);
- handle_gpct_interrupt(dev, 0);
- handle_gpct_interrupt(dev, 1);
- handle_cdio_interrupt(dev);
- spin_unlock_irqrestore(&dev->spinlock, flags);
- return IRQ_HANDLED;
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan)
+ mite_sync_input_dma(devpriv->ai_mite_chan, s);
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
}
-#ifdef PCIDMA
-static void ni_sync_ai_dma(struct comedi_device *dev)
+static int ni_ai_drain_dma(struct comedi_device *dev)
{
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ int i;
+ static const int timeout = 10000;
unsigned long flags;
+ int retval = 0;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan)
- mite_sync_input_dma(devpriv->ai_mite_chan, s);
+ if (devpriv->ai_mite_chan) {
+ for (i = 0; i < timeout; i++) {
+ if ((ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St)
+ && mite_bytes_in_transit(devpriv->ai_mite_chan) ==
+ 0)
+ break;
+ udelay(5);
+ }
+ if (i == timeout) {
+ dev_err(dev->class_dev, "%s timed out\n", __func__);
+ dev_err(dev->class_dev,
+ "mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
+ mite_bytes_in_transit(devpriv->ai_mite_chan),
+ ni_stc_readw(dev, AI_Status_1_Register));
+ retval = -1;
+ }
+ }
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ ni_sync_ai_dma(dev);
+
+ return retval;
}
static void mite_handle_b_linkc(struct mite_struct *mite,
struct comedi_device *dev)
{
struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
+ struct comedi_subdevice *s = dev->write_subdev;
unsigned long flags;
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -883,13 +1100,13 @@ static void mite_handle_b_linkc(struct mite_struct *mite,
static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
{
- struct ni_private *devpriv = dev->private;
static const int timeout = 10000;
int i;
+
for (i = 0; i < timeout; i++) {
unsigned short b_status;
- b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+ b_status = ni_stc_readw(dev, AO_Status_1_Register);
if (b_status & AO_FIFO_Half_Full_St)
break;
/* if we poll too often, the pci bus activity seems
@@ -897,247 +1114,19 @@ static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
udelay(10);
}
if (i == timeout) {
- comedi_error(dev, "timed out waiting for dma load");
+ dev_err(dev->class_dev, "timed out waiting for dma load\n");
return -EPIPE;
}
return 0;
}
-
#endif /* PCIDMA */
-static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->aimode == AIMODE_SCAN) {
-#ifdef PCIDMA
- static const int timeout = 10;
- int i;
-
- for (i = 0; i < timeout; i++) {
- ni_sync_ai_dma(dev);
- if ((s->async->events & COMEDI_CB_EOS))
- break;
- udelay(1);
- }
-#else
- ni_handle_fifo_dregs(dev);
- s->async->events |= COMEDI_CB_EOS;
-#endif
- }
- /* handle special case of single scan using AI_End_On_End_Of_Scan */
- if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan))
- shutdown_ai_command(dev);
-}
-
-static void shutdown_ai_command(struct comedi_device *dev)
-{
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-
-#ifdef PCIDMA
- ni_ai_drain_dma(dev);
-#endif
- ni_handle_fifo_dregs(dev);
- get_last_sample_611x(dev);
- get_last_sample_6143(dev);
-
- s->async->events |= COMEDI_CB_EOA;
-}
-
-static void handle_gpct_interrupt(struct comedi_device *dev,
- unsigned short counter_index)
-{
-#ifdef PCIDMA
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s;
-
- s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
-
- ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
- s);
- cfc_handle_events(dev, s);
-#endif
-}
-
-static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
-{
- struct ni_private *devpriv = dev->private;
- unsigned short ack = 0;
-
- if (a_status & AI_SC_TC_St)
- ack |= AI_SC_TC_Interrupt_Ack;
- if (a_status & AI_START1_St)
- ack |= AI_START1_Interrupt_Ack;
- if (a_status & AI_START_St)
- ack |= AI_START_Interrupt_Ack;
- if (a_status & AI_STOP_St)
- /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
- ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */;
- if (ack)
- devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register);
-}
-
-static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
- unsigned ai_mite_status)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-
- /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */
- if (s->type == COMEDI_SUBD_UNUSED)
- return;
-
-#ifdef PCIDMA
- if (ai_mite_status & CHSR_LINKC)
- ni_sync_ai_dma(dev);
-
- if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
- CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
- CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
- printk
- ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
- ai_mite_status);
- s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
- /* disable_irq(dev->irq); */
- }
-#endif
-
- /* test for all uncommon interrupt events at the same time */
- if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
- AI_SC_TC_St | AI_START1_St)) {
- if (status == 0xffff) {
- printk
- ("ni_mio_common: a_status=0xffff. Card removed?\n");
- /* we probably aren't even running a command now,
- * so it's a good idea to be careful. */
- if (comedi_is_subdevice_running(s)) {
- s->async->events |=
- COMEDI_CB_ERROR | COMEDI_CB_EOA;
- cfc_handle_events(dev, s);
- }
- return;
- }
- if (status & (AI_Overrun_St | AI_Overflow_St |
- AI_SC_TC_Error_St)) {
- printk("ni_mio_common: ai error a_status=%04x\n",
- status);
-
- shutdown_ai_command(dev);
-
- s->async->events |= COMEDI_CB_ERROR;
- if (status & (AI_Overrun_St | AI_Overflow_St))
- s->async->events |= COMEDI_CB_OVERFLOW;
-
- cfc_handle_events(dev, s);
- return;
- }
- if (status & AI_SC_TC_St) {
- if (!devpriv->ai_continuous)
- shutdown_ai_command(dev);
- }
- }
-#ifndef PCIDMA
- if (status & AI_FIFO_Half_Full_St) {
- int i;
- static const int timeout = 10;
- /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
- *fail to get the fifo less than half full, so loop to be sure.*/
- for (i = 0; i < timeout; ++i) {
- ni_handle_fifo_half_full(dev);
- if ((devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Half_Full_St) == 0)
- break;
- }
- }
-#endif /* !PCIDMA */
-
- if ((status & AI_STOP_St))
- ni_handle_eos(dev, s);
-
- cfc_handle_events(dev, s);
-}
-
-static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
-{
- struct ni_private *devpriv = dev->private;
- unsigned short ack = 0;
-
- if (b_status & AO_BC_TC_St)
- ack |= AO_BC_TC_Interrupt_Ack;
- if (b_status & AO_Overrun_St)
- ack |= AO_Error_Interrupt_Ack;
- if (b_status & AO_START_St)
- ack |= AO_START_Interrupt_Ack;
- if (b_status & AO_START1_St)
- ack |= AO_START1_Interrupt_Ack;
- if (b_status & AO_UC_TC_St)
- ack |= AO_UC_TC_Interrupt_Ack;
- if (b_status & AO_UI2_TC_St)
- ack |= AO_UI2_TC_Interrupt_Ack;
- if (b_status & AO_UPDATE_St)
- ack |= AO_UPDATE_Interrupt_Ack;
- if (ack)
- devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register);
-}
-
-static void handle_b_interrupt(struct comedi_device *dev,
- unsigned short b_status, unsigned ao_mite_status)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV];
- /* unsigned short ack=0; */
-
-#ifdef PCIDMA
- /* Currently, mite.c requires us to handle LINKC */
- if (ao_mite_status & CHSR_LINKC)
- mite_handle_b_linkc(devpriv->mite, dev);
-
- if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
- CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
- CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
- printk
- ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
- ao_mite_status);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- }
-#endif
-
- if (b_status == 0xffff)
- return;
- if (b_status & AO_Overrun_St) {
- printk
- ("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
- b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
-
- if (b_status & AO_BC_TC_St)
- s->async->events |= COMEDI_CB_EOA;
-
-#ifndef PCIDMA
- if (b_status & AO_FIFO_Request_St) {
- int ret;
-
- ret = ni_ao_fifo_half_empty(dev, s);
- if (!ret) {
- printk("ni_mio_common: AO buffer underrun\n");
- ni_set_bits(dev, Interrupt_B_Enable_Register,
- AO_FIFO_Interrupt_Enable |
- AO_Error_Interrupt_Enable, 0);
- s->async->events |= COMEDI_CB_OVERFLOW;
- }
- }
-#endif
-
- cfc_handle_events(dev, s);
-}
#ifndef PCIDMA
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 ni_private *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
int chan;
@@ -1155,10 +1144,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
range = CR_RANGE(cmd->chanlist[chan]);
- if (board->reg_type & ni_reg_6xxx_mask) {
+ if (devpriv->is_6xxx) {
packed_data = d & 0xffff;
/* 6711 only has 16 bit wide ao fifo */
- if (board->reg_type != ni_reg_6711) {
+ if (!devpriv->is_6711) {
err &= comedi_buf_get(s, &d);
if (err == 0)
break;
@@ -1166,9 +1155,9 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
i++;
packed_data |= (d << 16) & 0xffff0000;
}
- ni_writel(packed_data, DAC_FIFO_Data_611x);
+ ni_writel(dev, packed_data, DAC_FIFO_Data_611x);
} else {
- ni_writew(d, DAC_FIFO_Data);
+ ni_writew(dev, d, DAC_FIFO_Data);
}
chan++;
chan %= cmd->chanlist_len;
@@ -1225,8 +1214,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev,
int n;
/* reset fifo */
- devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
- if (board->reg_type & ni_reg_6xxx_mask)
+ ni_stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (devpriv->is_6xxx)
ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
/* load some data */
@@ -1246,17 +1235,16 @@ 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 (board->reg_type == ni_reg_611x) {
+ if (devpriv->is_611x) {
unsigned short data[2];
u32 dl;
for (i = 0; i < n / 2; i++) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
/* This may get the hi/lo data in the wrong order */
data[0] = (dl >> 16) & 0xffff;
data[1] = dl & 0xffff;
@@ -1264,17 +1252,17 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
}
/* Check if there's a single sample stuck in the FIFO */
if (n % 2) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
data[0] = dl & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
- } else if (board->reg_type == ni_reg_6143) {
+ } else if (devpriv->is_6143) {
unsigned short data[2];
u32 dl;
/* This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */
for (i = 0; i < n / 2; i++) {
- dl = ni_readl(AIFIFO_Data_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
data[0] = (dl >> 16) & 0xffff;
data[1] = dl & 0xffff;
@@ -1282,21 +1270,23 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
}
if (n % 2) {
/* Assume there is a single sample stuck in the FIFO */
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01, AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
data[0] = (dl >> 16) & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
} else {
if (n > sizeof(devpriv->ai_fifo_buffer) /
sizeof(devpriv->ai_fifo_buffer[0])) {
- comedi_error(dev, "bug! ai_fifo_buffer too small");
+ dev_err(dev->class_dev,
+ "bug! ai_fifo_buffer too small\n");
async->events |= COMEDI_CB_ERROR;
return;
}
for (i = 0; i < n; i++) {
devpriv->ai_fifo_buffer[i] =
- ni_readw(ADC_FIFO_Data_Register);
+ ni_readw(dev, ADC_FIFO_Data_Register);
}
cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
n *
@@ -1307,7 +1297,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
static void ni_handle_fifo_half_full(struct comedi_device *dev)
{
const struct ni_board_struct *board = comedi_board(dev);
- struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
+ struct comedi_subdevice *s = dev->read_subdev;
int n;
n = board->ai_fifo_depth / 2;
@@ -1316,70 +1306,32 @@ static void ni_handle_fifo_half_full(struct comedi_device *dev)
}
#endif
-#ifdef PCIDMA
-static int ni_ai_drain_dma(struct comedi_device *dev)
-{
- struct ni_private *devpriv = dev->private;
- int i;
- static const int timeout = 10000;
- unsigned long flags;
- int retval = 0;
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->ai_mite_chan) {
- for (i = 0; i < timeout; i++) {
- if ((devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St)
- && mite_bytes_in_transit(devpriv->ai_mite_chan) ==
- 0)
- break;
- udelay(5);
- }
- if (i == timeout) {
- printk("ni_mio_common: wait for dma drain timed out\n");
- printk
- ("mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
- mite_bytes_in_transit(devpriv->ai_mite_chan),
- devpriv->stc_readw(dev, AI_Status_1_Register));
- retval = -1;
- }
- }
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- ni_sync_ai_dma(dev);
-
- return retval;
-}
-#endif
/*
Empties the AI fifo
*/
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];
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned short data[2];
u32 dl;
unsigned short fifo_empty;
int i;
- if (board->reg_type == ni_reg_611x) {
- while ((devpriv->stc_readw(dev,
- AI_Status_1_Register) &
+ if (devpriv->is_611x) {
+ while ((ni_stc_readw(dev, AI_Status_1_Register) &
AI_FIFO_Empty_St) == 0) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
/* This may get the hi/lo data in the wrong order */
data[0] = (dl >> 16);
data[1] = (dl & 0xffff);
cfc_write_array_to_buffer(s, data, sizeof(data));
}
- } else if (board->reg_type == ni_reg_6143) {
+ } else if (devpriv->is_6143) {
i = 0;
- while (ni_readl(AIFIFO_Status_6143) & 0x04) {
- dl = ni_readl(AIFIFO_Data_6143);
+ while (ni_readl(dev, AIFIFO_Status_6143) & 0x04) {
+ dl = ni_readl(dev, AIFIFO_Data_6143);
/* This may get the hi/lo data in the wrong order */
data[0] = (dl >> 16);
@@ -1388,30 +1340,29 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
i += 2;
}
/* Check if stranded sample is present */
- if (ni_readl(AIFIFO_Status_6143) & 0x01) {
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
+ if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) {
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01, AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
data[0] = (dl >> 16) & 0xffff;
cfc_write_to_buffer(s, data[0]);
}
} else {
- fifo_empty =
- devpriv->stc_readw(dev,
- AI_Status_1_Register) & AI_FIFO_Empty_St;
+ fifo_empty = ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St;
while (fifo_empty == 0) {
for (i = 0;
i <
sizeof(devpriv->ai_fifo_buffer) /
sizeof(devpriv->ai_fifo_buffer[0]); i++) {
- fifo_empty =
- devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St;
+ fifo_empty = ni_stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St;
if (fifo_empty)
break;
devpriv->ai_fifo_buffer[i] =
- ni_readw(ADC_FIFO_Data_Register);
+ ni_readw(dev, ADC_FIFO_Data_Register);
}
cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
i *
@@ -1423,18 +1374,17 @@ 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];
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned short data;
u32 dl;
- if (board->reg_type != ni_reg_611x)
+ if (!devpriv->is_611x)
return;
/* Check if there's a single sample stuck in the FIFO */
- if (ni_readb(XXX_Status) & 0x80) {
- dl = ni_readl(ADC_FIFO_Data_611x);
+ if (ni_readb(dev, XXX_Status) & 0x80) {
+ dl = ni_readl(dev, ADC_FIFO_Data_611x);
data = (dl & 0xffff);
cfc_write_to_buffer(s, data);
}
@@ -1442,19 +1392,19 @@ 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];
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned short data;
u32 dl;
- if (board->reg_type != ni_reg_6143)
+ if (!devpriv->is_6143)
return;
/* Check if there's a single sample stuck in the FIFO */
- if (ni_readl(AIFIFO_Status_6143) & 0x01) {
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
+ if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) {
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01, AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
/* This may get the hi/lo data in the wrong order */
data = (dl >> 16) & 0xffff;
@@ -1462,6 +1412,232 @@ static void get_last_sample_6143(struct comedi_device *dev)
}
}
+static void shutdown_ai_command(struct comedi_device *dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+
+#ifdef PCIDMA
+ ni_ai_drain_dma(dev);
+#endif
+ ni_handle_fifo_dregs(dev);
+ get_last_sample_611x(dev);
+ get_last_sample_6143(dev);
+
+ s->async->events |= COMEDI_CB_EOA;
+}
+
+static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct ni_private *devpriv = dev->private;
+
+ if (devpriv->aimode == AIMODE_SCAN) {
+#ifdef PCIDMA
+ static const int timeout = 10;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ ni_sync_ai_dma(dev);
+ if ((s->async->events & COMEDI_CB_EOS))
+ break;
+ udelay(1);
+ }
+#else
+ ni_handle_fifo_dregs(dev);
+ s->async->events |= COMEDI_CB_EOS;
+#endif
+ }
+ /* handle special case of single scan using AI_End_On_End_Of_Scan */
+ if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan))
+ shutdown_ai_command(dev);
+}
+
+static void handle_gpct_interrupt(struct comedi_device *dev,
+ unsigned short counter_index)
+{
+#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+
+ s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
+
+ ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
+ s);
+ cfc_handle_events(dev, s);
+#endif
+}
+
+static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
+{
+ unsigned short ack = 0;
+
+ if (a_status & AI_SC_TC_St)
+ ack |= AI_SC_TC_Interrupt_Ack;
+ if (a_status & AI_START1_St)
+ ack |= AI_START1_Interrupt_Ack;
+ if (a_status & AI_START_St)
+ ack |= AI_START_Interrupt_Ack;
+ if (a_status & AI_STOP_St)
+ /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
+ ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */;
+ if (ack)
+ ni_stc_writew(dev, ack, Interrupt_A_Ack_Register);
+}
+
+static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
+ unsigned ai_mite_status)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */
+ if (s->type == COMEDI_SUBD_UNUSED)
+ return;
+
+#ifdef PCIDMA
+ if (ai_mite_status & CHSR_LINKC)
+ ni_sync_ai_dma(dev);
+
+ if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ dev_err(dev->class_dev,
+ "unknown mite interrupt (ai_mite_status=%08x)\n",
+ ai_mite_status);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ /* disable_irq(dev->irq); */
+ }
+#endif
+
+ /* test for all uncommon interrupt events at the same time */
+ if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
+ AI_SC_TC_St | AI_START1_St)) {
+ if (status == 0xffff) {
+ dev_err(dev->class_dev, "Card removed?\n");
+ /* we probably aren't even running a command now,
+ * so it's a good idea to be careful. */
+ if (comedi_is_subdevice_running(s)) {
+ s->async->events |=
+ COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ cfc_handle_events(dev, s);
+ }
+ return;
+ }
+ if (status & (AI_Overrun_St | AI_Overflow_St |
+ AI_SC_TC_Error_St)) {
+ dev_err(dev->class_dev, "ai error a_status=%04x\n",
+ status);
+
+ shutdown_ai_command(dev);
+
+ s->async->events |= COMEDI_CB_ERROR;
+ if (status & (AI_Overrun_St | AI_Overflow_St))
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ cfc_handle_events(dev, s);
+ return;
+ }
+ if (status & AI_SC_TC_St) {
+ if (cmd->stop_src == TRIG_COUNT)
+ shutdown_ai_command(dev);
+ }
+ }
+#ifndef PCIDMA
+ if (status & AI_FIFO_Half_Full_St) {
+ int i;
+ static const int timeout = 10;
+ /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
+ *fail to get the fifo less than half full, so loop to be sure.*/
+ for (i = 0; i < timeout; ++i) {
+ ni_handle_fifo_half_full(dev);
+ if ((ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Half_Full_St) == 0)
+ break;
+ }
+ }
+#endif /* !PCIDMA */
+
+ if ((status & AI_STOP_St))
+ ni_handle_eos(dev, s);
+
+ cfc_handle_events(dev, s);
+}
+
+static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
+{
+ unsigned short ack = 0;
+
+ if (b_status & AO_BC_TC_St)
+ ack |= AO_BC_TC_Interrupt_Ack;
+ if (b_status & AO_Overrun_St)
+ ack |= AO_Error_Interrupt_Ack;
+ if (b_status & AO_START_St)
+ ack |= AO_START_Interrupt_Ack;
+ if (b_status & AO_START1_St)
+ ack |= AO_START1_Interrupt_Ack;
+ if (b_status & AO_UC_TC_St)
+ ack |= AO_UC_TC_Interrupt_Ack;
+ if (b_status & AO_UI2_TC_St)
+ ack |= AO_UI2_TC_Interrupt_Ack;
+ if (b_status & AO_UPDATE_St)
+ ack |= AO_UPDATE_Interrupt_Ack;
+ if (ack)
+ ni_stc_writew(dev, ack, Interrupt_B_Ack_Register);
+}
+
+static void handle_b_interrupt(struct comedi_device *dev,
+ unsigned short b_status, unsigned ao_mite_status)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ /* unsigned short ack=0; */
+
+#ifdef PCIDMA
+ /* Currently, mite.c requires us to handle LINKC */
+ if (ao_mite_status & CHSR_LINKC) {
+ struct ni_private *devpriv = dev->private;
+
+ mite_handle_b_linkc(devpriv->mite, dev);
+ }
+
+ if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ dev_err(dev->class_dev,
+ "unknown mite interrupt (ao_mite_status=%08x)\n",
+ ao_mite_status);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+#endif
+
+ if (b_status == 0xffff)
+ return;
+ if (b_status & AO_Overrun_St) {
+ dev_err(dev->class_dev,
+ "AO FIFO underrun status=0x%04x status2=0x%04x\n",
+ b_status, ni_stc_readw(dev, AO_Status_2_Register));
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+
+ if (b_status & AO_BC_TC_St)
+ s->async->events |= COMEDI_CB_EOA;
+
+#ifndef PCIDMA
+ if (b_status & AO_FIFO_Request_St) {
+ int ret;
+
+ ret = ni_ao_fifo_half_empty(dev, s);
+ if (!ret) {
+ dev_err(dev->class_dev, "AO buffer underrun\n");
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_FIFO_Interrupt_Enable |
+ AO_Error_Interrupt_Enable, 0);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ }
+#endif
+
+ cfc_handle_events(dev, s);
+}
+
static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
unsigned int chan_index)
@@ -1494,16 +1670,14 @@ 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];
+ struct comedi_subdevice *s = dev->read_subdev;
int retval;
unsigned long flags;
retval = ni_request_ai_mite_channel(dev);
if (retval)
return retval;
-/* printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel); */
/* write alloc the entire buffer */
comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
@@ -1514,18 +1688,13 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
return -EIO;
}
- switch (board->reg_type) {
- case ni_reg_611x:
- case ni_reg_6143:
+ if (devpriv->is_611x || devpriv->is_6143)
mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
- break;
- case ni_reg_628x:
+ else if (devpriv->is_628x)
mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
- break;
- default:
+ else
mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
- break;
- }
+
/*start the MITE */
mite_dma_arm(devpriv->ai_mite_chan);
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -1535,9 +1704,8 @@ 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];
+ struct comedi_subdevice *s = dev->write_subdev;
int retval;
unsigned long flags;
@@ -1550,7 +1718,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 (board->reg_type & (ni_reg_611x | ni_reg_6713)) {
+ if (devpriv->is_611x || devpriv->is_6713) {
mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
} else {
/* doing 32 instead of 16 bit wide transfers from memory
@@ -1575,13 +1743,12 @@ 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);
/* ai configuration */
- devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
- Joint_Reset_Register);
+ ni_stc_writew(dev, AI_Configuration_Start | AI_Reset,
+ Joint_Reset_Register);
ni_set_bits(dev, Interrupt_A_Enable_Register,
AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable |
@@ -1591,56 +1758,58 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
ni_clear_ai_fifo(dev);
- if (board->reg_type != ni_reg_6143)
- ni_writeb(0, Misc_Command);
+ if (!devpriv->is_6143)
+ ni_writeb(dev, 0, Misc_Command);
- devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
- devpriv->stc_writew(dev,
- AI_Start_Stop | AI_Mode_1_Reserved
- /*| AI_Trigger_Once */ ,
- AI_Mode_1_Register);
- devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
+ ni_stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
+ ni_stc_writew(dev, AI_Start_Stop | AI_Mode_1_Reserved
+ /*| AI_Trigger_Once */,
+ AI_Mode_1_Register);
+ ni_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 (board->reg_type == ni_reg_611x) {
- devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
- AI_SOC_Polarity |
- AI_LOCALMUX_CLK_Pulse_Width,
- AI_Personal_Register);
- devpriv->stc_writew(dev,
- AI_SCAN_IN_PROG_Output_Select(3) |
- AI_EXTMUX_CLK_Output_Select(0) |
- AI_LOCALMUX_CLK_Output_Select(2) |
- AI_SC_TC_Output_Select(3) |
- AI_CONVERT_Output_Select
- (AI_CONVERT_Output_Enable_High),
- AI_Output_Control_Register);
- } else if (board->reg_type == ni_reg_6143) {
- devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
- AI_SOC_Polarity |
- AI_LOCALMUX_CLK_Pulse_Width,
- AI_Personal_Register);
- devpriv->stc_writew(dev,
- AI_SCAN_IN_PROG_Output_Select(3) |
- AI_EXTMUX_CLK_Output_Select(0) |
- AI_LOCALMUX_CLK_Output_Select(2) |
- AI_SC_TC_Output_Select(3) |
- AI_CONVERT_Output_Select
- (AI_CONVERT_Output_Enable_Low),
- AI_Output_Control_Register);
+ ni_stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
+ if (devpriv->is_611x) {
+ ni_stc_writew(dev,
+ AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width,
+ AI_Personal_Register);
+ ni_stc_writew(dev,
+ AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_High),
+ AI_Output_Control_Register);
+ } else if (devpriv->is_6143) {
+ ni_stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width,
+ AI_Personal_Register);
+ ni_stc_writew(dev,
+ AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_Low),
+ AI_Output_Control_Register);
} else {
unsigned ai_output_control_bits;
- devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
- AI_SOC_Polarity |
- AI_CONVERT_Pulse_Width |
- AI_LOCALMUX_CLK_Pulse_Width,
- AI_Personal_Register);
+
+ ni_stc_writew(dev,
+ AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_CONVERT_Pulse_Width |
+ AI_LOCALMUX_CLK_Pulse_Width,
+ AI_Personal_Register);
ai_output_control_bits =
AI_SCAN_IN_PROG_Output_Select(3) |
AI_EXTMUX_CLK_Output_Select(0) |
AI_LOCALMUX_CLK_Output_Select(2) |
AI_SC_TC_Output_Select(3);
- if (board->reg_type == ni_reg_622x)
+ if (devpriv->is_622x)
ai_output_control_bits |=
AI_CONVERT_Output_Select
(AI_CONVERT_Output_Enable_High);
@@ -1648,8 +1817,8 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
ai_output_control_bits |=
AI_CONVERT_Output_Select
(AI_CONVERT_Output_Enable_Low);
- devpriv->stc_writew(dev, ai_output_control_bits,
- AI_Output_Control_Register);
+ ni_stc_writew(dev, ai_output_control_bits,
+ AI_Output_Control_Register);
}
/* the following registers should not be changed, because there
* are no backup registers in devpriv. If you want to change
@@ -1659,9 +1828,17 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
* AI_Personal_Register
* AI_Output_Control_Register
*/
- devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
-
- devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev,
+ AI_SC_TC_Error_Confirm |
+ AI_START_Interrupt_Ack |
+ AI_START2_Interrupt_Ack |
+ AI_START1_Interrupt_Ack |
+ AI_SC_TC_Interrupt_Ack |
+ AI_Error_Interrupt_Ack |
+ AI_STOP_Interrupt_Ack,
+ Interrupt_A_Ack_Register); /* clear interrupts */
+
+ ni_stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
return 0;
}
@@ -1678,127 +1855,26 @@ static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
#else
ni_sync_ai_dma(dev);
#endif
- count = s->async->buf_write_count - s->async->buf_read_count;
+ count = comedi_buf_n_bytes_ready(s);
spin_unlock_irqrestore(&dev->spinlock, flags);
return count;
}
-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 << board->adbits) - 1;
- unsigned signbits;
- unsigned short d;
- unsigned long dl;
-
- ni_load_channelgain_list(dev, 1, &insn->chanspec);
-
- ni_clear_ai_fifo(dev);
-
- signbits = devpriv->ai_offset[0];
- 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);
- udelay(1);
- }
- for (n = 0; n < insn->n; n++) {
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- /* The 611x has screwy 32-bit FIFOs. */
- d = 0;
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (ni_readb(XXX_Status) & 0x80) {
- d = (ni_readl(ADC_FIFO_Data_611x) >> 16)
- & 0xffff;
- break;
- }
- if (!(devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St)) {
- d = ni_readl(ADC_FIFO_Data_611x) &
- 0xffff;
- break;
- }
- }
- if (i == NI_TIMEOUT) {
- printk
- ("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
- return -ETIME;
- }
- d += signbits;
- data[n] = d;
- }
- } 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);
-
- /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
- dl = 0;
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (ni_readl(AIFIFO_Status_6143) & 0x01) {
- ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
- dl = ni_readl(AIFIFO_Data_6143);
- break;
- }
- }
- if (i == NI_TIMEOUT) {
- printk
- ("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
- return -ETIME;
- }
- data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
- }
- } else {
- for (n = 0; n < insn->n; n++) {
- devpriv->stc_writew(dev, AI_CONVERT_Pulse,
- AI_Command_1_Register);
- for (i = 0; i < NI_TIMEOUT; i++) {
- if (!(devpriv->stc_readw(dev,
- AI_Status_1_Register) &
- AI_FIFO_Empty_St))
- break;
- }
- if (i == NI_TIMEOUT) {
- printk
- ("ni_mio_common: timeout in ni_ai_insn_read\n");
- return -ETIME;
- }
- if (board->reg_type & ni_reg_m_series_mask) {
- data[n] =
- ni_readl(M_Offset_AI_FIFO_Data) & mask;
- } else {
- d = ni_readw(ADC_FIFO_Data_Register);
- d += signbits; /* subtle: needs to be short addition */
- data[n] = d;
- }
- }
- }
- return insn->n;
-}
-
static void ni_prime_channelgain_list(struct comedi_device *dev)
{
- struct ni_private *devpriv = dev->private;
int i;
- devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+ ni_stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
for (i = 0; i < NI_TIMEOUT; ++i) {
- if (!(devpriv->stc_readw(dev,
- AI_Status_1_Register) &
+ if (!(ni_stc_readw(dev, AI_Status_1_Register) &
AI_FIFO_Empty_St)) {
- devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+ ni_stc_writew(dev, 1, ADC_FIFO_Clear);
return;
}
udelay(1);
}
- printk("ni_mio_common: timeout loading channel/gain list\n");
+ dev_err(dev->class_dev, "timeout loading channel/gain list\n");
}
static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
@@ -1809,15 +1885,14 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
struct ni_private *devpriv = dev->private;
unsigned int chan, range, aref;
unsigned int i;
- unsigned offset;
unsigned int dither;
unsigned range_code;
- devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+ ni_stc_writew(dev, 1, Configuration_Memory_Clear);
-/* 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[board->gainlkup][range];
@@ -1835,20 +1910,20 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
/* don't use 2's complement encoding */
bypass_bits |= MSeries_AI_Bypass_Polarity_Bit;
- ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
+ ni_writel(dev, bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
} else {
- ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
+ ni_writel(dev, 0, M_Offset_AI_Config_FIFO_Bypass);
}
- offset = 0;
for (i = 0; i < n_chan; i++) {
unsigned config_bits = 0;
+
chan = CR_CHAN(list[i]);
aref = CR_AREF(list[i]);
range = CR_RANGE(list[i]);
dither = ((list[i] & CR_ALT_FILTER) != 0);
range_code = ni_gainlkup[board->gainlkup][range];
- devpriv->ai_offset[i] = offset;
+ devpriv->ai_offset[i] = 0;
switch (aref) {
case AREF_DIFF:
config_bits |=
@@ -1875,7 +1950,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
config_bits |= MSeries_AI_Config_Dither_Bit;
/* don't use 2's complement encoding */
config_bits |= MSeries_AI_Config_Polarity_Bit;
- ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data);
+ ni_writew(dev, config_bits, M_Offset_AI_Config_FIFO_Data);
}
ni_prime_channelgain_list(dev);
}
@@ -1910,22 +1985,22 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
* valid channels are 0-3
*/
static void ni_load_channelgain_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
unsigned int n_chan, unsigned int *list)
{
const struct ni_board_struct *board = comedi_board(dev);
struct ni_private *devpriv = dev->private;
+ unsigned int offset = (s->maxdata + 1) >> 1;
unsigned int chan, range, aref;
unsigned int i;
unsigned int hi, lo;
- unsigned offset;
unsigned int dither;
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
ni_m_series_load_channelgain_list(dev, n_chan, list);
return;
}
- if (n_chan == 1 && (board->reg_type != ni_reg_611x)
- && (board->reg_type != ni_reg_6143)) {
+ if (n_chan == 1 && !devpriv->is_611x && !devpriv->is_6143) {
if (devpriv->changain_state
&& devpriv->changain_spec == list[0]) {
/* ready to go. */
@@ -1937,61 +2012,58 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
devpriv->changain_state = 0;
}
- devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+ ni_stc_writew(dev, 1, Configuration_Memory_Clear);
/* Set up Calibration mode if required */
- if (board->reg_type == ni_reg_6143) {
+ if (devpriv->is_6143) {
if ((list[0] & CR_ALT_SOURCE)
&& !devpriv->ai_calib_source_enabled) {
/* Strobe Relay enable bit */
- ni_writew(devpriv->ai_calib_source |
- Calibration_Channel_6143_RelayOn,
+ ni_writew(dev, devpriv->ai_calib_source |
+ Calibration_Channel_6143_RelayOn,
Calibration_Channel_6143);
- ni_writew(devpriv->ai_calib_source,
+ ni_writew(dev, devpriv->ai_calib_source,
Calibration_Channel_6143);
devpriv->ai_calib_source_enabled = 1;
msleep_interruptible(100); /* Allow relays to change */
} else if (!(list[0] & CR_ALT_SOURCE)
&& devpriv->ai_calib_source_enabled) {
/* Strobe Relay disable bit */
- ni_writew(devpriv->ai_calib_source |
- Calibration_Channel_6143_RelayOff,
+ ni_writew(dev, devpriv->ai_calib_source |
+ Calibration_Channel_6143_RelayOff,
Calibration_Channel_6143);
- ni_writew(devpriv->ai_calib_source,
+ ni_writew(dev, devpriv->ai_calib_source,
Calibration_Channel_6143);
devpriv->ai_calib_source_enabled = 0;
msleep_interruptible(100); /* Allow relays to change */
}
}
- offset = 1 << (board->adbits - 1);
for (i = 0; i < n_chan; i++) {
- if ((board->reg_type != ni_reg_6143)
- && (list[i] & CR_ALT_SOURCE)) {
+ if (!devpriv->is_6143 && (list[i] & CR_ALT_SOURCE))
chan = devpriv->ai_calib_source;
- } else {
+ else
chan = CR_CHAN(list[i]);
- }
aref = CR_AREF(list[i]);
range = CR_RANGE(list[i]);
dither = ((list[i] & CR_ALT_FILTER) != 0);
/* fix the external/internal range differences */
range = ni_gainlkup[board->gainlkup][range];
- if (board->reg_type == ni_reg_611x)
+ if (devpriv->is_611x)
devpriv->ai_offset[i] = offset;
else
devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
hi = 0;
if ((list[i] & CR_ALT_SOURCE)) {
- if (board->reg_type == ni_reg_611x)
- ni_writew(CR_CHAN(list[i]) & 0x0003,
+ if (devpriv->is_611x)
+ ni_writew(dev, CR_CHAN(list[i]) & 0x0003,
Calibration_Channel_Select_611x);
} else {
- if (board->reg_type == ni_reg_611x)
+ if (devpriv->is_611x)
aref = AREF_DIFF;
- else if (board->reg_type == ni_reg_6143)
+ else if (devpriv->is_6143)
aref = AREF_OTHER;
switch (aref) {
case AREF_DIFF:
@@ -2009,33 +2081,132 @@ static void ni_load_channelgain_list(struct comedi_device *dev,
}
hi |= AI_CONFIG_CHANNEL(chan);
- ni_writew(hi, Configuration_Memory_High);
+ ni_writew(dev, hi, Configuration_Memory_High);
- if (board->reg_type != ni_reg_6143) {
+ if (!devpriv->is_6143) {
lo = range;
if (i == n_chan - 1)
lo |= AI_LAST_CHANNEL;
if (dither)
lo |= AI_DITHER;
- ni_writew(lo, Configuration_Memory_Low);
+ ni_writew(dev, lo, Configuration_Memory_Low);
}
}
/* prime the channel/gain list */
- if ((board->reg_type != ni_reg_611x)
- && (board->reg_type != ni_reg_6143)) {
+ if (!devpriv->is_611x && !devpriv->is_6143)
ni_prime_channelgain_list(dev);
+}
+
+static int ni_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct ni_private *devpriv = dev->private;
+ unsigned int mask = (s->maxdata + 1) >> 1;
+ int i, n;
+ unsigned signbits;
+ unsigned short d;
+ unsigned long dl;
+
+ ni_load_channelgain_list(dev, s, 1, &insn->chanspec);
+
+ ni_clear_ai_fifo(dev);
+
+ signbits = devpriv->ai_offset[0];
+ if (devpriv->is_611x) {
+ for (n = 0; n < num_adc_stages_611x; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ udelay(1);
+ }
+ for (n = 0; n < insn->n; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ /* The 611x has screwy 32-bit FIFOs. */
+ d = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readb(dev, XXX_Status) & 0x80) {
+ d = ni_readl(dev, ADC_FIFO_Data_611x);
+ d >>= 16;
+ d &= 0xffff;
+ break;
+ }
+ if (!(ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St)) {
+ d = ni_readl(dev, ADC_FIFO_Data_611x);
+ d &= 0xffff;
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ dev_err(dev->class_dev, "%s timeout\n",
+ __func__);
+ return -ETIME;
+ }
+ d += signbits;
+ data[n] = d;
+ }
+ } else if (devpriv->is_6143) {
+ for (n = 0; n < insn->n; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+
+ /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
+ dl = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readl(dev, AIFIFO_Status_6143) & 0x01) {
+ /* Get stranded sample into FIFO */
+ ni_writel(dev, 0x01,
+ AIFIFO_Control_6143);
+ dl = ni_readl(dev, AIFIFO_Data_6143);
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ dev_err(dev->class_dev, "%s timeout\n",
+ __func__);
+ return -ETIME;
+ }
+ data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
+ }
+ } else {
+ for (n = 0; n < insn->n; n++) {
+ ni_stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (!(ni_stc_readw(dev, AI_Status_1_Register) &
+ AI_FIFO_Empty_St))
+ break;
+ }
+ if (i == NI_TIMEOUT) {
+ dev_err(dev->class_dev, "%s timeout\n",
+ __func__);
+ return -ETIME;
+ }
+ if (devpriv->is_m_series) {
+ dl = ni_readl(dev, M_Offset_AI_FIFO_Data);
+ dl &= mask;
+ data[n] = dl;
+ } else {
+ d = ni_readw(dev, ADC_FIFO_Data_Register);
+ d += signbits; /* subtle: needs to be short addition */
+ data[n] = d;
+ }
+ }
}
+ return insn->n;
}
static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec,
- int round_mode)
+ unsigned int flags)
{
struct ni_private *devpriv = dev->private;
int divider;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns;
@@ -2061,17 +2232,13 @@ static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
unsigned num_channels)
{
const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
- switch (board->reg_type) {
- case ni_reg_611x:
- case ni_reg_6143:
- /* simultaneously-sampled inputs */
+ /* simultaneously-sampled inputs */
+ if (devpriv->is_611x || devpriv->is_6143)
return board->ai_speed;
- break;
- default:
- /* multiplexed inputs */
- break;
- }
+
+ /* multiplexed inputs */
return board->ai_speed * num_channels;
}
@@ -2095,8 +2262,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
TRIG_TIMER | TRIG_EXT);
sources = TRIG_TIMER | TRIG_EXT;
- if (board->reg_type == ni_reg_611x ||
- board->reg_type == ni_reg_6143)
+ if (devpriv->is_611x || devpriv->is_6143)
sources |= TRIG_NOW;
err |= cfc_check_trigger_src(&cmd->convert_src, sources);
@@ -2153,8 +2319,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
}
if (cmd->convert_src == TRIG_TIMER) {
- if ((board->reg_type == ni_reg_611x)
- || (board->reg_type == ni_reg_6143)) {
+ if (devpriv->is_611x || devpriv->is_6143) {
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
} else {
err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
@@ -2179,7 +2344,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 (board->reg_type == ni_reg_611x)
+ if (devpriv->is_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);
@@ -2198,22 +2363,17 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
cmd->scan_begin_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
cmd->scan_begin_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK));
+ cmd->flags));
if (tmp != cmd->scan_begin_arg)
err++;
}
if (cmd->convert_src == TRIG_TIMER) {
- if ((board->reg_type != ni_reg_611x)
- && (board->reg_type != ni_reg_6143)) {
+ if (!devpriv->is_611x && !devpriv->is_6143) {
tmp = cmd->convert_arg;
cmd->convert_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
cmd->convert_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK));
+ cmd->flags));
if (tmp != cmd->convert_arg)
err++;
if (cmd->scan_begin_src == TRIG_TIMER &&
@@ -2232,9 +2392,25 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
return 0;
}
+static int ni_ai_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
+{
+ struct ni_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
+
+ ni_stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
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;
@@ -2245,29 +2421,30 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
int interrupt_a_enable = 0;
if (dev->irq == 0) {
- comedi_error(dev, "cannot run command without an irq");
+ dev_err(dev->class_dev, "cannot run command without an irq\n");
return -EIO;
}
ni_clear_ai_fifo(dev);
- ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+ ni_load_channelgain_list(dev, s, cmd->chanlist_len, cmd->chanlist);
/* start configuration */
- devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
+ ni_stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
/* disable analog triggering for now, since it
* interferes with the use of pfi0 */
devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
- devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
- Analog_Trigger_Etc_Register);
+ ni_stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
switch (cmd->start_src) {
case TRIG_INT:
case TRIG_NOW:
- devpriv->stc_writew(dev, AI_START2_Select(0) |
- AI_START1_Sync | AI_START1_Edge |
- AI_START1_Select(0),
- AI_Trigger_Select_Register);
+ ni_stc_writew(dev,
+ AI_START2_Select(0) |
+ AI_START1_Sync | AI_START1_Edge |
+ AI_START1_Select(0),
+ AI_Trigger_Select_Register);
break;
case TRIG_EXT:
{
@@ -2279,8 +2456,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
bits |= AI_START1_Polarity;
if (cmd->start_arg & CR_EDGE)
bits |= AI_START1_Edge;
- devpriv->stc_writew(dev, bits,
- AI_Trigger_Select_Register);
+ ni_stc_writew(dev, bits, AI_Trigger_Select_Register);
break;
}
}
@@ -2288,37 +2464,34 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
mode2 &= ~AI_Pre_Trigger;
mode2 &= ~AI_SC_Initial_Load_Source;
mode2 &= ~AI_SC_Reload_Mode;
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
- if (cmd->chanlist_len == 1 || (board->reg_type == ni_reg_611x)
- || (board->reg_type == ni_reg_6143)) {
+ if (cmd->chanlist_len == 1 || devpriv->is_611x || devpriv->is_6143) {
start_stop_select |= AI_STOP_Polarity;
start_stop_select |= AI_STOP_Select(31); /* logic low */
start_stop_select |= AI_STOP_Sync;
} else {
start_stop_select |= AI_STOP_Select(19); /* ai configuration memory */
}
- devpriv->stc_writew(dev, start_stop_select,
- AI_START_STOP_Select_Register);
+ ni_stc_writew(dev, start_stop_select, AI_START_STOP_Select_Register);
devpriv->ai_cmd2 = 0;
switch (cmd->stop_src) {
case TRIG_COUNT:
stop_count = cmd->stop_arg - 1;
- if (board->reg_type == ni_reg_611x) {
+ if (devpriv->is_611x) {
/* have to take 3 stage adc pipeline into account */
stop_count += num_adc_stages_611x;
}
/* stage number of scans */
- devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
+ ni_stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
- devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ ni_stc_writew(dev, mode1, AI_Mode_1_Register);
/* load SC (Scan Count) */
- devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+ ni_stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
- devpriv->ai_continuous = 0;
if (stop_count == 0) {
devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
interrupt_a_enable |= AI_STOP_Interrupt_Enable;
@@ -2330,16 +2503,13 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
break;
case TRIG_NONE:
/* stage number of scans */
- devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers);
+ ni_stc_writel(dev, 0, AI_SC_Load_A_Registers);
mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
- devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ ni_stc_writew(dev, mode1, AI_Mode_1_Register);
/* load SC (Scan Count) */
- devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
-
- devpriv->ai_continuous = 1;
-
+ ni_stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
break;
}
@@ -2360,20 +2530,20 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
AI_STOP_Select=19 external pin (configuration mem)
*/
start_stop_select |= AI_START_Edge | AI_START_Sync;
- devpriv->stc_writew(dev, start_stop_select,
- AI_START_STOP_Select_Register);
+ ni_stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
mode2 |= AI_SI_Reload_Mode(0);
/* AI_SI_Initial_Load_Source=A */
mode2 &= ~AI_SI_Initial_Load_Source;
/* mode2 |= AI_SC_Reload_Mode; */
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
/* load SI */
timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
- devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers);
- devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
+ ni_stc_writel(dev, timer, AI_SI_Load_A_Registers);
+ ni_stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
break;
case TRIG_EXT:
if (cmd->scan_begin_arg & CR_EDGE)
@@ -2387,7 +2557,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
start_stop_select |= AI_START_Sync;
start_stop_select |=
AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
- devpriv->stc_writew(dev, start_stop_select,
+ ni_stc_writew(dev, start_stop_select,
AI_START_STOP_Select_Register);
break;
}
@@ -2400,31 +2570,32 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
else
timer = ni_ns_to_timer(dev, cmd->convert_arg,
TRIG_ROUND_NEAREST);
- devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register); /* 0,0 does not work. */
- devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register);
+ /* 0,0 does not work */
+ ni_stc_writew(dev, 1, AI_SI2_Load_A_Register);
+ ni_stc_writew(dev, timer, AI_SI2_Load_B_Register);
/* AI_SI2_Reload_Mode = alternate */
/* AI_SI2_Initial_Load_Source = A */
mode2 &= ~AI_SI2_Initial_Load_Source;
mode2 |= AI_SI2_Reload_Mode;
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
/* AI_SI2_Load */
- devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
+ ni_stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
mode2 |= AI_SI2_Reload_Mode; /* alternate */
mode2 |= AI_SI2_Initial_Load_Source; /* B */
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
break;
case TRIG_EXT:
mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg);
if ((cmd->convert_arg & CR_INVERT) == 0)
mode1 |= AI_CONVERT_Source_Polarity;
- devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ ni_stc_writew(dev, mode1, AI_Mode_1_Register);
mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
- devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ ni_stc_writew(dev, mode2, AI_Mode_2_Register);
break;
}
@@ -2451,25 +2622,25 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
case AIMODE_HALF_FULL:
/*generate FIFO interrupts and DMA requests on half-full */
#ifdef PCIDMA
- devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_HF_to_E,
+ AI_Mode_3_Register);
#else
- devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
#endif
break;
case AIMODE_SAMPLE:
/*generate FIFO interrupts on non-empty */
- devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
break;
case AIMODE_SCAN:
#ifdef PCIDMA
- devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
#else
- devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
- AI_Mode_3_Register);
+ ni_stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
#endif
interrupt_a_enable |= AI_STOP_Interrupt_Enable;
break;
@@ -2477,7 +2648,16 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
break;
}
- devpriv->stc_writew(dev, AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register); /* clear interrupts */
+ /* clear interrupts */
+ ni_stc_writew(dev,
+ AI_Error_Interrupt_Ack |
+ AI_STOP_Interrupt_Ack |
+ AI_START_Interrupt_Ack |
+ AI_START2_Interrupt_Ack |
+ AI_START1_Interrupt_Ack |
+ AI_SC_TC_Interrupt_Ack |
+ AI_SC_TC_Error_Confirm,
+ Interrupt_A_Ack_Register);
ni_set_bits(dev, Interrupt_A_Enable_Register,
interrupt_a_enable, 1);
@@ -2489,25 +2669,26 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* end configuration */
- devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
switch (cmd->scan_begin_src) {
case TRIG_TIMER:
- devpriv->stc_writew(dev,
- AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
- AI_SC_Arm, AI_Command_1_Register);
+ ni_stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
break;
case TRIG_EXT:
/* XXX AI_SI_Arm? */
- devpriv->stc_writew(dev,
- AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
- AI_SC_Arm, AI_Command_1_Register);
+ ni_stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
break;
}
#ifdef PCIDMA
{
int retval = ni_ai_setup_MITE_dma(dev);
+
if (retval)
return retval;
}
@@ -2515,8 +2696,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
if (cmd->start_src == TRIG_NOW) {
/* AI_START1_Pulse */
- devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
- AI_Command_2_Register);
+ ni_stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
s->async->inttrig = NULL;
} else if (cmd->start_src == TRIG_EXT) {
s->async->inttrig = NULL;
@@ -2527,43 +2708,18 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
-static int ni_ai_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct ni_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
- AI_Command_2_Register);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
-static int ni_ai_config_analog_trig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data);
-
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)
return -EINVAL;
switch (data[0]) {
- case INSN_CONFIG_ANALOG_TRIG:
- return ni_ai_config_analog_trig(dev, s, insn, data);
case INSN_CONFIG_ALT_SOURCE:
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
MSeries_AI_Bypass_Mode_Mux_Mask |
@@ -2571,7 +2727,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
}
devpriv->ai_calib_source = data[1];
- } else if (board->reg_type == ni_reg_6143) {
+ } else if (devpriv->is_6143) {
unsigned int calib_source;
calib_source = data[1] & 0xf;
@@ -2580,7 +2736,7 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
devpriv->ai_calib_source = calib_source;
- ni_writew(calib_source, Calibration_Channel_6143);
+ ni_writew(dev, calib_source, Calibration_Channel_6143);
} else {
unsigned int calib_source;
unsigned int calib_source_adjust;
@@ -2591,8 +2747,8 @@ static int ni_ai_insn_config(struct comedi_device *dev,
if (calib_source >= 8)
return -EINVAL;
devpriv->ai_calib_source = calib_source;
- if (board->reg_type == ni_reg_611x) {
- ni_writeb(calib_source_adjust,
+ if (devpriv->is_611x) {
+ ni_writeb(dev, calib_source_adjust,
Cal_Gain_Select_611x);
}
}
@@ -2604,127 +2760,30 @@ static int ni_ai_insn_config(struct comedi_device *dev,
return -EINVAL;
}
-static int ni_ai_config_analog_trig(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 a, b, modebits;
- int err = 0;
-
- /* data[1] is flags
- * data[2] is analog line
- * data[3] is set level
- * data[4] is reset level */
- 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] >= board->n_adchan) {
- data[2] = board->n_adchan - 1;
- err++;
- }
- if (data[3] > 255) { /* a */
- data[3] = 255;
- err++;
- }
- if (data[4] > 255) { /* b */
- data[4] = 255;
- err++;
- }
- /*
- * 00 ignore
- * 01 set
- * 10 reset
- *
- * modes:
- * 1 level: +b- +a-
- * high mode 00 00 01 10
- * low mode 00 00 10 01
- * 2 level: (a<b)
- * hysteresis low mode 10 00 00 01
- * hysteresis high mode 01 00 00 10
- * middle mode 10 01 01 10
- */
-
- a = data[3];
- b = data[4];
- modebits = data[1] & 0xff;
- if (modebits & 0xf0) {
- /* two level mode */
- if (b < a) {
- /* swap order */
- a = data[4];
- b = data[3];
- modebits =
- ((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >> 4);
- }
- devpriv->atrig_low = a;
- devpriv->atrig_high = b;
- switch (modebits) {
- case 0x81: /* low hysteresis mode */
- devpriv->atrig_mode = 6;
- break;
- case 0x42: /* high hysteresis mode */
- devpriv->atrig_mode = 3;
- break;
- case 0x96: /* middle window mode */
- devpriv->atrig_mode = 2;
- break;
- default:
- data[1] &= ~0xff;
- err++;
- }
- } else {
- /* one level mode */
- if (b != 0) {
- data[4] = 0;
- err++;
- }
- switch (modebits) {
- case 0x06: /* high window mode */
- devpriv->atrig_high = a;
- devpriv->atrig_mode = 0;
- break;
- case 0x09: /* low window mode */
- devpriv->atrig_low = a;
- devpriv->atrig_mode = 1;
- break;
- default:
- data[1] &= ~0xff;
- err++;
- }
- }
- if (err)
- return -EAGAIN;
- return 5;
-}
-
-/* munge data from unsigned to 2's complement for analog output bipolar modes */
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;
- struct comedi_cmd *cmd = &async->cmd;
- unsigned int length = num_bytes / sizeof(short);
- unsigned int offset = 1 << (board->aobits - 1);
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int length = num_bytes / bytes_per_sample(s);
unsigned short *array = data;
- unsigned int range;
unsigned int i;
for (i = 0; i < length; i++) {
- range = CR_RANGE(cmd->chanlist[chan_index]);
- if (board->ao_unipolar == 0 || (range & 1) == 0)
- array[i] -= offset;
+ unsigned int range = CR_RANGE(cmd->chanlist[chan_index]);
+ unsigned short val = array[i];
+
+ /*
+ * Munge data from unsigned to two's complement for
+ * bipolar ranges.
+ */
+ if (comedi_range_is_bipolar(s, range))
+ val = comedi_offset_munge(s, val);
#ifdef PCIDMA
- array[i] = cpu_to_le16(array[i]);
+ val = cpu_to_le16(val);
#endif
+ array[i] = val;
+
chan_index++;
chan_index %= cmd->chanlist_len;
}
@@ -2735,7 +2794,6 @@ 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;
@@ -2744,15 +2802,16 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
int invert = 0;
if (timed) {
- for (i = 0; i < board->n_aochan; ++i) {
+ for (i = 0; i < s->n_chan; ++i) {
devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
- ni_writeb(devpriv->ao_conf[i],
+ ni_writeb(dev, devpriv->ao_conf[i],
M_Offset_AO_Config_Bank(i));
- ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
+ ni_writeb(dev, 0xf, M_Offset_AO_Waveform_Order(i));
}
}
for (i = 0; i < n_chans; i++) {
const struct comedi_krange *krange;
+
chan = CR_CHAN(chanspec[i]);
range = CR_RANGE(chanspec[i]);
krange = s->range_table->range + range;
@@ -2761,25 +2820,28 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
switch (krange->max - krange->min) {
case 20000000:
conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
- ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ ni_writeb(dev, 0,
+ M_Offset_AO_Reference_Attenuation(chan));
break;
case 10000000:
conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
- ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ ni_writeb(dev, 0,
+ M_Offset_AO_Reference_Attenuation(chan));
break;
case 4000000:
conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
- ni_writeb(MSeries_Attenuate_x5_Bit,
+ ni_writeb(dev, MSeries_Attenuate_x5_Bit,
M_Offset_AO_Reference_Attenuation(chan));
break;
case 2000000:
conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
- ni_writeb(MSeries_Attenuate_x5_Bit,
+ ni_writeb(dev, MSeries_Attenuate_x5_Bit,
M_Offset_AO_Reference_Attenuation(chan));
break;
default:
- printk("%s: bug! unhandled ao reference voltage\n",
- __func__);
+ dev_err(dev->class_dev,
+ "%s: bug! unhandled ao reference voltage\n",
+ __func__);
break;
}
switch (krange->max + krange->min) {
@@ -2790,15 +2852,16 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
conf |= MSeries_AO_DAC_Offset_5V_Bits;
break;
default:
- printk("%s: bug! unhandled ao offset voltage\n",
- __func__);
+ dev_err(dev->class_dev,
+ "%s: bug! unhandled ao offset voltage\n",
+ __func__);
break;
}
if (timed)
conf |= MSeries_AO_Update_Timed_Bit;
- ni_writeb(conf, M_Offset_AO_Config_Bank(chan));
+ ni_writeb(dev, conf, M_Offset_AO_Config_Bank(chan));
devpriv->ao_conf[chan] = conf;
- ni_writeb(i, M_Offset_AO_Waveform_Order(chan));
+ ni_writeb(dev, i, M_Offset_AO_Waveform_Order(chan));
}
return invert;
}
@@ -2808,7 +2871,6 @@ 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;
@@ -2821,19 +2883,14 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
range = CR_RANGE(chanspec[i]);
conf = AO_Channel(chan);
- if (board->ao_unipolar) {
- if ((range & 1) == 0) {
- conf |= AO_Bipolar;
- invert = (1 << (board->aobits - 1));
- } else {
- invert = 0;
- }
- if (range & 2)
- conf |= AO_Ext_Ref;
- } else {
+ if (comedi_range_is_bipolar(s, range)) {
conf |= AO_Bipolar;
- invert = (1 << (board->aobits - 1));
+ invert = (s->maxdata + 1) >> 1;
+ } else {
+ invert = 0;
}
+ if (comedi_range_is_external(s, range))
+ conf |= AO_Ext_Ref;
/* not all boards can deglitch, but this shouldn't hurt */
if (chanspec[i] & CR_DEGLITCH)
@@ -2844,7 +2901,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev,
conf |= (CR_AREF(chanspec[i]) ==
AREF_OTHER) ? AO_Ground_Ref : 0;
- ni_writew(conf, AO_Configuration);
+ ni_writew(dev, conf, AO_Configuration);
devpriv->ao_conf[chan] = conf;
}
return invert;
@@ -2855,9 +2912,9 @@ static int ni_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;
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series)
return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
timed);
else
@@ -2865,56 +2922,75 @@ static int ni_ao_config_chanlist(struct comedi_device *dev,
}
static int ni_ao_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s, struct comedi_insn *insn,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
unsigned int *data)
{
struct ni_private *devpriv = dev->private;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ int i;
- data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao[chan];
- return 1;
+ return insn->n;
}
static int ni_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)
{
- 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;
-
- invert = ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
-
- devpriv->ao[chan] = data[0];
-
- 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,
- (chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
+ unsigned int range = CR_RANGE(insn->chanspec);
+ int reg;
+ int i;
- return 1;
-}
+ if (devpriv->is_6xxx) {
+ ni_ao_win_outw(dev, 1 << chan, AO_Immediate_671x);
-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 << (board->aobits - 1);
+ reg = DACx_Direct_Data_671x(chan);
+ } else if (devpriv->is_m_series) {
+ reg = M_Offset_DAC_Direct_Data(chan);
+ } else {
+ reg = (chan) ? DAC1_Direct_Data : DAC0_Direct_Data;
+ }
ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
- devpriv->ao[chan] = data[0];
- ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
+ for (i = 0; i < insn->n; i++) {
+ unsigned int val = data[i];
+
+ devpriv->ao[chan] = val;
+
+ if (devpriv->is_6xxx) {
+ /*
+ * 6xxx boards have bipolar outputs, munge the
+ * unsigned comedi values to 2's complement
+ */
+ val = comedi_offset_munge(s, val);
+
+ ni_ao_win_outw(dev, val, reg);
+ } else if (devpriv->is_m_series) {
+ /*
+ * M-series boards use offset binary values for
+ * bipolar and uinpolar outputs
+ */
+ ni_writew(dev, val, reg);
+ } else {
+ /*
+ * Non-M series boards need two's complement values
+ * for bipolar ranges.
+ */
+ if (comedi_range_is_bipolar(s, range))
+ val = comedi_offset_munge(s, val);
+
+ ni_writew(dev, val, reg);
+ }
+ }
- return 1;
+ return insn->n;
}
static int ni_ao_insn_config(struct comedi_device *dev,
@@ -2937,7 +3013,6 @@ static int ni_ao_insn_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
return 0;
default:
@@ -2951,7 +3026,6 @@ static int ni_ao_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int trig_num)
{
- const struct ni_board_struct *board __maybe_unused = comedi_board(dev);
struct ni_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
int ret;
@@ -2971,8 +3045,8 @@ static int ni_ao_inttrig(struct comedi_device *dev,
AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
interrupt_b_bits = AO_Error_Interrupt_Enable;
#ifdef PCIDMA
- devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
- if (board->reg_type & ni_reg_6xxx_mask)
+ ni_stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (devpriv->is_6xxx)
ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
ret = ni_ao_setup_MITE_dma(dev);
if (ret)
@@ -2988,35 +3062,36 @@ static int ni_ao_inttrig(struct comedi_device *dev,
interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
#endif
- devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
- AO_Mode_3_Register);
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
+ AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
/* wait for DACs to be loaded */
for (i = 0; i < timeout; i++) {
udelay(1);
- if ((devpriv->stc_readw(dev,
- Joint_Status_2_Register) &
+ if ((ni_stc_readw(dev, Joint_Status_2_Register) &
AO_TMRDACWRs_In_Progress_St) == 0)
break;
}
if (i == timeout) {
- comedi_error(dev,
- "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
+ dev_err(dev->class_dev,
+ "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear\n");
return -EIO;
}
- /* stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears */
- devpriv->stc_writew(dev, AO_Error_Interrupt_Ack,
- Interrupt_B_Ack_Register);
+ /*
+ * stc manual says we are need to clear error interrupt after
+ * AO_TMRDACWRs_In_Progress_St clears
+ */
+ ni_stc_writew(dev, AO_Error_Interrupt_Ack, Interrupt_B_Ack_Register);
ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
- devpriv->stc_writew(dev,
- devpriv->ao_cmd1 | AO_UI_Arm | AO_UC_Arm | AO_BC_Arm
- | AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
- AO_Command_1_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd1 |
+ AO_UI_Arm | AO_UC_Arm | AO_BC_Arm |
+ AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
+ AO_Command_1_Register);
- devpriv->stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
- AO_Command_2_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
+ AO_Command_2_Register);
return 0;
}
@@ -3031,16 +3106,16 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned trigvar;
if (dev->irq == 0) {
- comedi_error(dev, "cannot run command without an irq");
+ dev_err(dev->class_dev, "cannot run command without an irq\n");
return -EIO;
}
- devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
- devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+ ni_stc_writew(dev, AO_Disarm, AO_Command_1_Register);
- if (board->reg_type & ni_reg_6xxx_mask) {
- ao_win_out(CLEAR_WG, AO_Misc_611x);
+ if (devpriv->is_6xxx) {
+ ni_ao_win_outw(dev, CLEAR_WG, AO_Misc_611x);
bits = 0;
for (i = 0; i < cmd->chanlist_len; i++) {
@@ -3048,9 +3123,9 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
chan = CR_CHAN(cmd->chanlist[i]);
bits |= 1 << chan;
- ao_win_out(chan, AO_Waveform_Generation_611x);
+ ni_ao_win_outw(dev, chan, AO_Waveform_Generation_611x);
}
- ao_win_out(bits, AO_Timed_611x);
+ ni_ao_win_outw(dev, bits, AO_Timed_611x);
}
ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
@@ -3062,15 +3137,15 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_mode1 &= ~AO_Continuous;
devpriv->ao_mode1 |= AO_Trigger_Once;
}
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
switch (cmd->start_src) {
case TRIG_INT:
case TRIG_NOW:
devpriv->ao_trigger_select &=
~(AO_START1_Polarity | AO_START1_Select(-1));
devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync;
- devpriv->stc_writew(dev, devpriv->ao_trigger_select,
- AO_Trigger_Select_Register);
+ ni_stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
break;
case TRIG_EXT:
devpriv->ao_trigger_select =
@@ -3079,52 +3154,50 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_trigger_select |= AO_START1_Polarity; /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */
if (cmd->start_arg & CR_EDGE)
devpriv->ao_trigger_select |= AO_START1_Edge; /* 0=edge detection disabled, 1=enabled */
- devpriv->stc_writew(dev, devpriv->ao_trigger_select,
- AO_Trigger_Select_Register);
+ ni_stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
break;
default:
BUG();
break;
}
devpriv->ao_mode3 &= ~AO_Trigger_Length;
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
if (cmd->stop_src == TRIG_NONE)
- devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
+ ni_stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
else
- devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register);
- devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, 0, AO_BC_Load_A_Register);
+ ni_stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
switch (cmd->stop_src) {
case TRIG_COUNT:
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
/* 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);
- devpriv->stc_writew(dev, AO_UC_Load,
- AO_Command_1_Register);
+ ni_stc_writel(dev, cmd->stop_arg - 1,
+ AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
} else {
- devpriv->stc_writel(dev, cmd->stop_arg,
- AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load,
- AO_Command_1_Register);
- devpriv->stc_writel(dev, cmd->stop_arg - 1,
- AO_UC_Load_A_Register);
+ ni_stc_writel(dev, cmd->stop_arg,
+ AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, cmd->stop_arg - 1,
+ AO_UC_Load_A_Register);
}
break;
case TRIG_NONE:
- devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
- devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ ni_stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
break;
default:
- devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register);
- devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
- devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+ ni_stc_writel(dev, 0, AO_UC_Load_A_Register);
+ ni_stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
}
devpriv->ao_mode1 &=
@@ -3136,9 +3209,9 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
trigvar =
ni_ns_to_timer(dev, cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
- devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register);
- devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
- devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register);
+ ni_stc_writel(dev, 1, AO_UI_Load_A_Register);
+ ni_stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
+ ni_stc_writel(dev, trigvar, AO_UI_Load_A_Register);
break;
case TRIG_EXT:
devpriv->ao_mode1 |=
@@ -3151,40 +3224,38 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
BUG();
break;
}
- devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
devpriv->ao_mode2 &=
~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source);
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
if (cmd->scan_end_arg > 1) {
devpriv->ao_mode1 |= AO_Multiple_Channels;
- devpriv->stc_writew(dev,
- AO_Number_Of_Channels(cmd->scan_end_arg -
- 1) |
- AO_UPDATE_Output_Select
- (AO_Update_Output_High_Z),
- AO_Output_Control_Register);
+ ni_stc_writew(dev,
+ AO_Number_Of_Channels(cmd->scan_end_arg - 1) |
+ AO_UPDATE_Output_Select(AO_Update_Output_High_Z),
+ AO_Output_Control_Register);
} else {
unsigned bits;
+
devpriv->ao_mode1 &= ~AO_Multiple_Channels;
bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
- if (board->reg_type &
- (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
+ if (devpriv->is_m_series || devpriv->is_6xxx) {
bits |= AO_Number_Of_Channels(0);
} else {
bits |=
AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]));
}
- devpriv->stc_writew(dev, bits, AO_Output_Control_Register);
+ ni_stc_writew(dev, bits, AO_Output_Control_Register);
}
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
- devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
- AO_Command_1_Register);
+ ni_stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
+ AO_Command_1_Register);
devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask;
#ifdef PCIDMA
@@ -3193,7 +3264,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
#endif
devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
- devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
AO_TMRDACWR_Pulse_Width;
@@ -3204,18 +3275,18 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
#if 0
/* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
verified with bus analyzer. */
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series)
bits |= AO_Number_Of_DAC_Packages;
#endif
- devpriv->stc_writew(dev, bits, AO_Personal_Register);
+ ni_stc_writew(dev, bits, AO_Personal_Register);
/* enable sending of ao dma requests */
- devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
+ ni_stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
- devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
if (cmd->stop_src == TRIG_COUNT) {
- devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
- Interrupt_B_Ack_Register);
+ ni_stc_writew(dev, AO_BC_TC_Interrupt_Ack,
+ Interrupt_B_Ack_Register);
ni_set_bits(dev, Interrupt_B_Enable_Register,
AO_BC_TC_Interrupt_Enable, 1);
}
@@ -3299,9 +3370,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
cmd->scan_begin_arg =
ni_timer_to_ns(dev, ni_ns_to_timer(dev,
cmd->scan_begin_arg,
- cmd->
- flags &
- TRIG_ROUND_MASK));
+ cmd->flags));
if (tmp != cmd->scan_begin_arg)
err++;
}
@@ -3313,51 +3382,45 @@ 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; */
- /* ni_writew(devpriv->ao0p,AO_Configuration); */
-
- /* devpriv->ao1p=AO_Channel(1); */
- /* ni_writew(devpriv->ao1p,AO_Configuration); */
-
ni_release_ao_mite_channel(dev);
- devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
- devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+ ni_stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Disarm, AO_Command_1_Register);
ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0);
- devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
- devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
- devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
- AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
- devpriv->stc_writew(dev, 0, AO_Output_Control_Register);
- devpriv->stc_writew(dev, 0, AO_Start_Select_Register);
+ ni_stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
+ ni_stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
+ ni_stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+ AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
+ ni_stc_writew(dev, 0, AO_Output_Control_Register);
+ ni_stc_writew(dev, 0, AO_Start_Select_Register);
devpriv->ao_cmd1 = 0;
- devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
devpriv->ao_cmd2 = 0;
- devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ ni_stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
devpriv->ao_mode1 = 0;
- devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ ni_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 (board->reg_type & ni_reg_m_series_mask)
+ ni_stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ if (devpriv->is_m_series)
devpriv->ao_mode3 = AO_Last_Gate_Disable;
else
devpriv->ao_mode3 = 0;
- devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ ni_stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
devpriv->ao_trigger_select = 0;
- devpriv->stc_writew(dev, devpriv->ao_trigger_select,
- AO_Trigger_Select_Register);
- if (board->reg_type & ni_reg_6xxx_mask) {
+ ni_stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
+ if (devpriv->is_6xxx) {
unsigned immediate_bits = 0;
unsigned i;
+
for (i = 0; i < s->n_chan; ++i)
immediate_bits |= 1 << i;
- ao_win_out(immediate_bits, AO_Immediate_671x);
- ao_win_out(CLEAR_WG, AO_Misc_611x);
+ ni_ao_win_outw(dev, immediate_bits, AO_Immediate_671x);
+ ni_ao_win_outw(dev, CLEAR_WG, AO_Misc_611x);
}
- devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+ ni_stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
return 0;
}
@@ -3378,7 +3441,7 @@ static int ni_dio_insn_config(struct comedi_device *dev,
devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
- devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
return insn->n;
}
@@ -3397,11 +3460,10 @@ static int ni_dio_insn_bits(struct comedi_device *dev,
if (comedi_dio_update_state(s, data)) {
devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
- devpriv->stc_writew(dev, devpriv->dio_output,
- DIO_Output_Register);
+ ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
}
- data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
+ data[1] = ni_stc_readw(dev, DIO_Parallel_Input_Register);
return insn->n;
}
@@ -3411,14 +3473,13 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_private *devpriv __maybe_unused = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- ni_writel(s->io_bits, M_Offset_DIO_Direction);
+ ni_writel(dev, s->io_bits, M_Offset_DIO_Direction);
return insn->n;
}
@@ -3428,12 +3489,10 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct ni_private *devpriv __maybe_unused = dev->private;
-
if (comedi_dio_update_state(s, data))
- ni_writel(s->state, M_Offset_Static_Digital_Output);
+ ni_writel(dev, s->state, M_Offset_Static_Digital_Output);
- data[1] = ni_readl(M_Offset_Static_Digital_Input);
+ data[1] = ni_readl(dev, M_Offset_Static_Digital_Input);
return insn->n;
}
@@ -3508,57 +3567,18 @@ static int ni_cdio_cmdtest(struct comedi_device *dev,
return 0;
}
-static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct ni_private *devpriv __maybe_unused = dev->private;
- const struct comedi_cmd *cmd = &s->async->cmd;
- unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
- int retval;
-
- ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command);
- switch (cmd->scan_begin_src) {
- case TRIG_EXT:
- cdo_mode_bits |=
- CR_CHAN(cmd->scan_begin_arg) &
- CDO_Sample_Source_Select_Mask;
- break;
- default:
- BUG();
- break;
- }
- if (cmd->scan_begin_arg & CR_INVERT)
- cdo_mode_bits |= CDO_Polarity_Bit;
- ni_writel(cdo_mode_bits, M_Offset_CDO_Mode);
- if (s->io_bits) {
- ni_writel(s->state, M_Offset_CDO_FIFO_Data);
- ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command);
- ni_writel(s->io_bits, M_Offset_CDO_Mask_Enable);
- } else {
- comedi_error(dev,
- "attempted to run digital output command with no lines configured as outputs");
- return -EIO;
- }
- retval = ni_request_cdo_mite_channel(dev);
- if (retval < 0)
- return retval;
-
- s->async->inttrig = ni_cdo_inttrig;
-
- return 0;
-}
-
static int ni_cdo_inttrig(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned int trig_num)
{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ const unsigned timeout = 1000;
+ int retval = 0;
+ unsigned i;
#ifdef PCIDMA
struct ni_private *devpriv = dev->private;
unsigned long flags;
#endif
- struct comedi_cmd *cmd = &s->async->cmd;
- int retval = 0;
- unsigned i;
- const unsigned timeout = 1000;
if (trig_num != cmd->start_arg)
return -EINVAL;
@@ -3574,7 +3594,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev,
mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
mite_dma_arm(devpriv->cdo_mite_chan);
} else {
- comedi_error(dev, "BUG: no cdo mite channel?");
+ dev_err(dev->class_dev, "BUG: no cdo mite channel?\n");
retval = -EIO;
}
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -3583,53 +3603,88 @@ static int ni_cdo_inttrig(struct comedi_device *dev,
#endif
/*
* XXX not sure what interrupt C group does
-* ni_writeb(Interrupt_Group_C_Enable_Bit,
+* ni_writeb(dev, Interrupt_Group_C_Enable_Bit,
* M_Offset_Interrupt_C_Enable); wait for dma to fill output fifo
*/
for (i = 0; i < timeout; ++i) {
- if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
+ if (ni_readl(dev, M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
break;
udelay(10);
}
if (i == timeout) {
- comedi_error(dev, "dma failed to fill cdo fifo!");
- ni_cdio_cancel(dev, s);
+ dev_err(dev->class_dev, "dma failed to fill cdo fifo!\n");
+ s->cancel(dev, s);
return -EIO;
}
- ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
- CDO_Empty_FIFO_Interrupt_Enable_Set_Bit,
+ ni_writel(dev, CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Set_Bit,
M_Offset_CDIO_Command);
return retval;
}
-static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- struct ni_private *devpriv __maybe_unused = dev->private;
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
+ int retval;
+
+ ni_writel(dev, CDO_Reset_Bit, M_Offset_CDIO_Command);
+ switch (cmd->scan_begin_src) {
+ case TRIG_EXT:
+ cdo_mode_bits |=
+ CR_CHAN(cmd->scan_begin_arg) &
+ CDO_Sample_Source_Select_Mask;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (cmd->scan_begin_arg & CR_INVERT)
+ cdo_mode_bits |= CDO_Polarity_Bit;
+ ni_writel(dev, cdo_mode_bits, M_Offset_CDO_Mode);
+ if (s->io_bits) {
+ ni_writel(dev, s->state, M_Offset_CDO_FIFO_Data);
+ ni_writel(dev, CDO_SW_Update_Bit, M_Offset_CDIO_Command);
+ ni_writel(dev, s->io_bits, M_Offset_CDO_Mask_Enable);
+ } else {
+ dev_err(dev->class_dev,
+ "attempted to run digital output command with no lines configured as outputs\n");
+ return -EIO;
+ }
+ retval = ni_request_cdo_mite_channel(dev);
+ if (retval < 0)
+ return retval;
+
+ s->async->inttrig = ni_cdo_inttrig;
- ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
- CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
- CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
+ return 0;
+}
+
+static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ ni_writel(dev, CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
+ CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
M_Offset_CDIO_Command);
/*
-* XXX not sure what interrupt C group does ni_writeb(0,
+* XXX not sure what interrupt C group does ni_writeb(dev, 0,
* M_Offset_Interrupt_C_Enable);
*/
- ni_writel(0, M_Offset_CDO_Mask_Enable);
+ ni_writel(dev, 0, M_Offset_CDO_Mask_Enable);
ni_release_cdo_mite_channel(dev);
return 0;
}
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;
+ struct ni_private *devpriv = dev->private;
unsigned cdio_status;
struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV];
#ifdef PCIDMA
unsigned long flags;
#endif
- if ((board->reg_type & ni_reg_m_series_mask) == 0)
+ if (!devpriv->is_m_series)
return;
#ifdef PCIDMA
spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
@@ -3646,112 +3701,21 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
#endif
- cdio_status = ni_readl(M_Offset_CDIO_Status);
+ cdio_status = ni_readl(dev, M_Offset_CDIO_Status);
if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
- /* printk("cdio error: statux=0x%x\n", cdio_status); */
- ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); /* XXX just guessing this is needed and does something useful */
+ /* XXX just guessing this is needed and does something useful */
+ ni_writel(dev, CDO_Error_Interrupt_Confirm_Bit,
+ M_Offset_CDIO_Command);
s->async->events |= COMEDI_CB_OVERFLOW;
}
if (cdio_status & CDO_FIFO_Empty_Bit) {
- /* printk("cdio fifo empty\n"); */
- ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
+ ni_writel(dev, CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
M_Offset_CDIO_Command);
/* s->async->events |= COMEDI_CB_EOA; */
}
cfc_handle_events(dev, s);
}
-static int ni_serial_insn_config(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
- int err = insn->n;
- unsigned char byte_out, byte_in = 0;
-
- if (insn->n != 2)
- return -EINVAL;
-
- switch (data[0]) {
- case INSN_CONFIG_SERIAL_CLOCK:
- devpriv->serial_hw_mode = 1;
- devpriv->dio_control |= DIO_HW_Serial_Enable;
-
- if (data[1] == SERIAL_DISABLED) {
- devpriv->serial_hw_mode = 0;
- devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
- DIO_Software_Serial_Control);
- data[1] = SERIAL_DISABLED;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_600NS) {
- /* Warning: this clock speed is too fast to reliably
- control SCXI. */
- devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
- devpriv->clock_and_fout |= Slow_Internal_Timebase;
- devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
- data[1] = SERIAL_600NS;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_1_2US) {
- devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
- devpriv->clock_and_fout |= Slow_Internal_Timebase |
- DIO_Serial_Out_Divide_By_2;
- data[1] = SERIAL_1_2US;
- devpriv->serial_interval_ns = data[1];
- } else if (data[1] <= SERIAL_10US) {
- devpriv->dio_control |= DIO_HW_Serial_Timebase;
- devpriv->clock_and_fout |= Slow_Internal_Timebase |
- DIO_Serial_Out_Divide_By_2;
- /* Note: DIO_Serial_Out_Divide_By_2 only affects
- 600ns/1.2us. If you turn divide_by_2 off with the
- slow clock, you will still get 10us, except then
- all your delays are wrong. */
- data[1] = SERIAL_10US;
- devpriv->serial_interval_ns = data[1];
- } else {
- devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
- DIO_Software_Serial_Control);
- devpriv->serial_hw_mode = 0;
- data[1] = (data[1] / 1000) * 1000;
- devpriv->serial_interval_ns = data[1];
- }
-
- devpriv->stc_writew(dev, devpriv->dio_control,
- DIO_Control_Register);
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- return 1;
-
- break;
-
- case INSN_CONFIG_BIDIRECTIONAL_DATA:
-
- if (devpriv->serial_interval_ns == 0)
- return -EINVAL;
-
- byte_out = data[1] & 0xFF;
-
- if (devpriv->serial_hw_mode) {
- err = ni_serial_hw_readwrite8(dev, s, byte_out,
- &byte_in);
- } else if (devpriv->serial_interval_ns > 0) {
- err = ni_serial_sw_readwrite8(dev, s, byte_out,
- &byte_in);
- } else {
- printk("ni_serial_insn_config: serial disabled!\n");
- return -EINVAL;
- }
- if (err < 0)
- return err;
- data[1] = byte_in & 0xFF;
- return insn->n;
-
- break;
- default:
- return -EINVAL;
- }
-
-}
-
static int ni_serial_hw_readwrite8(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned char data_out,
@@ -3763,28 +3727,27 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
devpriv->dio_output &= ~DIO_Serial_Data_Mask;
devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
- devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
+ ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
- status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
+ status1 = ni_stc_readw(dev, Joint_Status_1_Register);
if (status1 & DIO_Serial_IO_In_Progress_St) {
err = -EBUSY;
goto Error;
}
devpriv->dio_control |= DIO_HW_Serial_Start;
- devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
devpriv->dio_control &= ~DIO_HW_Serial_Start;
/* Wait until STC says we're done, but don't loop infinitely. */
- while ((status1 =
- devpriv->stc_readw(dev,
- Joint_Status_1_Register)) &
+ while ((status1 = ni_stc_readw(dev, Joint_Status_1_Register)) &
DIO_Serial_IO_In_Progress_St) {
/* Delay one bit per loop */
udelay((devpriv->serial_interval_ns + 999) / 1000);
if (--count < 0) {
- printk
- ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
+ dev_err(dev->class_dev,
+ "%s: SPI serial I/O didn't finish in time!\n",
+ __func__);
err = -ETIME;
goto Error;
}
@@ -3795,10 +3758,10 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev,
udelay((devpriv->serial_interval_ns + 999) / 1000);
if (data_in != NULL)
- *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
+ *data_in = ni_stc_readw(dev, DIO_Serial_Input_Register);
Error:
- devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
return err;
}
@@ -3821,29 +3784,23 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
devpriv->dio_output &= ~DIO_SDOUT;
if (data_out & mask)
devpriv->dio_output |= DIO_SDOUT;
- devpriv->stc_writew(dev, devpriv->dio_output,
- DIO_Output_Register);
+ ni_stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
/* Assert SDCLK (active low, inverted), wait for half of
the delay, deassert SDCLK, and wait for the other half. */
devpriv->dio_control |= DIO_Software_Serial_Control;
- devpriv->stc_writew(dev, devpriv->dio_control,
- DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
udelay((devpriv->serial_interval_ns + 999) / 2000);
devpriv->dio_control &= ~DIO_Software_Serial_Control;
- devpriv->stc_writew(dev, devpriv->dio_control,
- DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
udelay((devpriv->serial_interval_ns + 999) / 2000);
/* Input current bit */
- if (devpriv->stc_readw(dev,
- DIO_Parallel_Input_Register) & DIO_SDIN) {
- /* printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
+ if (ni_stc_readw(dev, DIO_Parallel_Input_Register) & DIO_SDIN)
input |= mask;
- }
}
if (data_in)
@@ -3852,14 +3809,96 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev,
return 0;
}
-static void mio_common_detach(struct comedi_device *dev)
+static int ni_serial_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
+ int err = insn->n;
+ unsigned char byte_out, byte_in = 0;
- if (devpriv) {
- if (devpriv->counter_dev)
- ni_gpct_device_destroy(devpriv->counter_dev);
+ if (insn->n != 2)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SERIAL_CLOCK:
+ devpriv->serial_hw_mode = 1;
+ devpriv->dio_control |= DIO_HW_Serial_Enable;
+
+ if (data[1] == SERIAL_DISABLED) {
+ devpriv->serial_hw_mode = 0;
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ data[1] = SERIAL_DISABLED;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_600NS) {
+ /* Warning: this clock speed is too fast to reliably
+ control SCXI. */
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase;
+ devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_600NS;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_1_2US) {
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_1_2US;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_10US) {
+ devpriv->dio_control |= DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ /* Note: DIO_Serial_Out_Divide_By_2 only affects
+ 600ns/1.2us. If you turn divide_by_2 off with the
+ slow clock, you will still get 10us, except then
+ all your delays are wrong. */
+ data[1] = SERIAL_10US;
+ devpriv->serial_interval_ns = data[1];
+ } else {
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ devpriv->serial_hw_mode = 0;
+ data[1] = (data[1] / 1000) * 1000;
+ devpriv->serial_interval_ns = data[1];
+ }
+
+ ni_stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return 1;
+
+ break;
+
+ case INSN_CONFIG_BIDIRECTIONAL_DATA:
+
+ if (devpriv->serial_interval_ns == 0)
+ return -EINVAL;
+
+ byte_out = data[1] & 0xFF;
+
+ if (devpriv->serial_hw_mode) {
+ err = ni_serial_hw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else if (devpriv->serial_interval_ns > 0) {
+ err = ni_serial_sw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else {
+ dev_err(dev->class_dev, "%s: serial disabled!\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (err < 0)
+ return err;
+ data[1] = byte_in & 0xFF;
+ return insn->n;
+
+ break;
+ default:
+ return -EINVAL;
}
+
}
static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -3870,12 +3909,13 @@ static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
AO_Configuration_2_67xx);
}
- ao_win_out(0x0, AO_Later_Single_Point_Updates);
+ ni_ao_win_outw(dev, 0x0, AO_Later_Single_Point_Updates);
}
static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
{
unsigned stc_register;
+
switch (reg) {
case NITIO_G0_AUTO_INC:
stc_register = G_Autoincrement_Register(0);
@@ -3960,7 +4000,6 @@ static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
__func__, reg);
BUG();
return 0;
- break;
}
return stc_register;
}
@@ -3969,7 +4008,6 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
enum ni_gpct_register reg)
{
struct comedi_device *dev = counter->counter_dev->dev;
- struct ni_private *devpriv = dev->private;
unsigned stc_register;
/* bits in the join reset register which are relevant to counters */
static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
@@ -3981,28 +4019,28 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
switch (reg) {
/* m-series-only registers */
case NITIO_G0_CNT_MODE:
- ni_writew(bits, M_Offset_G0_Counting_Mode);
+ ni_writew(dev, bits, M_Offset_G0_Counting_Mode);
break;
case NITIO_G1_CNT_MODE:
- ni_writew(bits, M_Offset_G1_Counting_Mode);
+ ni_writew(dev, bits, M_Offset_G1_Counting_Mode);
break;
case NITIO_G0_GATE2:
- ni_writew(bits, M_Offset_G0_Second_Gate);
+ ni_writew(dev, bits, M_Offset_G0_Second_Gate);
break;
case NITIO_G1_GATE2:
- ni_writew(bits, M_Offset_G1_Second_Gate);
+ ni_writew(dev, bits, M_Offset_G1_Second_Gate);
break;
case NITIO_G0_DMA_CFG:
- ni_writew(bits, M_Offset_G0_DMA_Config);
+ ni_writew(dev, bits, M_Offset_G0_DMA_Config);
break;
case NITIO_G1_DMA_CFG:
- ni_writew(bits, M_Offset_G1_DMA_Config);
+ ni_writew(dev, bits, M_Offset_G1_DMA_Config);
break;
case NITIO_G0_ABZ:
- ni_writew(bits, M_Offset_G0_MSeries_ABZ);
+ ni_writew(dev, bits, M_Offset_G0_MSeries_ABZ);
break;
case NITIO_G1_ABZ:
- ni_writew(bits, M_Offset_G1_MSeries_ABZ);
+ ni_writew(dev, bits, M_Offset_G1_MSeries_ABZ);
break;
/* 32 bit registers */
@@ -4011,7 +4049,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
case NITIO_G0_LOADB:
case NITIO_G1_LOADB:
stc_register = ni_gpct_to_stc_register(reg);
- devpriv->stc_writel(dev, bits, stc_register);
+ ni_stc_writel(dev, bits, stc_register);
break;
/* 16 bit registers */
@@ -4030,7 +4068,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
/* fall-through */
default:
stc_register = ni_gpct_to_stc_register(reg);
- devpriv->stc_writew(dev, bits, stc_register);
+ ni_stc_writew(dev, bits, stc_register);
}
}
@@ -4038,15 +4076,14 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter,
enum ni_gpct_register reg)
{
struct comedi_device *dev = counter->counter_dev->dev;
- struct ni_private *devpriv = dev->private;
unsigned stc_register;
switch (reg) {
/* m-series only registers */
case NITIO_G0_DMA_STATUS:
- return ni_readw(M_Offset_G0_DMA_Status);
+ return ni_readw(dev, M_Offset_G0_DMA_Status);
case NITIO_G1_DMA_STATUS:
- return ni_readw(M_Offset_G1_DMA_Status);
+ return ni_readw(dev, M_Offset_G1_DMA_Status);
/* 32 bit registers */
case NITIO_G0_HW_SAVE:
@@ -4054,506 +4091,101 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter,
case NITIO_G0_SW_SAVE:
case NITIO_G1_SW_SAVE:
stc_register = ni_gpct_to_stc_register(reg);
- return devpriv->stc_readl(dev, stc_register);
+ return ni_stc_readl(dev, stc_register);
/* 16 bit registers */
default:
stc_register = ni_gpct_to_stc_register(reg);
- return devpriv->stc_readw(dev, stc_register);
- break;
+ return ni_stc_readw(dev, stc_register);
}
return 0;
}
static int ni_freq_out_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 ni_private *devpriv = dev->private;
+ unsigned int val = devpriv->clock_and_fout & FOUT_Divider_mask;
+ int i;
- data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
- return 1;
+ for (i = 0; i < insn->n; i++)
+ data[i] = val;
+
+ return insn->n;
}
static int ni_freq_out_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 ni_private *devpriv = dev->private;
- devpriv->clock_and_fout &= ~FOUT_Enable;
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- devpriv->clock_and_fout &= ~FOUT_Divider_mask;
- devpriv->clock_and_fout |= FOUT_Divider(data[0]);
- devpriv->clock_and_fout |= FOUT_Enable;
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- return insn->n;
-}
+ if (insn->n) {
+ devpriv->clock_and_fout &= ~FOUT_Enable;
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ devpriv->clock_and_fout &= ~FOUT_Divider_mask;
-static int ni_set_freq_out_clock(struct comedi_device *dev,
- unsigned int clock_source)
-{
- struct ni_private *devpriv = dev->private;
+ /* use the last data value to set the fout divider */
+ devpriv->clock_and_fout |= FOUT_Divider(data[insn->n - 1]);
- switch (clock_source) {
- case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
- devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
- break;
- case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
- devpriv->clock_and_fout |= FOUT_Timebase_Select;
- break;
- default:
- return -EINVAL;
- }
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
- return 3;
-}
-
-static void ni_get_freq_out_clock(struct comedi_device *dev,
- unsigned int *clock_source,
- unsigned int *clock_period_ns)
-{
- struct ni_private *devpriv = dev->private;
-
- if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
- *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
- *clock_period_ns = TIMEBASE_2_NS;
- } else {
- *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
- *clock_period_ns = TIMEBASE_1_NS * 2;
+ devpriv->clock_and_fout |= FOUT_Enable;
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
}
+ return insn->n;
}
static int ni_freq_out_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 ni_private *devpriv = dev->private;
+
switch (data[0]) {
case INSN_CONFIG_SET_CLOCK_SRC:
- return ni_set_freq_out_clock(dev, data[1]);
+ switch (data[1]) {
+ case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
+ devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
+ break;
+ case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
+ devpriv->clock_and_fout |= FOUT_Timebase_Select;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ni_stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
break;
case INSN_CONFIG_GET_CLOCK_SRC:
- ni_get_freq_out_clock(dev, &data[1], &data[2]);
- return 3;
- default:
+ if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
+ data[1] = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
+ data[2] = TIMEBASE_2_NS;
+ } else {
+ data[1] = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
+ data[2] = TIMEBASE_1_NS * 2;
+ }
break;
- }
- return -EINVAL;
-}
-
-static int ni_alloc_private(struct comedi_device *dev)
-{
- struct ni_private *devpriv;
-
- devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
- if (!devpriv)
- return -ENOMEM;
-
- spin_lock_init(&devpriv->window_lock);
- spin_lock_init(&devpriv->soft_reg_copy_lock);
- spin_lock_init(&devpriv->mite_channel_lock);
-
- return 0;
-};
-
-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 (board->n_aochan > MAX_N_AO_CHAN) {
- printk("bug! n_aochan > MAX_N_AO_CHAN\n");
+ default:
return -EINVAL;
}
-
- ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES);
- if (ret)
- return ret;
-
- /* analog input subdevice */
-
- s = &dev->subdevices[NI_AI_SUBDEV];
- dev->read_subdev = s;
- if (board->n_adchan) {
- s->type = COMEDI_SUBD_AI;
- s->subdev_flags =
- SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
- if (board->reg_type != ni_reg_611x)
- s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
- if (board->adbits > 16)
- s->subdev_flags |= SDF_LSAMPL;
- if (board->reg_type & ni_reg_m_series_mask)
- s->subdev_flags |= SDF_SOFT_CALIBRATED;
- s->n_chan = board->n_adchan;
- s->len_chanlist = 512;
- 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;
- s->do_cmd = &ni_ai_cmd;
- s->cancel = &ni_ai_reset;
- s->poll = &ni_ai_poll;
- s->munge = &ni_ai_munge;
-#ifdef PCIDMA
- s->async_dma_dir = DMA_FROM_DEVICE;
-#endif
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* analog output subdevice */
-
- s = &dev->subdevices[NI_AO_SUBDEV];
- if (board->n_aochan) {
- s->type = COMEDI_SUBD_AO;
- s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
- if (board->reg_type & ni_reg_m_series_mask)
- s->subdev_flags |= SDF_SOFT_CALIBRATED;
- 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 (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 (board->n_aochan) {
- s->async_dma_dir = DMA_TO_DEVICE;
-#else
- 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 = 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 ((board->reg_type & ni_reg_67xx_mask))
- init_ao_67xx(dev, s);
-
- /* digital i/o subdevice */
-
- s = &dev->subdevices[NI_DIO_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
- s->maxdata = 1;
- s->io_bits = 0; /* all bits input */
- s->range_table = &range_digital;
- 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;
- s->insn_config = &ni_m_series_dio_insn_config;
- s->do_cmd = &ni_cdio_cmd;
- s->do_cmdtest = &ni_cdio_cmdtest;
- s->cancel = &ni_cdio_cancel;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
- s->len_chanlist = s->n_chan;
-
- ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
- ni_writel(s->io_bits, M_Offset_DIO_Direction);
- } else {
- s->insn_bits = &ni_dio_insn_bits;
- s->insn_config = &ni_dio_insn_config;
- devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
- ni_writew(devpriv->dio_control, DIO_Control_Register);
- }
-
- /* 8255 device */
- s = &dev->subdevices[NI_8255_DIO_SUBDEV];
- if (board->has_8255) {
- ret = subdev_8255_init(dev, s, ni_8255_callback,
- (unsigned long)dev);
- if (ret)
- return ret;
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* formerly general purpose counter/timer device, but no longer used */
- s = &dev->subdevices[NI_UNUSED_SUBDEV];
- s->type = COMEDI_SUBD_UNUSED;
-
- /* calibration subdevice -- ai and ao */
- s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
- s->type = COMEDI_SUBD_CALIB;
- 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 (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;
- s->n_chan = 1;
- s->maxdata = 0;
- } else {
- s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
- s->insn_read = &ni_calib_insn_read;
- s->insn_write = &ni_calib_insn_write;
- caldac_setup(dev, s);
- }
-
- /* EEPROM */
- s = &dev->subdevices[NI_EEPROM_SUBDEV];
- s->type = COMEDI_SUBD_MEMORY;
- s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
- s->maxdata = 0xff;
- 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 {
- s->n_chan = 512;
- s->insn_read = &ni_eeprom_insn_read;
- }
-
- /* PFI */
- s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- if (board->reg_type & ni_reg_m_series_mask) {
- unsigned i;
- s->n_chan = 16;
- ni_writew(s->state, M_Offset_PFI_DO);
- for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
- ni_writew(devpriv->pfi_output_select_reg[i],
- M_Offset_PFI_Output_Select(i + 1));
- }
- } else {
- s->n_chan = 10;
- }
- s->maxdata = 1;
- if (board->reg_type & ni_reg_m_series_mask)
- s->insn_bits = &ni_pfi_insn_bits;
- s->insn_config = &ni_pfi_insn_config;
- ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
-
- /* cs5529 calibration adc */
- s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
- 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 = board->n_aochan;
- s->maxdata = (1 << 16) - 1;
- s->range_table = &range_unknown; /* XXX */
- s->insn_read = cs5529_ai_insn_read;
- s->insn_config = NULL;
- init_cs5529(dev);
- } else {
- s->type = COMEDI_SUBD_UNUSED;
- }
-
- /* Serial */
- s = &dev->subdevices[NI_SERIAL_SUBDEV];
- s->type = COMEDI_SUBD_SERIAL;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 1;
- s->maxdata = 0xff;
- s->insn_config = ni_serial_insn_config;
- devpriv->serial_interval_ns = 0;
- devpriv->serial_hw_mode = 0;
-
- /* RTSI */
- s = &dev->subdevices[NI_RTSI_SUBDEV];
- s->type = COMEDI_SUBD_DIO;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
- s->n_chan = 8;
- s->maxdata = 1;
- s->insn_bits = ni_rtsi_insn_bits;
- s->insn_config = ni_rtsi_insn_config;
- ni_rtsi_init(dev);
-
- if (board->reg_type & ni_reg_m_series_mask)
- counter_variant = ni_gpct_variant_m_series;
- else
- counter_variant = ni_gpct_variant_e_series;
- devpriv->counter_dev = ni_gpct_device_construct(dev,
- &ni_gpct_write_register,
- &ni_gpct_read_register,
- counter_variant,
- NUM_GPCT);
- if (!devpriv->counter_dev)
- return -ENOMEM;
-
- /* General purpose counters */
- for (j = 0; j < NUM_GPCT; ++j) {
- s = &dev->subdevices[NI_GPCT_SUBDEV(j)];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
- s->n_chan = 3;
- if (board->reg_type & ni_reg_m_series_mask)
- s->maxdata = 0xffffffff;
- else
- s->maxdata = 0xffffff;
- s->insn_read = ni_tio_insn_read;
- s->insn_write = ni_tio_insn_read;
- s->insn_config = ni_tio_insn_config;
-#ifdef PCIDMA
- s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
- s->do_cmd = &ni_gpct_cmd;
- s->len_chanlist = 1;
- s->do_cmdtest = ni_tio_cmdtest;
- s->cancel = &ni_gpct_cancel;
- s->async_dma_dir = DMA_BIDIRECTIONAL;
-#endif
- s->private = &devpriv->counter_dev->counters[j];
-
- devpriv->counter_dev->counters[j].chip_index = 0;
- devpriv->counter_dev->counters[j].counter_index = j;
- ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
- }
-
- /* Frequency output */
- s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
- s->type = COMEDI_SUBD_COUNTER;
- s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
- s->n_chan = 1;
- s->maxdata = 0xf;
- s->insn_read = &ni_freq_out_insn_read;
- s->insn_write = &ni_freq_out_insn_write;
- s->insn_config = &ni_freq_out_insn_config;
-
- /* ai configuration */
- s = &dev->subdevices[NI_AI_SUBDEV];
- ni_ai_reset(dev, s);
- 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 |
- Slow_Internal_Timebase |
- Clock_To_Board_Divide_By_2 |
- Clock_To_Board |
- AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
- } else {
- devpriv->clock_and_fout =
- Slow_Internal_Time_Divide_By_2 |
- Slow_Internal_Timebase |
- Clock_To_Board_Divide_By_2 | Clock_To_Board;
- }
- devpriv->stc_writew(dev, devpriv->clock_and_fout,
- Clock_and_FOUT_Register);
-
- /* analog output configuration */
- s = &dev->subdevices[NI_AO_SUBDEV];
- ni_ao_reset(dev, s);
-
- if (dev->irq) {
- devpriv->stc_writew(dev,
- (IRQ_POLARITY ? Interrupt_Output_Polarity :
- 0) | (Interrupt_Output_On_3_Pins & 0) |
- Interrupt_A_Enable | Interrupt_B_Enable |
- Interrupt_A_Output_Select(interrupt_pin
- (dev->irq)) |
- Interrupt_B_Output_Select(interrupt_pin
- (dev->irq)),
- Interrupt_Control_Register);
- }
-
- /* DMA setup */
- ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
- ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
-
- if (board->reg_type & ni_reg_6xxx_mask) {
- ni_writeb(0, Magic_611x);
- } else if (board->reg_type & ni_reg_m_series_mask) {
- int 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));
- }
- ni_writeb(0x0, M_Offset_AO_Calibration);
- }
-
- return 0;
+ return insn->n;
}
static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
{
struct comedi_device *dev = (struct comedi_device *)arg;
- struct ni_private *devpriv __maybe_unused = dev->private;
if (dir) {
- ni_writeb(data, Port_A + 2 * port);
+ ni_writeb(dev, data, Port_A + 2 * port);
return 0;
- } else {
- return ni_readb(Port_A + 2 * port);
}
-}
-/*
- presents the EEPROM as a subdevice
-*/
-
-static int ni_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
-
- return 1;
-}
-
-/*
- reads bytes out of eeprom
-*/
-
-static int ni_read_eeprom(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv __maybe_unused = dev->private;
- int bit;
- int bitstring;
-
- bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
- ni_writeb(0x04, Serial_Command);
- for (bit = 0x8000; bit; bit >>= 1) {
- ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
- Serial_Command);
- ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
- Serial_Command);
- }
- bitstring = 0;
- for (bit = 0x80; bit; bit >>= 1) {
- ni_writeb(0x04, Serial_Command);
- ni_writeb(0x05, Serial_Command);
- bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
- }
- ni_writeb(0x00, Serial_Command);
-
- return bitstring;
-}
-
-static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
-{
- struct ni_private *devpriv = dev->private;
-
- data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
-
- return 1;
+ return ni_readb(dev, Port_A + 2 * port);
}
static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
@@ -4567,7 +4199,8 @@ static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
static int ni_m_series_pwm_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
unsigned up_count, down_count;
@@ -4590,7 +4223,6 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
switch (data[3]) {
case TRIG_ROUND_NEAREST:
@@ -4608,7 +4240,6 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
if (up_count * devpriv->clock_ns != data[2] ||
down_count * devpriv->clock_ns != data[4]) {
@@ -4616,26 +4247,24 @@ static int ni_m_series_pwm_config(struct comedi_device *dev,
data[4] = down_count * devpriv->clock_ns;
return -EAGAIN;
}
- ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
- MSeries_Cal_PWM_Low_Time_Bits(down_count),
+ ni_writel(dev, MSeries_Cal_PWM_High_Time_Bits(up_count) |
+ MSeries_Cal_PWM_Low_Time_Bits(down_count),
M_Offset_Cal_PWM);
devpriv->pwm_up_count = up_count;
devpriv->pwm_down_count = down_count;
return 5;
- break;
case INSN_CONFIG_GET_PWM_OUTPUT:
return ni_get_pwm_config(dev, data);
- break;
default:
return -EINVAL;
- break;
}
return 0;
}
static int ni_6143_pwm_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
struct ni_private *devpriv = dev->private;
unsigned up_count, down_count;
@@ -4658,7 +4287,6 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
switch (data[3]) {
case TRIG_ROUND_NEAREST:
@@ -4676,7 +4304,6 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
if (up_count * devpriv->clock_ns != data[2] ||
down_count * devpriv->clock_ns != data[4]) {
@@ -4684,51 +4311,66 @@ static int ni_6143_pwm_config(struct comedi_device *dev,
data[4] = down_count * devpriv->clock_ns;
return -EAGAIN;
}
- ni_writel(up_count, Calibration_HighTime_6143);
+ ni_writel(dev, up_count, Calibration_HighTime_6143);
devpriv->pwm_up_count = up_count;
- ni_writel(down_count, Calibration_LowTime_6143);
+ ni_writel(dev, down_count, Calibration_LowTime_6143);
devpriv->pwm_down_count = down_count;
return 5;
- break;
case INSN_CONFIG_GET_PWM_OUTPUT:
return ni_get_pwm_config(dev, data);
default:
return -EINVAL;
- break;
}
return 0;
}
-static void ni_write_caldac(struct comedi_device *dev, int addr, int val);
-/*
- calibration subdevice
-*/
-static int ni_calib_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int pack_mb88341(int addr, int val, int *bitstring)
{
- ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+ /*
+ Fujitsu MB 88341
+ Note that address bits are reversed. Thanks to
+ Ingo Keen for noticing this.
- return 1;
+ Note also that the 88341 expects address values from
+ 1-12, whereas we use channel numbers 0-11. The NI
+ docs use 1-12, also, so be careful here.
+ */
+ addr++;
+ *bitstring = ((addr & 0x1) << 11) |
+ ((addr & 0x2) << 9) |
+ ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
+ return 12;
}
-static int ni_calib_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int pack_dac8800(int addr, int val, int *bitstring)
{
- struct ni_private *devpriv = dev->private;
+ *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
+ return 11;
+}
- data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+static int pack_dac8043(int addr, int val, int *bitstring)
+{
+ *bitstring = val & 0xfff;
+ return 12;
+}
- return 1;
+static int pack_ad8522(int addr, int val, int *bitstring)
+{
+ *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
+ return 16;
}
-static int pack_mb88341(int addr, int val, int *bitstring);
-static int pack_dac8800(int addr, int val, int *bitstring);
-static int pack_dac8043(int addr, int val, int *bitstring);
-static int pack_ad8522(int addr, int val, int *bitstring);
-static int pack_ad8804(int addr, int val, int *bitstring);
-static int pack_ad8842(int addr, int val, int *bitstring);
+static int pack_ad8804(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
+ return 12;
+}
+
+static int pack_ad8842(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr + 1) << 8) | (val & 0xff);
+ return 12;
+}
struct caldac_struct {
int n_chans;
@@ -4746,6 +4388,64 @@ static struct caldac_struct caldacs[] = {
[ad8804_debug] = {16, 8, pack_ad8804},
};
+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;
+ int type;
+
+ if (devpriv->caldacs[addr] == val)
+ return;
+ devpriv->caldacs[addr] = val;
+
+ for (i = 0; i < 3; i++) {
+ type = board->caldac[i];
+ if (type == caldac_none)
+ break;
+ if (addr < caldacs[type].n_chans) {
+ bits = caldacs[type].packbits(addr, val, &bitstring);
+ loadbit = SerDacLd(i);
+ break;
+ }
+ addr -= caldacs[type].n_chans;
+ }
+
+ for (bit = 1 << (bits - 1); bit; bit >>= 1) {
+ ni_writeb(dev, ((bit & bitstring) ? 0x02 : 0), Serial_Command);
+ udelay(1);
+ ni_writeb(dev, 1 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ udelay(1);
+ }
+ ni_writeb(dev, loadbit, Serial_Command);
+ udelay(1);
+ ni_writeb(dev, 0, Serial_Command);
+}
+
+static int ni_calib_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+
+ return 1;
+}
+
+static int ni_calib_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ struct ni_private *devpriv = dev->private;
+
+ data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
{
const struct ni_board_struct *board = comedi_board(dev);
@@ -4777,7 +4477,8 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
unsigned int *maxdata_list;
if (n_chans > MAX_N_CALDACS)
- printk("BUG! MAX_N_CALDACS too small\n");
+ dev_err(dev->class_dev,
+ "BUG! MAX_N_CALDACS too small\n");
s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
chan = 0;
for (i = 0; i < n_dacs; i++) {
@@ -4800,221 +4501,106 @@ 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)
+static int ni_read_eeprom(struct comedi_device *dev, int addr)
{
- 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;
- int type;
-
- /* printk("ni_write_caldac: chan=%d val=%d\n",addr,val); */
- if (devpriv->caldacs[addr] == val)
- return;
- devpriv->caldacs[addr] = val;
+ int bit;
+ int bitstring;
- for (i = 0; i < 3; i++) {
- type = board->caldac[i];
- if (type == caldac_none)
- break;
- if (addr < caldacs[type].n_chans) {
- bits = caldacs[type].packbits(addr, val, &bitstring);
- loadbit = SerDacLd(i);
- /* printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring); */
- break;
- }
- addr -= caldacs[type].n_chans;
+ bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
+ ni_writeb(dev, 0x04, Serial_Command);
+ for (bit = 0x8000; bit; bit >>= 1) {
+ ni_writeb(dev, 0x04 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ ni_writeb(dev, 0x05 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
}
-
- for (bit = 1 << (bits - 1); bit; bit >>= 1) {
- ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
- udelay(1);
- ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
- udelay(1);
+ bitstring = 0;
+ for (bit = 0x80; bit; bit >>= 1) {
+ ni_writeb(dev, 0x04, Serial_Command);
+ ni_writeb(dev, 0x05, Serial_Command);
+ bitstring |= ((ni_readb(dev, XXX_Status) & PROMOUT) ? bit : 0);
}
- ni_writeb(loadbit, Serial_Command);
- udelay(1);
- ni_writeb(0, Serial_Command);
-}
-
-static int pack_mb88341(int addr, int val, int *bitstring)
-{
- /*
- Fujitsu MB 88341
- Note that address bits are reversed. Thanks to
- Ingo Keen for noticing this.
-
- Note also that the 88341 expects address values from
- 1-12, whereas we use channel numbers 0-11. The NI
- docs use 1-12, also, so be careful here.
- */
- addr++;
- *bitstring = ((addr & 0x1) << 11) |
- ((addr & 0x2) << 9) |
- ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
- return 12;
-}
-
-static int pack_dac8800(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
- return 11;
-}
-
-static int pack_dac8043(int addr, int val, int *bitstring)
-{
- *bitstring = val & 0xfff;
- return 12;
-}
+ ni_writeb(dev, 0x00, Serial_Command);
-static int pack_ad8522(int addr, int val, int *bitstring)
-{
- *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
- return 16;
+ return bitstring;
}
-static int pack_ad8804(int addr, int val, int *bitstring)
+static int ni_eeprom_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
- return 12;
-}
+ data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
-static int pack_ad8842(int addr, int val, int *bitstring)
-{
- *bitstring = ((addr + 1) << 8) | (val & 0xff);
- return 12;
+ return 1;
}
-#if 0
-/*
- * Read the GPCTs current value.
- */
-static int GPCT_G_Watch(struct comedi_device *dev, int chan)
+static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned int hi1, hi2, lo;
-
- devpriv->gpct_command[chan] &= ~G_Save_Trace;
- devpriv->stc_writew(dev, devpriv->gpct_command[chan],
- G_Command_Register(chan));
-
- devpriv->gpct_command[chan] |= G_Save_Trace;
- devpriv->stc_writew(dev, devpriv->gpct_command[chan],
- G_Command_Register(chan));
+ struct ni_private *devpriv = dev->private;
- /* This procedure is used because the two registers cannot
- * be read atomically. */
- do {
- hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
- lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
- hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
- } while (hi1 != hi2);
+ data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
- return (hi1 << 16) | lo;
+ return 1;
}
-static void GPCT_Reset(struct comedi_device *dev, int chan)
+static unsigned ni_old_get_pfi_routing(struct comedi_device *dev,
+ unsigned chan)
{
- int temp_ack_reg = 0;
-
- /* printk("GPCT_Reset..."); */
- devpriv->gpct_cur_operation[chan] = GPCT_RESET;
-
+ /* pre-m-series boards have fixed signals on pfi pins */
switch (chan) {
case 0:
- devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
- ni_set_bits(dev, Interrupt_A_Enable_Register,
- G0_TC_Interrupt_Enable, 0);
- ni_set_bits(dev, Interrupt_A_Enable_Register,
- G0_Gate_Interrupt_Enable, 0);
- temp_ack_reg |= G0_Gate_Error_Confirm;
- temp_ack_reg |= G0_TC_Error_Confirm;
- temp_ack_reg |= G0_TC_Interrupt_Ack;
- temp_ack_reg |= G0_Gate_Interrupt_Ack;
- devpriv->stc_writew(dev, temp_ack_reg,
- Interrupt_A_Ack_Register);
-
- /* problem...this interferes with the other ctr... */
- devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
- devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
- Analog_Trigger_Etc_Register);
- break;
+ return NI_PFI_OUTPUT_AI_START1;
case 1:
- devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
- ni_set_bits(dev, Interrupt_B_Enable_Register,
- G1_TC_Interrupt_Enable, 0);
- ni_set_bits(dev, Interrupt_B_Enable_Register,
- G0_Gate_Interrupt_Enable, 0);
- temp_ack_reg |= G1_Gate_Error_Confirm;
- temp_ack_reg |= G1_TC_Error_Confirm;
- temp_ack_reg |= G1_TC_Interrupt_Ack;
- temp_ack_reg |= G1_Gate_Interrupt_Ack;
- devpriv->stc_writew(dev, temp_ack_reg,
- Interrupt_B_Ack_Register);
-
- devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
- devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
- Analog_Trigger_Etc_Register);
+ return NI_PFI_OUTPUT_AI_START2;
+ case 2:
+ return NI_PFI_OUTPUT_AI_CONVERT;
+ case 3:
+ return NI_PFI_OUTPUT_G_SRC1;
+ case 4:
+ return NI_PFI_OUTPUT_G_GATE1;
+ case 5:
+ return NI_PFI_OUTPUT_AO_UPDATE_N;
+ case 6:
+ return NI_PFI_OUTPUT_AO_START1;
+ case 7:
+ return NI_PFI_OUTPUT_AI_START_PULSE;
+ case 8:
+ return NI_PFI_OUTPUT_G_SRC0;
+ case 9:
+ return NI_PFI_OUTPUT_G_GATE0;
+ default:
+ dev_err(dev->class_dev,
+ "%s: bug, unhandled case in switch.\n", __func__);
break;
}
-
- devpriv->gpct_mode[chan] = 0;
- devpriv->gpct_input_select[chan] = 0;
- devpriv->gpct_command[chan] = 0;
-
- devpriv->gpct_command[chan] |= G_Synchronized_Gate;
-
- devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
- G_Mode_Register(chan));
- devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
- G_Input_Select_Register(chan));
- devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
-
- /* printk("exit GPCT_Reset\n"); */
+ return 0;
}
-#endif
-
-#ifdef PCIDMA
-static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int ni_old_set_pfi_routing(struct comedi_device *dev,
+ unsigned chan, unsigned source)
{
- struct ni_gpct *counter = s->private;
- int retval;
-
- retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
- COMEDI_INPUT);
- if (retval) {
- comedi_error(dev,
- "no dma channel available for use by counter");
- return retval;
- }
- ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
- ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
-
- return ni_tio_cmd(dev, s);
+ /* pre-m-series boards have fixed signals on pfi pins */
+ if (source != ni_old_get_pfi_routing(dev, chan))
+ return -EINVAL;
+ return 2;
}
-#endif
-#ifdef PCIDMA
-static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev,
+ unsigned chan)
{
- struct ni_gpct *counter = s->private;
- int retval;
+ struct ni_private *devpriv = dev->private;
+ const unsigned array_offset = chan / 3;
- retval = ni_tio_cancel(counter);
- ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
- ni_release_gpct_mite_channel(dev, counter->counter_index);
- return retval;
+ return MSeries_PFI_Output_Select_Source(chan,
+ devpriv->pfi_output_select_reg[array_offset]);
}
-#endif
-
-/*
- *
- * Programmable Function Inputs
- *
- */
-static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static int ni_m_series_set_pfi_routing(struct comedi_device *dev,
+ unsigned chan, unsigned source)
{
struct ni_private *devpriv = dev->private;
unsigned pfi_reg_index;
@@ -5028,132 +4614,51 @@ static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
~MSeries_PFI_Output_Select_Mask(chan);
devpriv->pfi_output_select_reg[array_offset] |=
MSeries_PFI_Output_Select_Bits(chan, source);
- ni_writew(devpriv->pfi_output_select_reg[array_offset],
+ ni_writew(dev, devpriv->pfi_output_select_reg[array_offset],
M_Offset_PFI_Output_Select(pfi_reg_index));
return 2;
}
-static int ni_old_set_pfi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
{
- /* pre-m-series boards have fixed signals on pfi pins */
- if (source != ni_old_get_pfi_routing(dev, chan))
- return -EINVAL;
- return 2;
+ struct ni_private *devpriv = dev->private;
+
+ return (devpriv->is_m_series)
+ ? ni_m_series_get_pfi_routing(dev, chan)
+ : ni_old_get_pfi_routing(dev, chan);
}
static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
unsigned source)
{
- 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);
-}
-
-static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev,
- unsigned chan)
-{
struct ni_private *devpriv = dev->private;
- const unsigned array_offset = chan / 3;
-
- return MSeries_PFI_Output_Select_Source(chan,
- devpriv->
- pfi_output_select_reg
- [array_offset]);
-}
-
-static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, unsigned chan)
-{
- /* pre-m-series boards have fixed signals on pfi pins */
- switch (chan) {
- case 0:
- return NI_PFI_OUTPUT_AI_START1;
- break;
- case 1:
- return NI_PFI_OUTPUT_AI_START2;
- break;
- case 2:
- return NI_PFI_OUTPUT_AI_CONVERT;
- break;
- case 3:
- return NI_PFI_OUTPUT_G_SRC1;
- break;
- case 4:
- return NI_PFI_OUTPUT_G_GATE1;
- break;
- case 5:
- return NI_PFI_OUTPUT_AO_UPDATE_N;
- break;
- case 6:
- return NI_PFI_OUTPUT_AO_START1;
- break;
- case 7:
- return NI_PFI_OUTPUT_AI_START_PULSE;
- break;
- case 8:
- return NI_PFI_OUTPUT_G_SRC0;
- break;
- case 9:
- return NI_PFI_OUTPUT_G_GATE0;
- break;
- default:
- printk("%s: bug, unhandled case in switch.\n", __func__);
- break;
- }
- return 0;
-}
-
-static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
-{
- 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);
+ return (devpriv->is_m_series)
+ ? ni_m_series_set_pfi_routing(dev, chan, source)
+ : ni_old_set_pfi_routing(dev, chan, source);
}
-static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
+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;
+ struct ni_private *devpriv = dev->private;
unsigned bits;
- if ((board->reg_type & ni_reg_m_series_mask) == 0)
+ if (!devpriv->is_m_series)
return -ENOTSUPP;
- bits = ni_readl(M_Offset_PFI_Filter);
+
+ bits = ni_readl(dev, M_Offset_PFI_Filter);
bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
- ni_writel(bits, M_Offset_PFI_Filter);
+ ni_writel(dev, bits, M_Offset_PFI_Filter);
return 0;
}
-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 (!(board->reg_type & ni_reg_m_series_mask))
- return -ENOTSUPP;
-
- if (comedi_dio_update_state(s, data))
- ni_writew(s->state, M_Offset_PFI_DO);
-
- data[1] = ni_readw(M_Offset_PFI_DI);
-
- return insn->n;
-}
-
static int ni_pfi_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 ni_private *devpriv = dev->private;
unsigned int chan;
@@ -5175,78 +4680,178 @@ static int ni_pfi_insn_config(struct comedi_device *dev,
(devpriv->io_bidirection_pin_reg & (1 << chan)) ?
COMEDI_OUTPUT : COMEDI_INPUT;
return 0;
- break;
case INSN_CONFIG_SET_ROUTING:
return ni_set_pfi_routing(dev, chan, data[1]);
- break;
case INSN_CONFIG_GET_ROUTING:
data[1] = ni_get_pfi_routing(dev, chan);
break;
case INSN_CONFIG_FILTER:
return ni_config_filter(dev, chan, data[1]);
- break;
default:
return -EINVAL;
}
return 0;
}
-/*
- *
- * NI RTSI Bus Functions
- *
- */
-static void ni_rtsi_init(struct comedi_device *dev)
+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 = dev->private;
- /* Initialises the RTSI bus signal switch to a default state */
+ if (!devpriv->is_m_series)
+ return -ENOTSUPP;
- /* Set clock mode to internal */
- devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
- if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
- printk("ni_set_master_clock failed, bug?");
- /* default internal lines routing to RTSI bus lines */
- devpriv->rtsi_trig_a_output_reg =
- RTSI_Trig_Output_Bits(0,
- NI_RTSI_OUTPUT_ADR_START1) |
- RTSI_Trig_Output_Bits(1,
- NI_RTSI_OUTPUT_ADR_START2) |
- RTSI_Trig_Output_Bits(2,
- NI_RTSI_OUTPUT_SCLKG) |
- RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
- RTSI_Trig_A_Output_Register);
- devpriv->rtsi_trig_b_output_reg =
- RTSI_Trig_Output_Bits(4,
- NI_RTSI_OUTPUT_DA_START1) |
- RTSI_Trig_Output_Bits(5,
- NI_RTSI_OUTPUT_G_SRC0) |
- RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0);
- 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,
- RTSI_Trig_B_Output_Register);
+ if (comedi_dio_update_state(s, data))
+ ni_writew(dev, s->state, M_Offset_PFI_DO);
-/*
-* Sets the source and direction of the 4 on board lines
-* devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
-*/
+ data[1] = ni_readw(dev, M_Offset_PFI_DI);
+
+ return insn->n;
}
-static int ni_rtsi_insn_bits(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+static int cs5529_wait_for_idle(struct comedi_device *dev)
{
- data[1] = 0;
+ unsigned short status;
+ const int timeout = HZ;
+ int i;
+ for (i = 0; i < timeout; i++) {
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if ((status & CSS_ADC_BUSY) == 0)
+ break;
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(1))
+ return -EIO;
+ }
+ if (i == timeout) {
+ dev_err(dev->class_dev, "%s timeout\n", __func__);
+ return -ETIME;
+ }
+ return 0;
+}
+
+static void cs5529_command(struct comedi_device *dev, unsigned short value)
+{
+ static const int timeout = 100;
+ int i;
+
+ ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
+ /* give time for command to start being serially clocked into cs5529.
+ * this insures that the CSS_ADC_BUSY bit will get properly
+ * set before we exit this function.
+ */
+ for (i = 0; i < timeout; i++) {
+ if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
+ break;
+ udelay(1);
+ }
+ if (i == timeout)
+ dev_err(dev->class_dev,
+ "possible problem - never saw adc go busy?\n");
+}
+
+static int cs5529_do_conversion(struct comedi_device *dev,
+ unsigned short *data)
+{
+ int retval;
+ unsigned short status;
+
+ cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
+ retval = cs5529_wait_for_idle(dev);
+ if (retval) {
+ dev_err(dev->class_dev,
+ "timeout or signal in cs5529_do_conversion()\n");
+ return -ETIME;
+ }
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if (status & CSS_OSC_DETECT) {
+ dev_err(dev->class_dev,
+ "cs5529 conversion error, status CSS_OSC_DETECT\n");
+ return -EIO;
+ }
+ if (status & CSS_OVERRANGE) {
+ dev_err(dev->class_dev,
+ "cs5529 conversion error, overrange (ignoring)\n");
+ }
+ if (data) {
+ *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
+ /* cs5529 returns 16 bit signed data in bipolar mode */
+ *data ^= (1 << 15);
+ }
+ return 0;
+}
+
+static int cs5529_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ int n, retval;
+ unsigned short sample;
+ unsigned int channel_select;
+ const unsigned int INTERNAL_REF = 0x1000;
+
+ /* Set calibration adc source. Docs lie, reference select bits 8 to 11
+ * do nothing. bit 12 seems to chooses internal reference voltage, bit
+ * 13 causes the adc input to go overrange (maybe reads external reference?) */
+ if (insn->chanspec & CR_ALT_SOURCE)
+ channel_select = INTERNAL_REF;
+ else
+ channel_select = CR_CHAN(insn->chanspec);
+ ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+
+ for (n = 0; n < insn->n; n++) {
+ retval = cs5529_do_conversion(dev, &sample);
+ if (retval < 0)
+ return retval;
+ data[n] = sample;
+ }
return insn->n;
}
-/* Find best multiplier/divider to try and get the PLL running at 80 MHz
- * given an arbitrary frequency input clock */
+static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
+ unsigned int reg_select_bits)
+{
+ ni_ao_win_outw(dev, ((value >> 16) & 0xff),
+ CAL_ADC_Config_Data_High_Word_67xx);
+ ni_ao_win_outw(dev, (value & 0xffff),
+ CAL_ADC_Config_Data_Low_Word_67xx);
+ reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+ cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
+ if (cs5529_wait_for_idle(dev))
+ dev_err(dev->class_dev,
+ "timeout or signal in %s\n", __func__);
+}
+
+static int init_cs5529(struct comedi_device *dev)
+{
+ unsigned int config_bits =
+ CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+
+#if 1
+ /* do self-calibration */
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
+ CSCMD_CONFIG_REGISTER);
+ /* need to force a conversion for calibration to run */
+ cs5529_do_conversion(dev, NULL);
+#else
+ /* force gain calibration to 1 */
+ cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
+ CSCMD_CONFIG_REGISTER);
+ if (cs5529_wait_for_idle(dev))
+ dev_err(dev->class_dev,
+ "timeout or signal in %s\n", __func__);
+#endif
+ return 0;
+}
+
+/*
+ * Find best multiplier/divider to try and get the PLL running at 80 MHz
+ * given an arbitrary frequency input clock.
+ */
static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
unsigned *freq_divider,
unsigned *freq_multiplier,
@@ -5266,6 +4871,7 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
static const unsigned target_picosec = 12500;
static const unsigned fudge_factor_80_to_20Mhz = 4;
int best_period_picosec = 0;
+
for (div = 1; div <= max_div; ++div) {
for (mult = 1; mult <= max_mult; ++mult) {
unsigned new_period_ps =
@@ -5278,10 +4884,9 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
}
}
}
- if (best_period_picosec == 0) {
- printk("%s: bug, failed to find pll parameters\n", __func__);
+ if (best_period_picosec == 0)
return -EIO;
- }
+
*freq_divider = best_div;
*freq_multiplier = best_mult;
*actual_period_ns =
@@ -5290,16 +4895,6 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
return 0;
}
-static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
-{
- const struct ni_board_struct *board = comedi_board(dev);
-
- if (board->reg_type & ni_reg_m_series_mask)
- return 8;
- else
- return 7;
-}
-
static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
unsigned source, unsigned period_ns)
{
@@ -5317,15 +4912,14 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
period_ns = 100;
/* these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that */
if (period_ns < min_period_ns || period_ns > max_period_ns) {
- printk
- ("%s: you must specify an input clock frequency between %i and %i nanosec "
- "for the phased-lock loop.\n", __func__,
- min_period_ns, max_period_ns);
+ dev_err(dev->class_dev,
+ "%s: you must specify an input clock frequency between %i and %i nanosec for the phased-lock loop\n",
+ __func__, min_period_ns, max_period_ns);
return -EINVAL;
}
devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
pll_control_bits =
MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
devpriv->clock_and_fout2 |=
@@ -5335,26 +4929,17 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
devpriv->clock_and_fout2 |=
MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
- retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
- &freq_multiplier,
- &devpriv->clock_ns);
- if (retval < 0)
- return retval;
break;
case NI_MIO_PLL_PXI10_CLOCK:
/* pxi clock is 10MHz */
devpriv->clock_and_fout2 |=
MSeries_PLL_In_Source_Select_PXI_Clock10;
- retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
- &freq_multiplier,
- &devpriv->clock_ns);
- if (retval < 0)
- return retval;
break;
default:
{
unsigned rtsi_channel;
static const unsigned max_rtsi_channel = 7;
+
for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
++rtsi_channel) {
if (source ==
@@ -5367,81 +4952,78 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
}
if (rtsi_channel > max_rtsi_channel)
return -EINVAL;
- retval = ni_mseries_get_pll_parameters(period_ns,
- &freq_divider,
- &freq_multiplier,
- &devpriv->
- clock_ns);
- if (retval < 0)
- return retval;
}
break;
}
- ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
+ retval = ni_mseries_get_pll_parameters(period_ns,
+ &freq_divider,
+ &freq_multiplier,
+ &devpriv->clock_ns);
+ if (retval < 0) {
+ dev_err(dev->class_dev,
+ "%s: bug, failed to find pll parameters\n", __func__);
+ return retval;
+ }
+
+ ni_writew(dev, devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
pll_control_bits |=
MSeries_PLL_Divisor_Bits(freq_divider) |
MSeries_PLL_Multiplier_Bits(freq_multiplier);
- /* printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n",
- * freq_divider, freq_multiplier, pll_control_bits); */
- /* printk("clock_ns=%d\n", devpriv->clock_ns); */
- ni_writew(pll_control_bits, M_Offset_PLL_Control);
+ ni_writew(dev, pll_control_bits, M_Offset_PLL_Control);
devpriv->clock_source = source;
/* it seems to typically take a few hundred microseconds for PLL to lock */
for (i = 0; i < timeout; ++i) {
- if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit)
+ if (ni_readw(dev, M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit)
break;
udelay(1);
}
if (i == timeout) {
- printk
- ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
- __func__, source, period_ns);
+ dev_err(dev->class_dev,
+ "%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns\n",
+ __func__, source, period_ns);
return -ETIMEDOUT;
}
return 3;
}
-static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
- unsigned period_ns)
+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) {
devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
devpriv->clock_ns = TIMEBASE_1_NS;
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
devpriv->clock_and_fout2 &=
~(MSeries_Timebase1_Select_Bit |
MSeries_Timebase3_Select_Bit);
- ni_writew(devpriv->clock_and_fout2,
+ ni_writew(dev, devpriv->clock_and_fout2,
M_Offset_Clock_and_Fout2);
- ni_writew(0, M_Offset_PLL_Control);
+ ni_writew(dev, 0, M_Offset_PLL_Control);
}
devpriv->clock_source = source;
} else {
- if (board->reg_type & ni_reg_m_series_mask) {
+ if (devpriv->is_m_series) {
return ni_mseries_set_pll_master_clock(dev, source,
period_ns);
} else {
if (source == NI_MIO_RTSI_CLOCK) {
devpriv->rtsi_trig_direction_reg |=
Use_RTSI_Clock_Bit;
- devpriv->stc_writew(dev,
- devpriv->
- rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev,
+ devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
if (period_ns == 0) {
- printk
- ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
- __func__);
+ dev_err(dev->class_dev,
+ "%s: we don't handle an unspecified clock period correctly yet, returning error\n",
+ __func__);
return -EINVAL;
- } else {
- devpriv->clock_ns = period_ns;
}
+ devpriv->clock_ns = period_ns;
devpriv->clock_source = source;
} else
return -EINVAL;
@@ -5450,21 +5032,27 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
return 3;
}
-static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
{
- const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
+
+ return (devpriv->is_m_series) ? 8 : 7;
+}
+
+static int ni_valid_rtsi_output_source(struct comedi_device *dev,
+ unsigned chan, unsigned source)
+{
+ struct ni_private *devpriv = dev->private;
if (chan >= num_configurable_rtsi_channels(dev)) {
if (chan == old_RTSI_clock_channel) {
if (source == NI_RTSI_OUTPUT_RTSI_OSC)
return 1;
- else {
- printk
- ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
- __func__, chan, old_RTSI_clock_channel);
- return 0;
- }
+
+ dev_err(dev->class_dev,
+ "%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards\n",
+ __func__, chan, old_RTSI_clock_channel);
+ return 0;
}
return 0;
}
@@ -5479,21 +5067,15 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
case NI_RTSI_OUTPUT_RGOUT0:
case NI_RTSI_OUTPUT_RTSI_BRD_0:
return 1;
- break;
case NI_RTSI_OUTPUT_RTSI_OSC:
- if (board->reg_type & ni_reg_m_series_mask)
- return 1;
- else
- return 0;
- break;
+ return (devpriv->is_m_series) ? 1 : 0;
default:
return 0;
- break;
}
}
-static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
- unsigned source)
+static int ni_set_rtsi_routing(struct comedi_device *dev,
+ unsigned chan, unsigned source)
{
struct ni_private *devpriv = dev->private;
@@ -5503,14 +5085,14 @@ static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
devpriv->rtsi_trig_a_output_reg |=
RTSI_Trig_Output_Bits(chan, source);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
- RTSI_Trig_A_Output_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
} else if (chan < 8) {
devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
devpriv->rtsi_trig_b_output_reg |=
RTSI_Trig_Output_Bits(chan, source);
- devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
- RTSI_Trig_B_Output_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
}
return 2;
}
@@ -5528,16 +5110,17 @@ static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan)
} else {
if (chan == old_RTSI_clock_channel)
return NI_RTSI_OUTPUT_RTSI_OSC;
- printk("%s: bug! should never get here?\n", __func__);
+ dev_err(dev->class_dev, "%s: bug! should never get here?\n",
+ __func__);
return 0;
}
}
static int ni_rtsi_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ 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);
@@ -5545,33 +5128,30 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
case INSN_CONFIG_DIO_OUTPUT:
if (chan < num_configurable_rtsi_channels(dev)) {
devpriv->rtsi_trig_direction_reg |=
- RTSI_Output_Bit(chan,
- (board->reg_type & ni_reg_m_series_mask) != 0);
+ RTSI_Output_Bit(chan, devpriv->is_m_series);
} else if (chan == old_RTSI_clock_channel) {
devpriv->rtsi_trig_direction_reg |=
Drive_RTSI_Clock_Bit;
}
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
break;
case INSN_CONFIG_DIO_INPUT:
if (chan < num_configurable_rtsi_channels(dev)) {
devpriv->rtsi_trig_direction_reg &=
- ~RTSI_Output_Bit(chan,
- (board->reg_type & ni_reg_m_series_mask) != 0);
+ ~RTSI_Output_Bit(chan, devpriv->is_m_series);
} else if (chan == old_RTSI_clock_channel) {
devpriv->rtsi_trig_direction_reg &=
~Drive_RTSI_Clock_Bit;
}
- devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
- RTSI_Trig_Direction_Register);
+ ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
break;
case INSN_CONFIG_DIO_QUERY:
if (chan < num_configurable_rtsi_channels(dev)) {
data[1] =
(devpriv->rtsi_trig_direction_reg &
- RTSI_Output_Bit(chan,
- (board->reg_type & ni_reg_m_series_mask) != 0))
+ RTSI_Output_Bit(chan, devpriv->is_m_series))
? INSN_CONFIG_DIO_OUTPUT
: INSN_CONFIG_DIO_INPUT;
} else if (chan == old_RTSI_clock_channel) {
@@ -5581,160 +5161,600 @@ static int ni_rtsi_insn_config(struct comedi_device *dev,
? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT;
}
return 2;
- break;
case INSN_CONFIG_SET_CLOCK_SRC:
return ni_set_master_clock(dev, data[1], data[2]);
- break;
case INSN_CONFIG_GET_CLOCK_SRC:
data[1] = devpriv->clock_source;
data[2] = devpriv->clock_ns;
return 3;
- break;
case INSN_CONFIG_SET_ROUTING:
return ni_set_rtsi_routing(dev, chan, data[1]);
- break;
case INSN_CONFIG_GET_ROUTING:
data[1] = ni_get_rtsi_routing(dev, chan);
return 2;
- break;
default:
return -EINVAL;
- break;
}
return 1;
}
-static int cs5529_wait_for_idle(struct comedi_device *dev)
+static int ni_rtsi_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- unsigned short status;
- const int timeout = HZ;
- int i;
+ data[1] = 0;
- for (i = 0; i < timeout; i++) {
- status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
- if ((status & CSS_ADC_BUSY) == 0)
- break;
- set_current_state(TASK_INTERRUPTIBLE);
- if (schedule_timeout(1))
- return -EIO;
+ return insn->n;
+}
+
+static void ni_rtsi_init(struct comedi_device *dev)
+{
+ struct ni_private *devpriv = dev->private;
+
+ /* Initialises the RTSI bus signal switch to a default state */
+
+ /* Set clock mode to internal */
+ devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
+ if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
+ dev_err(dev->class_dev, "ni_set_master_clock failed, bug?\n");
+ /* default internal lines routing to RTSI bus lines */
+ devpriv->rtsi_trig_a_output_reg =
+ RTSI_Trig_Output_Bits(0,
+ NI_RTSI_OUTPUT_ADR_START1) |
+ RTSI_Trig_Output_Bits(1,
+ NI_RTSI_OUTPUT_ADR_START2) |
+ RTSI_Trig_Output_Bits(2,
+ NI_RTSI_OUTPUT_SCLKG) |
+ RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN);
+ ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
+ devpriv->rtsi_trig_b_output_reg =
+ RTSI_Trig_Output_Bits(4,
+ NI_RTSI_OUTPUT_DA_START1) |
+ RTSI_Trig_Output_Bits(5,
+ NI_RTSI_OUTPUT_G_SRC0) |
+ RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0);
+ if (devpriv->is_m_series)
+ devpriv->rtsi_trig_b_output_reg |=
+ RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
+ ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
+
+/*
+* Sets the source and direction of the 4 on board lines
+* ni_stc_writew(dev, 0x0000, RTSI_Board_Register);
+*/
+}
+
+#ifdef PCIDMA
+static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct ni_gpct *counter = s->private;
+ int retval;
+
+ retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
+ COMEDI_INPUT);
+ if (retval) {
+ dev_err(dev->class_dev,
+ "no dma channel available for use by counter\n");
+ return retval;
}
-/* printk("looped %i times waiting for idle\n", i); */
- if (i == timeout) {
- printk("%s: %s: timeout\n", __FILE__, __func__);
- return -ETIME;
+ ni_tio_acknowledge(counter);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
+
+ return ni_tio_cmd(dev, s);
+}
+
+static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct ni_gpct *counter = s->private;
+ int retval;
+
+ retval = ni_tio_cancel(counter);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
+ ni_release_gpct_mite_channel(dev, counter->counter_index);
+ return retval;
+}
+#endif
+
+#if 0
+/*
+ * Read the GPCTs current value.
+ */
+static int GPCT_G_Watch(struct comedi_device *dev, int chan)
+{
+ unsigned int hi1, hi2, lo;
+
+ devpriv->gpct_command[chan] &= ~G_Save_Trace;
+ ni_stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ devpriv->gpct_command[chan] |= G_Save_Trace;
+ ni_stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ /* This procedure is used because the two registers cannot
+ * be read atomically. */
+ do {
+ hi1 = ni_stc_readw(dev, G_Save_Register_High(chan));
+ lo = ni_stc_readw(dev, G_Save_Register_Low(chan));
+ hi2 = ni_stc_readw(dev, G_Save_Register_High(chan));
+ } while (hi1 != hi2);
+
+ return (hi1 << 16) | lo;
+}
+
+static void GPCT_Reset(struct comedi_device *dev, int chan)
+{
+ int temp_ack_reg = 0;
+
+ devpriv->gpct_cur_operation[chan] = GPCT_RESET;
+
+ switch (chan) {
+ case 0:
+ ni_stc_writew(dev, G0_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G0_Gate_Error_Confirm;
+ temp_ack_reg |= G0_TC_Error_Confirm;
+ temp_ack_reg |= G0_TC_Interrupt_Ack;
+ temp_ack_reg |= G0_Gate_Interrupt_Ack;
+ ni_stc_writew(dev, temp_ack_reg, Interrupt_A_Ack_Register);
+
+ /* problem...this interferes with the other ctr... */
+ devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
+ ni_stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
+ case 1:
+ ni_stc_writew(dev, G1_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G1_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G1_Gate_Error_Confirm;
+ temp_ack_reg |= G1_TC_Error_Confirm;
+ temp_ack_reg |= G1_TC_Interrupt_Ack;
+ temp_ack_reg |= G1_Gate_Interrupt_Ack;
+ ni_stc_writew(dev, temp_ack_reg, Interrupt_B_Ack_Register);
+
+ devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
+ ni_stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
}
- return 0;
+
+ devpriv->gpct_mode[chan] = 0;
+ devpriv->gpct_input_select[chan] = 0;
+ devpriv->gpct_command[chan] = 0;
+
+ devpriv->gpct_command[chan] |= G_Synchronized_Gate;
+
+ ni_stc_writew(dev, devpriv->gpct_mode[chan], G_Mode_Register(chan));
+ ni_stc_writew(dev, devpriv->gpct_input_select[chan],
+ G_Input_Select_Register(chan));
+ ni_stc_writew(dev, 0, G_Autoincrement_Register(chan));
}
+#endif
-static void cs5529_command(struct comedi_device *dev, unsigned short value)
+static irqreturn_t ni_E_interrupt(int irq, void *d)
{
- static const int timeout = 100;
- int i;
+ struct comedi_device *dev = d;
+ unsigned short a_status;
+ unsigned short b_status;
+ unsigned int ai_mite_status = 0;
+ unsigned int ao_mite_status = 0;
+ unsigned long flags;
+#ifdef PCIDMA
+ struct ni_private *devpriv = dev->private;
+ struct mite_struct *mite = devpriv->mite;
+#endif
- ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
- /* give time for command to start being serially clocked into cs5529.
- * this insures that the CSS_ADC_BUSY bit will get properly
- * set before we exit this function.
- */
- for (i = 0; i < timeout; i++) {
- if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
- break;
- udelay(1);
+ if (!dev->attached)
+ return IRQ_NONE;
+ smp_mb(); /* make sure dev->attached is checked before handler does anything else. */
+
+ /* lock to avoid race with comedi_poll */
+ spin_lock_irqsave(&dev->spinlock, flags);
+ a_status = ni_stc_readw(dev, AI_Status_1_Register);
+ b_status = ni_stc_readw(dev, AO_Status_1_Register);
+#ifdef PCIDMA
+ if (mite) {
+ struct ni_private *devpriv = dev->private;
+ unsigned long flags_too;
+
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
+ if (devpriv->ai_mite_chan) {
+ ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
+ if (ai_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ devpriv->mite->mite_io_addr +
+ MITE_CHOR(devpriv->
+ ai_mite_chan->channel));
+ }
+ if (devpriv->ao_mite_chan) {
+ ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
+ if (ao_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ mite->mite_io_addr +
+ MITE_CHOR(devpriv->
+ ao_mite_chan->channel));
+ }
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
}
-/* printk("looped %i times writing command to cs5529\n", i); */
- if (i == timeout)
- comedi_error(dev, "possible problem - never saw adc go busy?");
+#endif
+ ack_a_interrupt(dev, a_status);
+ ack_b_interrupt(dev, b_status);
+ if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
+ handle_a_interrupt(dev, a_status, ai_mite_status);
+ if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
+ handle_b_interrupt(dev, b_status, ao_mite_status);
+ handle_gpct_interrupt(dev, 0);
+ handle_gpct_interrupt(dev, 1);
+ handle_cdio_interrupt(dev);
+
+ spin_unlock_irqrestore(&dev->spinlock, flags);
+ return IRQ_HANDLED;
}
-/* write to cs5529 register */
-static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
- unsigned int reg_select_bits)
+static int ni_alloc_private(struct comedi_device *dev)
{
- ni_ao_win_outw(dev, ((value >> 16) & 0xff),
- CAL_ADC_Config_Data_High_Word_67xx);
- ni_ao_win_outw(dev, (value & 0xffff),
- CAL_ADC_Config_Data_Low_Word_67xx);
- reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
- cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
- if (cs5529_wait_for_idle(dev))
- comedi_error(dev, "time or signal in cs5529_config_write()");
+ struct ni_private *devpriv;
+
+ devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+ if (!devpriv)
+ return -ENOMEM;
+
+ spin_lock_init(&devpriv->window_lock);
+ spin_lock_init(&devpriv->soft_reg_copy_lock);
+ spin_lock_init(&devpriv->mite_channel_lock);
+
+ return 0;
}
-static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data)
+static int ni_E_init(struct comedi_device *dev,
+ unsigned interrupt_pin, unsigned irq_polarity)
{
- int retval;
- unsigned short status;
+ const struct ni_board_struct *board = comedi_board(dev);
+ struct ni_private *devpriv = dev->private;
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
- cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
- retval = cs5529_wait_for_idle(dev);
- if (retval) {
- comedi_error(dev,
- "timeout or signal in cs5529_do_conversion()");
- return -ETIME;
+ if (board->n_aochan > MAX_N_AO_CHAN) {
+ dev_err(dev->class_dev, "bug! n_aochan > MAX_N_AO_CHAN\n");
+ return -EINVAL;
}
- status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
- if (status & CSS_OSC_DETECT) {
- printk
- ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
- return -EIO;
+
+ /* initialize clock dividers */
+ devpriv->clock_and_fout = Slow_Internal_Time_Divide_By_2 |
+ Slow_Internal_Timebase |
+ Clock_To_Board_Divide_By_2 |
+ Clock_To_Board;
+ if (!devpriv->is_6xxx) {
+ /* BEAM is this needed for PCI-6143 ?? */
+ devpriv->clock_and_fout |= (AI_Output_Divide_By_2 |
+ AO_Output_Divide_By_2);
}
- if (status & CSS_OVERRANGE) {
- printk
- ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
+ ni_stc_writew(dev, devpriv->clock_and_fout, Clock_and_FOUT_Register);
+
+ ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES);
+ if (ret)
+ return ret;
+
+ /* Analog Input subdevice */
+ s = &dev->subdevices[NI_AI_SUBDEV];
+ if (board->n_adchan) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_DITHER;
+ if (!devpriv->is_611x)
+ s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
+ if (board->ai_maxdata > 0xffff)
+ s->subdev_flags |= SDF_LSAMPL;
+ if (devpriv->is_m_series)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = board->n_adchan;
+ s->maxdata = board->ai_maxdata;
+ s->range_table = ni_range_lkup[board->gainlkup];
+ s->insn_read = ni_ai_insn_read;
+ s->insn_config = ni_ai_insn_config;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->len_chanlist = 512;
+ s->do_cmdtest = ni_ai_cmdtest;
+ s->do_cmd = ni_ai_cmd;
+ s->cancel = ni_ai_reset;
+ s->poll = ni_ai_poll;
+ s->munge = ni_ai_munge;
+
+ if (devpriv->mite)
+ s->async_dma_dir = DMA_FROM_DEVICE;
+ }
+
+ /* reset the analog input configuration */
+ ni_ai_reset(dev, s);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
}
- if (data) {
- *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
- /* cs5529 returns 16 bit signed data in bipolar mode */
- *data ^= (1 << 15);
+
+ /* Analog Output subdevice */
+ s = &dev->subdevices[NI_AO_SUBDEV];
+ if (board->n_aochan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
+ if (devpriv->is_m_series)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = board->n_aochan;
+ s->maxdata = board->ao_maxdata;
+ s->range_table = board->ao_range_table;
+ s->insn_read = ni_ao_insn_read;
+ s->insn_write = ni_ao_insn_write;
+ s->insn_config = ni_ao_insn_config;
+
+ /*
+ * Along with the IRQ we need either a FIFO or DMA for
+ * async command support.
+ */
+ if (dev->irq && (board->ao_fifo_depth || devpriv->mite)) {
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = ni_ao_cmdtest;
+ s->do_cmd = ni_ao_cmd;
+ s->cancel = ni_ao_reset;
+ if (!devpriv->is_m_series)
+ s->munge = ni_ao_munge;
+
+ if (devpriv->mite)
+ s->async_dma_dir = DMA_TO_DEVICE;
+ }
+
+ if (devpriv->is_67xx)
+ init_ao_67xx(dev, s);
+
+ /* reset the analog output configuration */
+ ni_ao_reset(dev, s);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
}
- return 0;
-}
-static int cs5529_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
-{
- int n, retval;
- unsigned short sample;
- unsigned int channel_select;
- const unsigned int INTERNAL_REF = 0x1000;
+ /* Digital I/O subdevice */
+ s = &dev->subdevices[NI_DIO_SUBDEV];
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = board->has_32dio_chan ? 32 : 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ if (devpriv->is_m_series) {
+ s->subdev_flags |= SDF_LSAMPL;
+ s->insn_bits = ni_m_series_dio_insn_bits;
+ s->insn_config = ni_m_series_dio_insn_config;
+ if (dev->irq) {
+ s->subdev_flags |= SDF_CMD_WRITE /* | SDF_CMD_READ */;
+ s->len_chanlist = s->n_chan;
+ s->do_cmdtest = ni_cdio_cmdtest;
+ s->do_cmd = ni_cdio_cmd;
+ s->cancel = ni_cdio_cancel;
+
+ /* M-series boards use DMA */
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ }
- /* Set calibration adc source. Docs lie, reference select bits 8 to 11
- * do nothing. bit 12 seems to chooses internal reference voltage, bit
- * 13 causes the adc input to go overrange (maybe reads external reference?) */
- if (insn->chanspec & CR_ALT_SOURCE)
- channel_select = INTERNAL_REF;
- else
- channel_select = CR_CHAN(insn->chanspec);
- ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+ /* reset DIO and set all channels to inputs */
+ ni_writel(dev, CDO_Reset_Bit | CDI_Reset_Bit,
+ M_Offset_CDIO_Command);
+ ni_writel(dev, s->io_bits, M_Offset_DIO_Direction);
+ } else {
+ s->insn_bits = ni_dio_insn_bits;
+ s->insn_config = ni_dio_insn_config;
- for (n = 0; n < insn->n; n++) {
- retval = cs5529_do_conversion(dev, &sample);
- if (retval < 0)
- return retval;
- data[n] = sample;
+ /* set all channels to inputs */
+ devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
+ ni_writew(dev, devpriv->dio_control, DIO_Control_Register);
}
- return insn->n;
-}
-static int init_cs5529(struct comedi_device *dev)
-{
- unsigned int config_bits =
- CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+ /* 8255 device */
+ s = &dev->subdevices[NI_8255_DIO_SUBDEV];
+ if (board->has_8255) {
+ ret = subdev_8255_init(dev, s, ni_8255_callback,
+ (unsigned long)dev);
+ if (ret)
+ return ret;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
-#if 1
- /* do self-calibration */
- cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
- CSCMD_CONFIG_REGISTER);
- /* need to force a conversion for calibration to run */
- cs5529_do_conversion(dev, NULL);
-#else
- /* force gain calibration to 1 */
- cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
- cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
- CSCMD_CONFIG_REGISTER);
- if (cs5529_wait_for_idle(dev))
- comedi_error(dev, "timeout or signal in init_cs5529()\n");
+ /* formerly general purpose counter/timer device, but no longer used */
+ s = &dev->subdevices[NI_UNUSED_SUBDEV];
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* Calibration subdevice */
+ s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_INTERNAL;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ if (devpriv->is_m_series) {
+ /* internal PWM output used for AI nonlinearity calibration */
+ s->insn_config = ni_m_series_pwm_config;
+
+ ni_writel(dev, 0x0, M_Offset_Cal_PWM);
+ } else if (devpriv->is_6143) {
+ /* internal PWM output used for AI nonlinearity calibration */
+ s->insn_config = ni_6143_pwm_config;
+ } else {
+ s->subdev_flags |= SDF_WRITABLE;
+ s->insn_read = ni_calib_insn_read;
+ s->insn_write = ni_calib_insn_write;
+
+ /* setup the caldacs and find the real n_chan and maxdata */
+ caldac_setup(dev, s);
+ }
+
+ /* EEPROM subdevice */
+ s = &dev->subdevices[NI_EEPROM_SUBDEV];
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->maxdata = 0xff;
+ if (devpriv->is_m_series) {
+ s->n_chan = M_SERIES_EEPROM_SIZE;
+ s->insn_read = ni_m_series_eeprom_insn_read;
+ } else {
+ s->n_chan = 512;
+ s->insn_read = ni_eeprom_insn_read;
+ }
+
+ /* Digital I/O (PFI) subdevice */
+ s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->maxdata = 1;
+ if (devpriv->is_m_series) {
+ s->n_chan = 16;
+ s->insn_bits = ni_pfi_insn_bits;
+
+ ni_writew(dev, s->state, M_Offset_PFI_DO);
+ for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
+ ni_writew(dev, devpriv->pfi_output_select_reg[i],
+ M_Offset_PFI_Output_Select(i + 1));
+ }
+ } else {
+ s->n_chan = 10;
+ }
+ s->insn_config = ni_pfi_insn_config;
+
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
+
+ /* cs5529 calibration adc */
+ s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
+ if (devpriv->is_67xx) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
+ /* one channel for each analog output channel */
+ s->n_chan = board->n_aochan;
+ s->maxdata = (1 << 16) - 1;
+ s->range_table = &range_unknown; /* XXX */
+ s->insn_read = cs5529_ai_insn_read;
+ s->insn_config = NULL;
+ init_cs5529(dev);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Serial */
+ s = &dev->subdevices[NI_SERIAL_SUBDEV];
+ s->type = COMEDI_SUBD_SERIAL;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->insn_config = ni_serial_insn_config;
+ devpriv->serial_interval_ns = 0;
+ devpriv->serial_hw_mode = 0;
+
+ /* RTSI */
+ s = &dev->subdevices[NI_RTSI_SUBDEV];
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->insn_bits = ni_rtsi_insn_bits;
+ s->insn_config = ni_rtsi_insn_config;
+ ni_rtsi_init(dev);
+
+ /* allocate and initialize the gpct counter device */
+ devpriv->counter_dev = ni_gpct_device_construct(dev,
+ ni_gpct_write_register,
+ ni_gpct_read_register,
+ (devpriv->is_m_series)
+ ? ni_gpct_variant_m_series
+ : ni_gpct_variant_e_series,
+ NUM_GPCT);
+ if (!devpriv->counter_dev)
+ return -ENOMEM;
+
+ /* Counter (gpct) subdevices */
+ for (i = 0; i < NUM_GPCT; ++i) {
+ struct ni_gpct *gpct = &devpriv->counter_dev->counters[i];
+
+ /* setup and initialize the counter */
+ gpct->chip_index = 0;
+ gpct->counter_index = i;
+ ni_tio_init_counter(gpct);
+
+ s = &dev->subdevices[NI_GPCT_SUBDEV(i)];
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
+ s->n_chan = 3;
+ s->maxdata = (devpriv->is_m_series) ? 0xffffffff
+ : 0x00ffffff;
+ s->insn_read = ni_tio_insn_read;
+ s->insn_write = ni_tio_insn_read;
+ s->insn_config = ni_tio_insn_config;
+#ifdef PCIDMA
+ if (dev->irq && devpriv->mite) {
+ s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
+ s->len_chanlist = 1;
+ s->do_cmdtest = ni_tio_cmdtest;
+ s->do_cmd = ni_gpct_cmd;
+ s->cancel = ni_gpct_cancel;
+
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ }
#endif
+ s->private = gpct;
+ }
+
+ /* Frequency output subdevice */
+ s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xf;
+ s->insn_read = ni_freq_out_insn_read;
+ s->insn_write = ni_freq_out_insn_write;
+ s->insn_config = ni_freq_out_insn_config;
+
+ if (dev->irq) {
+ ni_stc_writew(dev,
+ (irq_polarity ? Interrupt_Output_Polarity : 0) |
+ (Interrupt_Output_On_3_Pins & 0) |
+ Interrupt_A_Enable | Interrupt_B_Enable |
+ Interrupt_A_Output_Select(interrupt_pin) |
+ Interrupt_B_Output_Select(interrupt_pin),
+ Interrupt_Control_Register);
+ }
+
+ /* DMA setup */
+ ni_writeb(dev, devpriv->ai_ao_select_reg, AI_AO_Select);
+ ni_writeb(dev, devpriv->g0_g1_select_reg, G0_G1_Select);
+
+ if (devpriv->is_6xxx) {
+ ni_writeb(dev, 0, Magic_611x);
+ } else if (devpriv->is_m_series) {
+ int channel;
+
+ for (channel = 0; channel < board->n_aochan; ++channel) {
+ ni_writeb(dev, 0xf,
+ M_Offset_AO_Waveform_Order(channel));
+ ni_writeb(dev, 0x0,
+ M_Offset_AO_Reference_Attenuation(channel));
+ }
+ ni_writeb(dev, 0x0, M_Offset_AO_Calibration);
+ }
+
return 0;
}
+
+static void mio_common_detach(struct comedi_device *dev)
+{
+ struct ni_private *devpriv = dev->private;
+
+ if (devpriv) {
+ if (devpriv->counter_dev)
+ ni_gpct_device_destroy(devpriv->counter_dev);
+ }
+}
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index de421486b758..9b201e48233e 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -47,156 +47,85 @@ See the notes in the ni_atmio.o driver.
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
-#define ATMIO 1
-#undef PCIMIO
-
/*
* AT specific setup
*/
-#define NI_SIZE 0x20
-
-#define MAX_N_CALDACS 32
-
static const struct ni_board_struct ni_boards[] = {
{
- .device_id = 0x010d,
.name = "DAQCard-ai-16xe-50",
+ .device_id = 0x010d,
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_8,
.ai_speed = 5000,
- .num_p0_dio_channels = 8,
.caldac = { dac8800, dac8043 },
}, {
- .device_id = 0x010c,
.name = "DAQCard-ai-16e-4",
+ .device_id = 0x010c,
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_16,
.ai_speed = 4000,
- .num_p0_dio_channels = 8,
.caldac = { mb88341 }, /* verified */
}, {
- .device_id = 0x02c4,
.name = "DAQCard-6062E",
+ .device_id = 0x02c4,
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_16,
.ai_speed = 2000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_fifo_depth = 2048,
.ao_range_table = &range_bipolar10,
.ao_speed = 1176,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug }, /* verified */
}, {
/* specs incorrect! */
- .device_id = 0x075e,
.name = "DAQCard-6024E",
+ .device_id = 0x075e,
.n_adchan = 16,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 1024,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
}, {
/* specs incorrect! */
- .device_id = 0x0245,
.name = "DAQCard-6036E",
+ .device_id = 0x0245,
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 1024,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_range_table = &range_bipolar10,
.ao_speed = 1000000,
- .num_p0_dio_channels = 8,
.caldac = { ad8804_debug },
},
#if 0
{
- .device_id = 0x0000, /* unknown */
.name = "DAQCard-6715",
+ .device_id = 0x0000, /* unknown */
.n_aochan = 8,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.ao_671x = 8192,
- .num_p0_dio_channels = 8,
.caldac = { mb88341, mb88341 },
},
#endif
};
-#define interrupt_pin(a) 0
-
-#define IRQ_POLARITY 1
-
-struct ni_private {
-
- struct pcmcia_device *link;
-
-NI_PRIVATE_COMMON};
-
-/* How we access registers */
-
-#define ni_writel(a, b) (outl((a), (b)+dev->iobase))
-#define ni_readl(a) (inl((a)+dev->iobase))
-#define ni_writew(a, b) (outw((a), (b)+dev->iobase))
-#define ni_readw(a) (inw((a)+dev->iobase))
-#define ni_writeb(a, b) (outb((a), (b)+dev->iobase))
-#define ni_readb(a) (inb((a)+dev->iobase))
-
-/* How we access windowed registers */
-
-/* We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board. The
- * DAQCard devices map the low 8 STC registers to iobase+addr*2. */
-
-static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (addr < 8) {
- ni_writew(data, addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ni_writew(data, Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-}
-
-static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr)
-{
- struct ni_private *devpriv = dev->private;
- unsigned long flags;
- uint16_t ret;
-
- spin_lock_irqsave(&devpriv->window_lock, flags);
- if (addr < 8) {
- ret = ni_readw(addr * 2);
- } else {
- ni_writew(addr, Window_Address);
- ret = ni_readw(Window_Data);
- }
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
-
- return ret;
-}
-
#include "ni_mio_common.c"
static const void *ni_getboardtype(struct comedi_device *dev,
@@ -260,12 +189,8 @@ static int mio_cs_auto_attach(struct comedi_device *dev,
return ret;
devpriv = dev->private;
- devpriv->stc_writew = mio_cs_win_out;
- devpriv->stc_readw = mio_cs_win_in;
- devpriv->stc_writel = win_out2;
- devpriv->stc_readl = win_in2;
- return ni_E_init(dev);
+ return ni_E_init(dev, 0, 1);
}
static void mio_cs_detach(struct comedi_device *dev)
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 5fc74d6ff6af..b5b36af80205 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -58,9 +58,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
#include "comedi_fc.h"
#include "mite.h"
-#define PCI_DIO_SIZE 4096
-#define PCI_MITE_SIZE 4096
-
/* defines for the PCI-DIO-32HS */
#define Window_Address 4 /* W */
@@ -297,16 +294,6 @@ struct nidio96_private {
spinlock_t mite_channel_lock;
};
-static int ni_pcidio_cmdtest(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_cmd *cmd);
-static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ni_pcidio_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int trignum);
-static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
-static int setup_mite_dma(struct comedi_device *dev,
- struct comedi_subdevice *s);
-
static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
{
struct nidio96_private *devpriv = dev->private;
@@ -319,13 +306,13 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
devpriv->di_mite_ring, 1, 2);
if (devpriv->di_mite_chan == NULL) {
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
- comedi_error(dev, "failed to reserve mite dma channel.");
+ dev_err(dev->class_dev, "failed to reserve mite dma channel\n");
return -EBUSY;
}
devpriv->di_mite_chan->dir = COMEDI_INPUT;
writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
- devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ dev->mmio + DMA_Line_Control_Group1);
mmiowb();
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
return 0;
@@ -344,12 +331,36 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
devpriv->di_mite_chan = NULL;
writeb(primary_DMAChannel_bits(0) |
secondary_DMAChannel_bits(0),
- devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ dev->mmio + DMA_Line_Control_Group1);
mmiowb();
}
spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
}
+static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+ struct nidio96_private *devpriv = dev->private;
+ int retval;
+ unsigned long flags;
+
+ retval = ni_pcidio_request_di_mite_channel(dev);
+ if (retval)
+ return retval;
+
+ /* write alloc the entire buffer */
+ comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
+
+ spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->di_mite_chan) {
+ mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+ mite_dma_arm(devpriv->di_mite_chan);
+ } else
+ retval = -EIO;
+ spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ return retval;
+}
+
static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct nidio96_private *devpriv = dev->private;
@@ -361,7 +372,7 @@ static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
if (devpriv->di_mite_chan)
mite_sync_input_dma(devpriv->di_mite_chan, s);
spin_unlock(&devpriv->mite_channel_lock);
- count = s->async->buf_write_count - s->async->buf_read_count;
+ count = comedi_buf_n_bytes_ready(s);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
return count;
}
@@ -392,9 +403,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
/* Lock to avoid race with comedi_poll */
spin_lock(&dev->spinlock);
- status = readb(devpriv->mite->daq_io_addr +
- Interrupt_And_Window_Status);
- flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+ status = readb(dev->mmio + Interrupt_And_Window_Status);
+ flags = readb(dev->mmio + Group_1_Flags);
spin_lock(&devpriv->mite_channel_lock);
if (devpriv->di_mite_chan)
@@ -423,8 +433,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
if (work > 20) {
dev_dbg(dev->class_dev, "too much work in interrupt\n");
writeb(0x00,
- devpriv->mite->daq_io_addr +
- Master_DMA_And_Interrupt_Control);
+ dev->mmio + Master_DMA_And_Interrupt_Control);
break;
}
@@ -436,64 +445,50 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
if (work > 100) {
dev_dbg(dev->class_dev,
"too much work in interrupt\n");
- writeb(0x00,
- devpriv->mite->daq_io_addr +
+ writeb(0x00, dev->mmio +
Master_DMA_And_Interrupt_Control
);
goto out;
}
- auxdata =
- readl(devpriv->mite->daq_io_addr +
- Group_1_FIFO);
+ auxdata = readl(dev->mmio + Group_1_FIFO);
data1 = auxdata & 0xffff;
data2 = (auxdata & 0xffff0000) >> 16;
comedi_buf_put(s, data1);
comedi_buf_put(s, data2);
- flags = readb(devpriv->mite->daq_io_addr +
- Group_1_Flags);
+ flags = readb(dev->mmio + Group_1_Flags);
}
async->events |= COMEDI_CB_BLOCK;
}
if (flags & CountExpired) {
- writeb(ClearExpired,
- devpriv->mite->daq_io_addr +
- Group_1_Second_Clear);
+ writeb(ClearExpired, dev->mmio + Group_1_Second_Clear);
async->events |= COMEDI_CB_EOA;
- writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
+ writeb(0x00, dev->mmio + OpMode);
break;
} else if (flags & Waited) {
- writeb(ClearWaited,
- devpriv->mite->daq_io_addr +
- Group_1_First_Clear);
+ writeb(ClearWaited, dev->mmio + Group_1_First_Clear);
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
break;
} else if (flags & PrimaryTC) {
writeb(ClearPrimaryTC,
- devpriv->mite->daq_io_addr +
- Group_1_First_Clear);
+ dev->mmio + Group_1_First_Clear);
async->events |= COMEDI_CB_EOA;
} else if (flags & SecondaryTC) {
writeb(ClearSecondaryTC,
- devpriv->mite->daq_io_addr +
- Group_1_First_Clear);
+ dev->mmio + Group_1_First_Clear);
async->events |= COMEDI_CB_EOA;
}
- flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
- status = readb(devpriv->mite->daq_io_addr +
- Interrupt_And_Window_Status);
+ flags = readb(dev->mmio + Group_1_Flags);
+ status = readb(dev->mmio + Interrupt_And_Window_Status);
}
out:
cfc_handle_events(dev, s);
#if 0
- if (!tag) {
- writeb(0x03,
- devpriv->mite->daq_io_addr +
- Master_DMA_And_Interrupt_Control);
- }
+ if (!tag)
+ writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
#endif
spin_unlock(&dev->spinlock);
@@ -505,14 +500,13 @@ static int ni_pcidio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct nidio96_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
if (ret)
return ret;
- writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+ writel(s->io_bits, dev->mmio + Port_Pin_Directions(0));
return insn->n;
}
@@ -522,16 +516,37 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct nidio96_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
+ writel(s->state, dev->mmio + Port_IO(0));
- data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
+ data[1] = readl(dev->mmio + Port_IO(0));
return insn->n;
}
+static int ni_pcidio_ns_to_timer(int *nanosec, unsigned int flags)
+{
+ int divider, base;
+
+ base = TIMER_BASE;
+
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec + base - 1) / base;
+ break;
+ }
+
+ *nanosec = base * divider;
+ return divider;
+}
+
static int ni_pcidio_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
@@ -596,7 +611,7 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- ni_pcidio_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ ni_pcidio_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
@@ -606,27 +621,20 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
return 0;
}
-static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
+static int ni_pcidio_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
{
- int divider, base;
+ struct nidio96_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
- base = TIMER_BASE;
+ if (trig_num != cmd->start_arg)
+ return -EINVAL;
- switch (round_mode) {
- case TRIG_ROUND_NEAREST:
- default:
- divider = (*nanosec + base / 2) / base;
- break;
- case TRIG_ROUND_DOWN:
- divider = (*nanosec) / base;
- break;
- case TRIG_ROUND_UP:
- divider = (*nanosec + base - 1) / base;
- break;
- }
+ writeb(devpriv->OpModeBits, dev->mmio + OpMode);
+ s->async->inttrig = NULL;
- *nanosec = base * divider;
- return divider;
+ return 1;
}
static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -635,98 +643,94 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
struct comedi_cmd *cmd = &s->async->cmd;
/* XXX configure ports for input */
- writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+ writel(0x0000, dev->mmio + Port_Pin_Directions(0));
if (1) {
/* enable fifos A B C D */
- writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
+ writeb(0x0f, dev->mmio + Data_Path);
/* set transfer width a 32 bits */
writeb(TransferWidth(0) | TransferLength(0),
- devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ dev->mmio + Transfer_Size_Control);
} else {
- writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
+ writeb(0x03, dev->mmio + Data_Path);
writeb(TransferWidth(3) | TransferLength(0),
- devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ dev->mmio + Transfer_Size_Control);
}
/* protocol configuration */
if (cmd->scan_begin_src == TRIG_TIMER) {
/* page 4-5, "input with internal REQs" */
- writeb(0, devpriv->mite->daq_io_addr + OpMode);
- writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
- writeb(1, devpriv->mite->daq_io_addr + Sequence);
- writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
- writeb(4, devpriv->mite->daq_io_addr + BlockMode);
- writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
- writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
+ writeb(0, dev->mmio + OpMode);
+ writeb(0x00, dev->mmio + ClockReg);
+ writeb(1, dev->mmio + Sequence);
+ writeb(0x04, dev->mmio + ReqReg);
+ writeb(4, dev->mmio + BlockMode);
+ writeb(3, dev->mmio + LinePolarities);
+ writeb(0xc0, dev->mmio + AckSer);
writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_NEAREST),
- devpriv->mite->daq_io_addr + StartDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
- writeb(1, devpriv->mite->daq_io_addr + AckDelay);
- writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
- writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
+ dev->mmio + StartDelay);
+ writeb(1, dev->mmio + ReqDelay);
+ writeb(1, dev->mmio + ReqNotDelay);
+ writeb(1, dev->mmio + AckDelay);
+ writeb(0x0b, dev->mmio + AckNotDelay);
+ writeb(0x01, dev->mmio + Data1Delay);
/* manual, page 4-5: ClockSpeed comment is incorrectly listed
* on DAQOptions */
- writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
- writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
+ writew(0, dev->mmio + ClockSpeed);
+ writeb(0, dev->mmio + DAQOptions);
} else {
/* TRIG_EXT */
/* page 4-5, "input with external REQs" */
- writeb(0, devpriv->mite->daq_io_addr + OpMode);
- writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
- writeb(0, devpriv->mite->daq_io_addr + Sequence);
- writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
- writeb(4, devpriv->mite->daq_io_addr + BlockMode);
- if (!(cmd->scan_begin_arg & CR_INVERT)) {
- /* Leading Edge pulse mode */
- writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
- } else {
- /* Trailing Edge pulse mode */
- writeb(2, devpriv->mite->daq_io_addr + LinePolarities);
- }
- writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
- writel(1, devpriv->mite->daq_io_addr + StartDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
- writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
- writeb(1, devpriv->mite->daq_io_addr + AckDelay);
- writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
- writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
- writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
- writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
+ writeb(0, dev->mmio + OpMode);
+ writeb(0x00, dev->mmio + ClockReg);
+ writeb(0, dev->mmio + Sequence);
+ writeb(0x00, dev->mmio + ReqReg);
+ writeb(4, dev->mmio + BlockMode);
+ if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */
+ writeb(0, dev->mmio + LinePolarities);
+ else /* Trailing Edge */
+ writeb(2, dev->mmio + LinePolarities);
+ writeb(0x00, dev->mmio + AckSer);
+ writel(1, dev->mmio + StartDelay);
+ writeb(1, dev->mmio + ReqDelay);
+ writeb(1, dev->mmio + ReqNotDelay);
+ writeb(1, dev->mmio + AckDelay);
+ writeb(0x0C, dev->mmio + AckNotDelay);
+ writeb(0x10, dev->mmio + Data1Delay);
+ writew(0, dev->mmio + ClockSpeed);
+ writeb(0x60, dev->mmio + DAQOptions);
}
if (cmd->stop_src == TRIG_COUNT) {
writel(cmd->stop_arg,
- devpriv->mite->daq_io_addr + Transfer_Count);
+ dev->mmio + Transfer_Count);
} else {
/* XXX */
}
#ifdef USE_DMA
writeb(ClearPrimaryTC | ClearSecondaryTC,
- devpriv->mite->daq_io_addr + Group_1_First_Clear);
+ dev->mmio + Group_1_First_Clear);
{
int retval = setup_mite_dma(dev, s);
+
if (retval)
return retval;
}
#else
- writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ writeb(0x00, dev->mmio + DMA_Line_Control_Group1);
#endif
- writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
+ writeb(0x00, dev->mmio + DMA_Line_Control_Group2);
/* clear and enable interrupts */
- writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
- /* writeb(ClearExpired,
- devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
+ writeb(0xff, dev->mmio + Group_1_First_Clear);
+ /* writeb(ClearExpired, dev->mmio+Group_1_Second_Clear); */
- writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
- writeb(0x03,
- devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+ writeb(IntEn, dev->mmio + Interrupt_Control);
+ writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
if (cmd->stop_src == TRIG_NONE) {
devpriv->OpModeBits = DataLatching(0) | RunMode(7);
@@ -735,8 +739,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
if (cmd->start_src == TRIG_NOW) {
/* start */
- writeb(devpriv->OpModeBits,
- devpriv->mite->daq_io_addr + OpMode);
+ writeb(devpriv->OpModeBits, dev->mmio + OpMode);
s->async->inttrig = NULL;
} else {
/* TRIG_INT */
@@ -746,60 +749,17 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return 0;
}
-static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
-{
- struct nidio96_private *devpriv = dev->private;
- int retval;
- unsigned long flags;
-
- retval = ni_pcidio_request_di_mite_channel(dev);
- if (retval)
- return retval;
-
- /* write alloc the entire buffer */
- comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
-
- spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
- if (devpriv->di_mite_chan) {
- mite_prep_dma(devpriv->di_mite_chan, 32, 32);
- mite_dma_arm(devpriv->di_mite_chan);
- } else
- retval = -EIO;
- spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
-
- return retval;
-}
-
-static int ni_pcidio_inttrig(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int trig_num)
-{
- struct nidio96_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
-
- if (trig_num != cmd->start_arg)
- return -EINVAL;
-
- writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
- s->async->inttrig = NULL;
-
- return 1;
-}
-
static int ni_pcidio_cancel(struct comedi_device *dev,
struct comedi_subdevice *s)
{
- struct nidio96_private *devpriv = dev->private;
-
- writeb(0x00,
- devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+ writeb(0x00, dev->mmio + Master_DMA_And_Interrupt_Control);
ni_pcidio_release_di_mite_channel(dev);
return 0;
}
static int ni_pcidio_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
+ struct comedi_subdevice *s)
{
struct nidio96_private *devpriv = dev->private;
int ret;
@@ -817,19 +777,16 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
const u8 *data, size_t data_len,
unsigned long context)
{
- struct nidio96_private *devpriv = dev->private;
static const int timeout = 1000;
int fpga_index = context;
int i;
size_t j;
- writew(0x80 | fpga_index,
- devpriv->mite->daq_io_addr + Firmware_Control_Register);
- writew(0xc0 | fpga_index,
- devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
+ writew(0xc0 | fpga_index, dev->mmio + Firmware_Control_Register);
for (i = 0;
- (readw(devpriv->mite->daq_io_addr +
- Firmware_Status_Register) & 0x2) == 0 && i < timeout; ++i) {
+ (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 &&
+ i < timeout; ++i) {
udelay(1);
}
if (i == timeout) {
@@ -838,11 +795,10 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
fpga_index);
return -EIO;
}
- writew(0x80 | fpga_index,
- devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
for (i = 0;
- readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
- 0x3 && i < timeout; ++i) {
+ readw(dev->mmio + Firmware_Status_Register) != 0x3 &&
+ i < timeout; ++i) {
udelay(1);
}
if (i == timeout) {
@@ -853,12 +809,11 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
}
for (j = 0; j + 1 < data_len;) {
unsigned int value = data[j++];
+
value |= data[j++] << 8;
- writew(value,
- devpriv->mite->daq_io_addr + Firmware_Data_Register);
+ writew(value, dev->mmio + Firmware_Data_Register);
for (i = 0;
- (readw(devpriv->mite->daq_io_addr +
- Firmware_Status_Register) & 0x2) == 0
+ (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0
&& i < timeout; ++i) {
udelay(1);
}
@@ -871,7 +826,7 @@ static int pci_6534_load_fpga(struct comedi_device *dev,
if (need_resched())
schedule();
}
- writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x0, dev->mmio + Firmware_Control_Register);
return 0;
}
@@ -882,30 +837,27 @@ static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
static int pci_6534_reset_fpgas(struct comedi_device *dev)
{
- struct nidio96_private *devpriv = dev->private;
int ret;
int i;
- writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0x0, dev->mmio + Firmware_Control_Register);
for (i = 0; i < 3; ++i) {
ret = pci_6534_reset_fpga(dev, i);
if (ret < 0)
break;
}
- writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
+ writew(0x0, dev->mmio + Firmware_Mask_Register);
return ret;
}
static void pci_6534_init_main_fpga(struct comedi_device *dev)
{
- struct nidio96_private *devpriv = dev->private;
-
- writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
- writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
+ writel(0, dev->mmio + FPGA_Control1_Register);
+ writel(0, dev->mmio + FPGA_Control2_Register);
+ writel(0, dev->mmio + FPGA_SCALS_Counter_Register);
+ writel(0, dev->mmio + FPGA_SCAMS_Counter_Register);
+ writel(0, dev->mmio + FPGA_SCBLS_Counter_Register);
+ writel(0, dev->mmio + FPGA_SCBMS_Counter_Register);
}
static int pci_6534_upload_firmware(struct comedi_device *dev)
@@ -937,15 +889,12 @@ static int pci_6534_upload_firmware(struct comedi_device *dev)
static void nidio_reset_board(struct comedi_device *dev)
{
- struct nidio96_private *devpriv = dev->private;
- void __iomem *daq_mmio = devpriv->mite->daq_io_addr;
-
- writel(0, daq_mmio + Port_IO(0));
- writel(0, daq_mmio + Port_Pin_Directions(0));
- writel(0, daq_mmio + Port_Pin_Mask(0));
+ writel(0, dev->mmio + Port_IO(0));
+ writel(0, dev->mmio + Port_Pin_Directions(0));
+ writel(0, dev->mmio + Port_Pin_Mask(0));
/* disable interrupts on board */
- writeb(0, daq_mmio + Master_DMA_And_Interrupt_Control);
+ writeb(0, dev->mmio + Master_DMA_And_Interrupt_Control);
}
static int nidio_auto_attach(struct comedi_device *dev,
@@ -979,11 +928,9 @@ static int nidio_auto_attach(struct comedi_device *dev,
if (!devpriv->mite)
return -ENOMEM;
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- dev_warn(dev->class_dev, "error setting up mite\n");
+ ret = mite_setup(dev, devpriv->mite);
+ if (ret < 0)
return ret;
- }
devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
if (devpriv->di_mite_ring == NULL)
@@ -1002,7 +949,7 @@ static int nidio_auto_attach(struct comedi_device *dev,
return ret;
dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name,
- readb(devpriv->mite->daq_io_addr + Chip_Version));
+ readb(dev->mmio + Chip_Version));
s = &dev->subdevices[0];
@@ -1024,7 +971,7 @@ static int nidio_auto_attach(struct comedi_device *dev,
s->async_dma_dir = DMA_BIDIRECTIONAL;
s->poll = &ni_pcidio_poll;
- irq = mite_irq(devpriv->mite);
+ irq = pcidev->irq;
if (irq) {
ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
dev->board_name, dev);
@@ -1046,11 +993,10 @@ static void nidio_detach(struct comedi_device *dev)
mite_free_ring(devpriv->di_mite_ring);
devpriv->di_mite_ring = NULL;
}
- if (devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ mite_detach(devpriv->mite);
}
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 89300dc78e35..da61fa70decf 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -118,13 +118,6 @@ Bugs:
#define PCIDMA
-#define PCIMIO 1
-#undef ATMIO
-
-#define MAX_N_CALDACS (16+16+2)
-
-#define DRV_NAME "ni_pcimio"
-
/* These are not all the possible ao ranges for 628x boards.
They can do OFFSET +- REFERENCE where OFFSET can be
0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
@@ -218,87 +211,79 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCIMIO_16XE_50] = {
.name = "pci-mio-16xe-50",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 2048,
.alwaysdither = 1,
.gainlkup = ai_gain_8,
.ai_speed = 50000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_16,
/*
@@ -307,216 +292,195 @@ static const struct ni_board_struct ni_boards[] = {
*/
.ai_speed = 2000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_16,
.ai_speed = 2000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.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_maxdata = 0xffff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 3000,
.n_aochan = 2,
- .aobits = 16,
- .ao_unipolar = 1,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.alwaysdither = 0,
.gainlkup = ai_gain_611x,
.ai_speed = 200,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_611x,
.ai_speed = 200,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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
@@ -524,16 +488,15 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCI6115] = { /* .device_id = 0x2ed0, */
.name = "pci-6115",
.n_adchan = 4,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_611x,
.ai_speed = 100,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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 },
@@ -543,17 +506,16 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PXI6115] = { /* .device_id = ????, */
.name = "pxi-6115",
.n_adchan = 4,
- .adbits = 12,
+ .ai_maxdata = 0x0fff,
.ai_fifo_depth = 8192,
.gainlkup = ai_gain_611x,
.ai_speed = 100,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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 },
},
@@ -561,56 +523,51 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCI6711] = {
.name = "pci-6711",
.n_aochan = 4,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
/* 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_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.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_maxdata = 0xffff,
.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 },
},
@@ -618,10 +575,9 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PXI6731] = { /* .device_id = ????, */
.name = "pxi-6731",
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8192,
.ao_range_table = &range_bipolar10,
- .num_p0_dio_channels = 8,
.reg_type = ni_reg_6711,
.caldac = { ad8804_debug },
},
@@ -629,759 +585,462 @@ static const struct ni_board_struct ni_boards[] = {
[BOARD_PCI6733] = {
.name = "pci-6733",
.n_aochan = 8,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0x0fff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 12,
+ .ao_maxdata = 0x0fff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_16,
.ai_speed = 3000,
.n_aochan = 2,
- .aobits = 16,
- .ao_unipolar = 1,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_14,
.ai_speed = 10000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 512,
.alwaysdither = 1,
.gainlkup = ai_gain_4,
.ai_speed = 5000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.reg_type = ni_reg_622x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PXI6224] = {
.name = "pxi-6224",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.reg_type = ni_reg_622x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6225] = {
.name = "pci-6225",
.n_adchan = 80,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PXI6225] = {
.name = "pxi-6225",
.n_adchan = 80,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6229] = {
.name = "pci-6229",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_622x,
.ai_speed = 4000,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.ao_fifo_depth = 8191,
.ao_range_table = &range_bipolar10,
.reg_type = ni_reg_622x,
.ao_speed = 1200,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6250] = {
.name = "pci-6250",
.n_adchan = 16,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.reg_type = ni_reg_625x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6259] = {
.name = "pci-6259",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCIE6259] = {
.name = "pcie-6259",
.n_adchan = 32,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.ai_fifo_depth = 4095,
.gainlkup = ai_gain_628x,
.ai_speed = 800,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6280] = {
.name = "pci-6280",
.n_adchan = 16,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.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_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.n_aochan = 2,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.reg_type = ni_reg_628x,
- .num_p0_dio_channels = 32,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6289] = {
.name = "pci-6289",
.n_adchan = 32,
- .adbits = 18,
+ .ai_maxdata = 0x3ffff,
.ai_fifo_depth = 2047,
.gainlkup = ai_gain_628x,
.ai_speed = 1600,
.n_aochan = 4,
- .aobits = 16,
+ .ao_maxdata = 0xffff,
.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,
+ .has_32dio_chan = 1,
.caldac = { caldac_none },
},
[BOARD_PCI6143] = {
.name = "pci-6143",
.n_adchan = 8,
- .adbits = 16,
+ .ai_maxdata = 0xffff,
.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_maxdata = 0xffff,
.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 },
},
};
-struct ni_private {
-NI_PRIVATE_COMMON};
-
-/* How we access registers */
-
-#define ni_writel(a, b) (writel((a), devpriv->mite->daq_io_addr + (b)))
-#define ni_readl(a) (readl(devpriv->mite->daq_io_addr + (a)))
-#define ni_writew(a, b) (writew((a), devpriv->mite->daq_io_addr + (b)))
-#define ni_readw(a) (readw(devpriv->mite->daq_io_addr + (a)))
-#define ni_writeb(a, b) (writeb((a), devpriv->mite->daq_io_addr + (b)))
-#define ni_readb(a) (readb(devpriv->mite->daq_io_addr + (a)))
-
-/* How we access STC registers */
-
-/* We automatically take advantage of STC registers that can be
- * read/written directly in the I/O space of the board. Most
- * PCIMIO devices map the low 8 STC registers to iobase+addr*2.
- * The 611x devices map the write registers to iobase+addr*2, and
- * the read registers to iobase+(addr-1)*2. */
-/* However, the 611x boards still aren't working, so I'm disabling
- * non-windowed STC access temporarily */
+#include "ni_mio_common.c"
-static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg)
+static int pcimio_ai_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned long flags;
+ int ret;
+
+ ret = mite_buf_change(devpriv->ai_mite_ring, s);
+ if (ret < 0)
+ return ret;
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(reg, Window_Address);
- ni_writew(data, Window_Data);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ return 0;
}
-static uint16_t e_series_win_in(struct comedi_device *dev, int reg)
+static int pcimio_ao_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned long flags;
- uint16_t ret;
+ int ret;
- spin_lock_irqsave(&devpriv->window_lock, flags);
- ni_writew(reg, Window_Address);
- ret = ni_readw(Window_Data);
- spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ ret = mite_buf_change(devpriv->ao_mite_ring, s);
+ if (ret < 0)
+ return ret;
- return ret;
+ return 0;
}
-static void m_series_stc_writew(struct comedi_device *dev, uint16_t data,
- int reg)
+static int pcimio_gpct0_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case ADC_FIFO_Clear:
- offset = M_Offset_AI_FIFO_Clear;
- break;
- case AI_Command_1_Register:
- offset = M_Offset_AI_Command_1;
- break;
- case AI_Command_2_Register:
- offset = M_Offset_AI_Command_2;
- break;
- case AI_Mode_1_Register:
- offset = M_Offset_AI_Mode_1;
- break;
- case AI_Mode_2_Register:
- offset = M_Offset_AI_Mode_2;
- break;
- case AI_Mode_3_Register:
- offset = M_Offset_AI_Mode_3;
- break;
- case AI_Output_Control_Register:
- offset = M_Offset_AI_Output_Control;
- break;
- case AI_Personal_Register:
- offset = M_Offset_AI_Personal;
- break;
- case AI_SI2_Load_A_Register:
- /* this is actually a 32 bit register on m series boards */
- ni_writel(data, M_Offset_AI_SI2_Load_A);
- return;
- break;
- case AI_SI2_Load_B_Register:
- /* this is actually a 32 bit register on m series boards */
- ni_writel(data, M_Offset_AI_SI2_Load_B);
- return;
- break;
- case AI_START_STOP_Select_Register:
- offset = M_Offset_AI_START_STOP_Select;
- break;
- case AI_Trigger_Select_Register:
- offset = M_Offset_AI_Trigger_Select;
- break;
- case Analog_Trigger_Etc_Register:
- offset = M_Offset_Analog_Trigger_Etc;
- break;
- case AO_Command_1_Register:
- offset = M_Offset_AO_Command_1;
- break;
- case AO_Command_2_Register:
- offset = M_Offset_AO_Command_2;
- break;
- case AO_Mode_1_Register:
- offset = M_Offset_AO_Mode_1;
- break;
- case AO_Mode_2_Register:
- offset = M_Offset_AO_Mode_2;
- break;
- case AO_Mode_3_Register:
- offset = M_Offset_AO_Mode_3;
- break;
- case AO_Output_Control_Register:
- offset = M_Offset_AO_Output_Control;
- break;
- case AO_Personal_Register:
- offset = M_Offset_AO_Personal;
- break;
- case AO_Start_Select_Register:
- offset = M_Offset_AO_Start_Select;
- break;
- case AO_Trigger_Select_Register:
- offset = M_Offset_AO_Trigger_Select;
- break;
- case Clock_and_FOUT_Register:
- offset = M_Offset_Clock_and_FOUT;
- break;
- case Configuration_Memory_Clear:
- offset = M_Offset_Configuration_Memory_Clear;
- break;
- case DAC_FIFO_Clear:
- offset = M_Offset_AO_FIFO_Clear;
- break;
- case DIO_Control_Register:
- dev_dbg(dev->class_dev,
- "%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
- __func__, reg);
- return;
- break;
- case G_Autoincrement_Register(0):
- offset = M_Offset_G0_Autoincrement;
- break;
- case G_Autoincrement_Register(1):
- offset = M_Offset_G1_Autoincrement;
- break;
- case G_Command_Register(0):
- offset = M_Offset_G0_Command;
- break;
- case G_Command_Register(1):
- offset = M_Offset_G1_Command;
- break;
- case G_Input_Select_Register(0):
- offset = M_Offset_G0_Input_Select;
- break;
- case G_Input_Select_Register(1):
- offset = M_Offset_G1_Input_Select;
- break;
- case G_Mode_Register(0):
- offset = M_Offset_G0_Mode;
- break;
- case G_Mode_Register(1):
- offset = M_Offset_G1_Mode;
- break;
- case Interrupt_A_Ack_Register:
- offset = M_Offset_Interrupt_A_Ack;
- break;
- case Interrupt_A_Enable_Register:
- offset = M_Offset_Interrupt_A_Enable;
- break;
- case Interrupt_B_Ack_Register:
- offset = M_Offset_Interrupt_B_Ack;
- break;
- case Interrupt_B_Enable_Register:
- offset = M_Offset_Interrupt_B_Enable;
- break;
- case Interrupt_Control_Register:
- offset = M_Offset_Interrupt_Control;
- break;
- case IO_Bidirection_Pin_Register:
- offset = M_Offset_IO_Bidirection_Pin;
- break;
- case Joint_Reset_Register:
- offset = M_Offset_Joint_Reset;
- break;
- case RTSI_Trig_A_Output_Register:
- offset = M_Offset_RTSI_Trig_A_Output;
- break;
- case RTSI_Trig_B_Output_Register:
- offset = M_Offset_RTSI_Trig_B_Output;
- break;
- case RTSI_Trig_Direction_Register:
- offset = M_Offset_RTSI_Trig_Direction;
- break;
- /* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
- and M_Offset_SCXI_Serial_Data_Out (8 bit) */
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return;
- break;
- }
- ni_writew(data, offset);
-}
+ int ret;
-static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
-{
- struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case AI_Status_1_Register:
- offset = M_Offset_AI_Status_1;
- break;
- case AO_Status_1_Register:
- offset = M_Offset_AO_Status_1;
- break;
- case AO_Status_2_Register:
- offset = M_Offset_AO_Status_2;
- break;
- case DIO_Serial_Input_Register:
- return ni_readb(M_Offset_SCXI_Serial_Data_In);
- break;
- case Joint_Status_1_Register:
- offset = M_Offset_Joint_Status_1;
- break;
- case Joint_Status_2_Register:
- offset = M_Offset_Joint_Status_2;
- break;
- case G_Status_Register:
- offset = M_Offset_G01_Status;
- break;
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return 0;
- break;
- }
- return ni_readw(offset);
+ ret = mite_buf_change(devpriv->gpct_mite_ring[0], s);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
-static void m_series_stc_writel(struct comedi_device *dev, uint32_t data,
- int reg)
+static int pcimio_gpct1_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case AI_SC_Load_A_Registers:
- offset = M_Offset_AI_SC_Load_A;
- break;
- case AI_SI_Load_A_Registers:
- offset = M_Offset_AI_SI_Load_A;
- break;
- case AO_BC_Load_A_Register:
- offset = M_Offset_AO_BC_Load_A;
- break;
- case AO_UC_Load_A_Register:
- offset = M_Offset_AO_UC_Load_A;
- break;
- case AO_UI_Load_A_Register:
- offset = M_Offset_AO_UI_Load_A;
- break;
- case G_Load_A_Register(0):
- offset = M_Offset_G0_Load_A;
- break;
- case G_Load_A_Register(1):
- offset = M_Offset_G1_Load_A;
- break;
- case G_Load_B_Register(0):
- offset = M_Offset_G0_Load_B;
- break;
- case G_Load_B_Register(1):
- offset = M_Offset_G1_Load_B;
- break;
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return;
- break;
- }
- ni_writel(data, offset);
+ int ret;
+
+ ret = mite_buf_change(devpriv->gpct_mite_ring[1], s);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
-static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
+static int pcimio_dio_change(struct comedi_device *dev,
+ struct comedi_subdevice *s)
{
struct ni_private *devpriv = dev->private;
- unsigned offset;
-
- switch (reg) {
- case G_HW_Save_Register(0):
- offset = M_Offset_G0_HW_Save;
- break;
- case G_HW_Save_Register(1):
- offset = M_Offset_G1_HW_Save;
- break;
- case G_Save_Register(0):
- offset = M_Offset_G0_Save;
- break;
- case G_Save_Register(1):
- offset = M_Offset_G1_Save;
- break;
- default:
- dev_warn(dev->class_dev,
- "%s: bug! unhandled register=0x%x in switch.\n",
- __func__, reg);
- BUG();
- return 0;
- break;
- }
- return ni_readl(offset);
-}
-
-#define interrupt_pin(a) 0
-#define IRQ_POLARITY 1
+ int ret;
-#define NI_E_IRQ_FLAGS IRQF_SHARED
+ ret = mite_buf_change(devpriv->cdo_mite_ring, s);
+ if (ret < 0)
+ return ret;
-#include "ni_mio_common.c"
+ return 0;
+}
-static int pcimio_ai_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size);
-static int pcimio_ao_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size);
-static int pcimio_gpct0_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size);
-static int pcimio_gpct1_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size);
-static int pcimio_dio_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size);
static void m_series_init_eeprom_buffer(struct comedi_device *dev)
{
@@ -1408,12 +1067,12 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev)
BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number));
for (i = 0; i < serial_number_eeprom_length; ++i) {
char *byte_ptr = (char *)&devpriv->serial_number + i;
- *byte_ptr = ni_readb(serial_number_eeprom_offset + i);
+ *byte_ptr = ni_readb(dev, serial_number_eeprom_offset + i);
}
devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i)
- devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
+ devpriv->eeprom_buffer[i] = ni_readb(dev, Start_Cal_EEPROM + i);
writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
@@ -1427,21 +1086,26 @@ static void init_6143(struct comedi_device *dev)
struct ni_private *devpriv = dev->private;
/* Disable interrupts */
- devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
+ ni_stc_writew(dev, 0, Interrupt_Control_Register);
/* Initialise 6143 AI specific bits */
- ni_writeb(0x00, Magic_6143); /* Set G0,G1 DMA mode to E series version */
- ni_writeb(0x80, PipelineDelay_6143); /* Set EOCMode, ADCMode and pipelinedelay */
- ni_writeb(0x00, EOC_Set_6143); /* Set EOC Delay */
+
+ /* Set G0,G1 DMA mode to E series version */
+ ni_writeb(dev, 0x00, Magic_6143);
+ /* Set EOCMode, ADCMode and pipelinedelay */
+ ni_writeb(dev, 0x80, PipelineDelay_6143);
+ /* Set EOC Delay */
+ ni_writeb(dev, 0x00, EOC_Set_6143);
/* Set the FIFO half full level */
- ni_writel(board->ai_fifo_depth / 2, AIFIFO_Flag_6143);
+ ni_writel(dev, board->ai_fifo_depth / 2, AIFIFO_Flag_6143);
/* Strobe Relay disable bit */
devpriv->ai_calib_source_enabled = 0;
- ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff,
+ ni_writew(dev, devpriv->ai_calib_source |
+ Calibration_Channel_6143_RelayOff,
Calibration_Channel_6143);
- ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+ ni_writew(dev, devpriv->ai_calib_source, Calibration_Channel_6143);
}
static void pcimio_detach(struct comedi_device *dev)
@@ -1457,11 +1121,10 @@ static void pcimio_detach(struct comedi_device *dev)
mite_free_ring(devpriv->cdo_mite_ring);
mite_free_ring(devpriv->gpct_mite_ring[0]);
mite_free_ring(devpriv->gpct_mite_ring[1]);
- if (devpriv->mite) {
- mite_unsetup(devpriv->mite);
- mite_free(devpriv->mite);
- }
+ mite_detach(devpriv->mite);
}
+ if (dev->mmio)
+ iounmap(dev->mmio);
comedi_pci_disable(dev);
}
@@ -1494,23 +1157,30 @@ static int pcimio_auto_attach(struct comedi_device *dev,
if (!devpriv->mite)
return -ENOMEM;
- 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;
- devpriv->stc_readl = &m_series_stc_readl;
- } else {
- devpriv->stc_writew = &e_series_win_out;
- devpriv->stc_readw = &e_series_win_in;
- devpriv->stc_writel = &win_out2;
- devpriv->stc_readl = &win_in2;
- }
-
- ret = mite_setup(devpriv->mite);
- if (ret < 0) {
- pr_warn("error setting up mite\n");
+ if (board->reg_type & ni_reg_m_series_mask)
+ devpriv->is_m_series = 1;
+ if (board->reg_type & ni_reg_6xxx_mask)
+ devpriv->is_6xxx = 1;
+ if (board->reg_type == ni_reg_611x)
+ devpriv->is_611x = 1;
+ if (board->reg_type == ni_reg_6143)
+ devpriv->is_6143 = 1;
+ if (board->reg_type == ni_reg_622x)
+ devpriv->is_622x = 1;
+ if (board->reg_type == ni_reg_625x)
+ devpriv->is_625x = 1;
+ if (board->reg_type == ni_reg_628x)
+ devpriv->is_628x = 1;
+ if (board->reg_type & ni_reg_67xx_mask)
+ devpriv->is_67xx = 1;
+ if (board->reg_type == ni_reg_6711)
+ devpriv->is_6711 = 1;
+ if (board->reg_type == ni_reg_6713)
+ devpriv->is_6713 = 1;
+
+ ret = mite_setup(dev, devpriv->mite);
+ if (ret < 0)
return ret;
- }
devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
if (devpriv->ai_mite_ring == NULL)
@@ -1528,20 +1198,20 @@ static int pcimio_auto_attach(struct comedi_device *dev,
if (devpriv->gpct_mite_ring[1] == NULL)
return -ENOMEM;
- if (board->reg_type & ni_reg_m_series_mask)
+ if (devpriv->is_m_series)
m_series_init_eeprom_buffer(dev);
- if (board->reg_type == ni_reg_6143)
+ if (devpriv->is_6143)
init_6143(dev);
- irq = mite_irq(devpriv->mite);
+ irq = pcidev->irq;
if (irq) {
- ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
+ ret = request_irq(irq, ni_E_interrupt, IRQF_SHARED,
dev->board_name, dev);
if (ret == 0)
dev->irq = irq;
}
- ret = ni_E_init(dev);
+ ret = ni_E_init(dev, 0, 1);
if (ret < 0)
return ret;
@@ -1554,73 +1224,6 @@ static int pcimio_auto_attach(struct comedi_device *dev,
return 0;
}
-static int pcimio_ai_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->ai_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_ao_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->ao_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_gpct0_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->gpct_mite_ring[0], s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_gpct1_change(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->gpct_mite_ring[1], s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int pcimio_dio_change(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned long new_size)
-{
- struct ni_private *devpriv = dev->private;
- int ret;
-
- ret = mite_buf_change(devpriv->cdo_mite_ring, s);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static struct comedi_driver ni_pcimio_driver = {
.driver_name = "ni_pcimio",
.module = THIS_MODULE,
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
index f0630b7897b5..a2841292ddd4 100644
--- a/drivers/staging/comedi/drivers/ni_stc.h
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -1285,14 +1285,6 @@ static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel,
return (bits >> ((channel % 3) * 5)) & 0x1f;
};
-enum MSeries_Gi_DMA_Config_Bits {
- Gi_DMA_BankSW_Error_Bit = 0x10,
- Gi_DMA_Reset_Bit = 0x8,
- Gi_DMA_Int_Enable_Bit = 0x4,
- Gi_DMA_Write_Bit = 0x2,
- Gi_DMA_Enable_Bit = 0x1,
-};
-
static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel)
{
return 0x3 << (channel * 2);
@@ -1388,12 +1380,12 @@ enum Interrupt_C_Status_Bits {
#define M_SERIES_EEPROM_SIZE 1024
struct ni_board_struct {
+ const char *name;
int device_id;
int isapnp_id;
- char *name;
int n_adchan;
- int adbits;
+ unsigned int ai_maxdata;
int ai_fifo_depth;
unsigned int alwaysdither:1;
@@ -1401,107 +1393,100 @@ struct ni_board_struct {
int ai_speed;
int n_aochan;
- int aobits;
+ unsigned int ao_maxdata;
int ao_fifo_depth;
const struct comedi_lrange *ao_range_table;
unsigned ao_speed;
- unsigned num_p0_dio_channels;
-
int reg_type;
- unsigned int ao_unipolar:1;
unsigned int has_8255:1;
- unsigned int has_analog_trig:1;
+ unsigned int has_32dio_chan:1;
enum caldac_enum caldac[3];
};
-#define MAX_N_AO_CHAN 8
-#define NUM_GPCT 2
-
-#define NI_PRIVATE_COMMON \
- uint16_t (*stc_readw)(struct comedi_device *dev, int register); \
- uint32_t (*stc_readl)(struct comedi_device *dev, int register); \
- void (*stc_writew)(struct comedi_device *dev, uint16_t value, int register); \
- void (*stc_writel)(struct comedi_device *dev, uint32_t value, int register); \
- \
- unsigned short dio_output; \
- unsigned short dio_control; \
- int ao0p, ao1p; \
- int lastchan; \
- int last_do; \
- int rt_irq; \
- int irqmask; \
- int aimode; \
- int ai_continuous; \
- int blocksize; \
- int n_left; \
- unsigned int ai_calib_source; \
- unsigned int ai_calib_source_enabled; \
- spinlock_t window_lock; \
- spinlock_t soft_reg_copy_lock; \
- spinlock_t mite_channel_lock; \
- \
- int changain_state; \
- unsigned int changain_spec; \
- \
- unsigned int caldac_maxdata_list[MAX_N_CALDACS]; \
- unsigned short ao[MAX_N_AO_CHAN]; \
- unsigned short caldacs[MAX_N_CALDACS]; \
- \
- unsigned short ai_cmd2; \
- \
- unsigned short ao_conf[MAX_N_AO_CHAN]; \
- unsigned short ao_mode1; \
- unsigned short ao_mode2; \
- unsigned short ao_mode3; \
- unsigned short ao_cmd1; \
- unsigned short ao_cmd2; \
- unsigned short ao_cmd3; \
- unsigned short ao_trigger_select; \
- \
- struct ni_gpct_device *counter_dev; \
- unsigned short an_trig_etc_reg; \
- \
- unsigned ai_offset[512]; \
- \
- unsigned long serial_interval_ns; \
- unsigned char serial_hw_mode; \
- unsigned short clock_and_fout; \
- unsigned short clock_and_fout2; \
- \
- unsigned short int_a_enable_reg; \
- unsigned short int_b_enable_reg; \
- unsigned short io_bidirection_pin_reg; \
- unsigned short rtsi_trig_direction_reg; \
- unsigned short rtsi_trig_a_output_reg; \
- unsigned short rtsi_trig_b_output_reg; \
- unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \
- unsigned short ai_ao_select_reg; \
- unsigned short g0_g1_select_reg; \
- unsigned short cdio_dma_select_reg; \
- \
- unsigned clock_ns; \
- unsigned clock_source; \
- \
- unsigned short atrig_mode; \
- unsigned short atrig_high; \
- unsigned short atrig_low; \
- \
- unsigned short pwm_up_count; \
- unsigned short pwm_down_count; \
- \
- unsigned short ai_fifo_buffer[0x2000]; \
- uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
- uint32_t serial_number; \
- \
- struct mite_struct *mite; \
- struct mite_channel *ai_mite_chan; \
- struct mite_channel *ao_mite_chan;\
- struct mite_channel *cdo_mite_chan;\
- struct mite_dma_descriptor_ring *ai_mite_ring; \
- struct mite_dma_descriptor_ring *ao_mite_ring; \
- struct mite_dma_descriptor_ring *cdo_mite_ring; \
+#define MAX_N_CALDACS 34
+#define MAX_N_AO_CHAN 8
+#define NUM_GPCT 2
+
+struct ni_private {
+ unsigned short dio_output;
+ unsigned short dio_control;
+ int aimode;
+ unsigned int ai_calib_source;
+ unsigned int ai_calib_source_enabled;
+ spinlock_t window_lock;
+ spinlock_t soft_reg_copy_lock;
+ spinlock_t mite_channel_lock;
+
+ int changain_state;
+ unsigned int changain_spec;
+
+ unsigned int caldac_maxdata_list[MAX_N_CALDACS];
+ unsigned short ao[MAX_N_AO_CHAN];
+ unsigned short caldacs[MAX_N_CALDACS];
+
+ unsigned short ai_cmd2;
+
+ unsigned short ao_conf[MAX_N_AO_CHAN];
+ unsigned short ao_mode1;
+ unsigned short ao_mode2;
+ unsigned short ao_mode3;
+ unsigned short ao_cmd1;
+ unsigned short ao_cmd2;
+ unsigned short ao_trigger_select;
+
+ struct ni_gpct_device *counter_dev;
+ unsigned short an_trig_etc_reg;
+
+ unsigned ai_offset[512];
+
+ unsigned long serial_interval_ns;
+ unsigned char serial_hw_mode;
+ unsigned short clock_and_fout;
+ unsigned short clock_and_fout2;
+
+ unsigned short int_a_enable_reg;
+ unsigned short int_b_enable_reg;
+ unsigned short io_bidirection_pin_reg;
+ unsigned short rtsi_trig_direction_reg;
+ unsigned short rtsi_trig_a_output_reg;
+ unsigned short rtsi_trig_b_output_reg;
+ unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS];
+ unsigned short ai_ao_select_reg;
+ unsigned short g0_g1_select_reg;
+ unsigned short cdio_dma_select_reg;
+
+ unsigned clock_ns;
+ unsigned clock_source;
+
+ unsigned short pwm_up_count;
+ unsigned short pwm_down_count;
+
+ unsigned short ai_fifo_buffer[0x2000];
+ uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE];
+ uint32_t serial_number;
+
+ struct mite_struct *mite;
+ struct mite_channel *ai_mite_chan;
+ struct mite_channel *ao_mite_chan;
+ struct mite_channel *cdo_mite_chan;
+ struct mite_dma_descriptor_ring *ai_mite_ring;
+ struct mite_dma_descriptor_ring *ao_mite_ring;
+ struct mite_dma_descriptor_ring *cdo_mite_ring;
struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT];
+ /* ni_pcimio board type flags (based on the boardinfo reg_type) */
+ unsigned int is_m_series:1;
+ unsigned int is_6xxx:1;
+ unsigned int is_611x:1;
+ unsigned int is_6143:1;
+ unsigned int is_622x:1;
+ unsigned int is_625x:1;
+ unsigned int is_628x:1;
+ unsigned int is_67xx:1;
+ unsigned int is_6711:1;
+ unsigned int is_6713:1;
+};
+
#endif /* _COMEDI_NI_STC_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
index 92691b491c24..0525292c1d8b 100644
--- a/drivers/staging/comedi/drivers/ni_tio.c
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -49,363 +49,336 @@ TODO:
#include "ni_tio_internal.h"
-static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
- unsigned generic_clock_source);
-static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter);
+/*
+ * clock sources for ni e and m series boards,
+ * get bits with GI_SRC_SEL()
+ */
+#define NI_M_TIMEBASE_1_CLK 0x0 /* 20MHz */
+#define NI_M_PFI_CLK(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
+#define NI_M_RTSI_CLK(x) (((x) == 7) ? 0x1b : (0xb + (x)))
+#define NI_M_TIMEBASE_2_CLK 0x12 /* 100KHz */
+#define NI_M_NEXT_TC_CLK 0x13
+#define NI_M_NEXT_GATE_CLK 0x14 /* Gi_Src_SubSelect=0 */
+#define NI_M_PXI_STAR_TRIGGER_CLK 0x14 /* Gi_Src_SubSelect=1 */
+#define NI_M_PXI10_CLK 0x1d
+#define NI_M_TIMEBASE_3_CLK 0x1e /* 80MHz, Gi_Src_SubSelect=0 */
+#define NI_M_ANALOG_TRIGGER_OUT_CLK 0x1e /* Gi_Src_SubSelect=1 */
+#define NI_M_LOGIC_LOW_CLK 0x1f
+#define NI_M_MAX_PFI_CHAN 15
+#define NI_M_MAX_RTSI_CHAN 7
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum
- ni_gpct_variant
- variant)
+/*
+ * clock sources for ni_660x boards,
+ * get bits with GI_SRC_SEL()
+ */
+#define NI_660X_TIMEBASE_1_CLK 0x0 /* 20MHz */
+#define NI_660X_SRC_PIN_I_CLK 0x1
+#define NI_660X_SRC_PIN_CLK(x) (0x2 + (x))
+#define NI_660X_NEXT_GATE_CLK 0xa
+#define NI_660X_RTSI_CLK(x) (0xb + (x))
+#define NI_660X_TIMEBASE_2_CLK 0x12 /* 100KHz */
+#define NI_660X_NEXT_TC_CLK 0x13
+#define NI_660X_TIMEBASE_3_CLK 0x1e /* 80MHz */
+#define NI_660X_LOGIC_LOW_CLK 0x1f
+#define NI_660X_MAX_SRC_PIN 7
+#define NI_660X_MAX_RTSI_CHAN 6
+
+/* ni m series gate_select */
+#define NI_M_TIMESTAMP_MUX_GATE_SEL 0x0
+#define NI_M_PFI_GATE_SEL(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
+#define NI_M_RTSI_GATE_SEL(x) (((x) == 7) ? 0x1b : (0xb + (x)))
+#define NI_M_AI_START2_GATE_SEL 0x12
+#define NI_M_PXI_STAR_TRIGGER_GATE_SEL 0x13
+#define NI_M_NEXT_OUT_GATE_SEL 0x14
+#define NI_M_AI_START1_GATE_SEL 0x1c
+#define NI_M_NEXT_SRC_GATE_SEL 0x1d
+#define NI_M_ANALOG_TRIG_OUT_GATE_SEL 0x1e
+#define NI_M_LOGIC_LOW_GATE_SEL 0x1f
+
+/* ni_660x gate select */
+#define NI_660X_SRC_PIN_I_GATE_SEL 0x0
+#define NI_660X_GATE_PIN_I_GATE_SEL 0x1
+#define NI_660X_PIN_GATE_SEL(x) (0x2 + (x))
+#define NI_660X_NEXT_SRC_GATE_SEL 0xa
+#define NI_660X_RTSI_GATE_SEL(x) (0xb + (x))
+#define NI_660X_NEXT_OUT_GATE_SEL 0x14
+#define NI_660X_LOGIC_LOW_GATE_SEL 0x1f
+#define NI_660X_MAX_GATE_PIN 7
+
+/* ni_660x second gate select */
+#define NI_660X_SRC_PIN_I_GATE2_SEL 0x0
+#define NI_660X_UD_PIN_I_GATE2_SEL 0x1
+#define NI_660X_UD_PIN_GATE2_SEL(x) (0x2 + (x))
+#define NI_660X_NEXT_SRC_GATE2_SEL 0xa
+#define NI_660X_RTSI_GATE2_SEL(x) (0xb + (x))
+#define NI_660X_NEXT_OUT_GATE2_SEL 0x14
+#define NI_660X_SELECTED_GATE2_SEL 0x1e
+#define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f
+#define NI_660X_MAX_UP_DOWN_PIN 7
+
+static inline unsigned GI_ALT_SYNC(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_Alternate_Sync_Bit;
- break;
+ return GI_M_ALT_SYNC;
case ni_gpct_variant_660x:
- return Gi_660x_Alternate_Sync_Bit;
- break;
- default:
- BUG();
- break;
+ return GI_660X_ALT_SYNC;
}
- return 0;
}
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
- ni_gpct_variant
- variant)
+static inline unsigned GI_PRESCALE_X2(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_Prescale_X2_Bit;
- break;
+ return GI_M_PRESCALE_X2;
case ni_gpct_variant_660x:
- return Gi_660x_Prescale_X2_Bit;
- break;
- default:
- BUG();
- break;
+ return GI_660X_PRESCALE_X2;
}
- return 0;
}
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
- ni_gpct_variant
- variant)
+static inline unsigned GI_PRESCALE_X8(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_Prescale_X8_Bit;
- break;
+ return GI_M_PRESCALE_X8;
case ni_gpct_variant_660x:
- return Gi_660x_Prescale_X8_Bit;
- break;
- default:
- BUG();
- break;
+ return GI_660X_PRESCALE_X8;
}
- return 0;
}
-static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum
- ni_gpct_variant
- variant)
+static inline unsigned GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant)
{
switch (variant) {
case ni_gpct_variant_e_series:
+ default:
return 0;
- break;
case ni_gpct_variant_m_series:
- return Gi_M_Series_HW_Arm_Select_Mask;
- break;
+ return GI_M_HW_ARM_SEL_MASK;
case ni_gpct_variant_660x:
- return Gi_660x_HW_Arm_Select_Mask;
- break;
- default:
- BUG();
- break;
+ return GI_660X_HW_ARM_SEL_MASK;
}
- return 0;
}
-/* clock sources for ni_660x boards, get bits with Gi_Source_Select_Bits() */
-enum ni_660x_clock_source {
- NI_660x_Timebase_1_Clock = 0x0, /* 20MHz */
- NI_660x_Source_Pin_i_Clock = 0x1,
- NI_660x_Next_Gate_Clock = 0xa,
- NI_660x_Timebase_2_Clock = 0x12, /* 100KHz */
- NI_660x_Next_TC_Clock = 0x13,
- NI_660x_Timebase_3_Clock = 0x1e, /* 80MHz */
- NI_660x_Logic_Low_Clock = 0x1f,
-};
-static const unsigned ni_660x_max_rtsi_channel = 6;
-static inline unsigned NI_660x_RTSI_Clock(unsigned n)
+static int ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev)
{
- BUG_ON(n > ni_660x_max_rtsi_channel);
- return 0xb + n;
-}
-
-static const unsigned ni_660x_max_source_pin = 7;
-static inline unsigned NI_660x_Source_Pin_Clock(unsigned n)
-{
- BUG_ON(n > ni_660x_max_source_pin);
- return 0x2 + n;
-}
-
-/* clock sources for ni e and m series boards, get bits with Gi_Source_Select_Bits() */
-enum ni_m_series_clock_source {
- NI_M_Series_Timebase_1_Clock = 0x0, /* 20MHz */
- NI_M_Series_Timebase_2_Clock = 0x12, /* 100KHz */
- NI_M_Series_Next_TC_Clock = 0x13,
- NI_M_Series_Next_Gate_Clock = 0x14, /* when Gi_Src_SubSelect = 0 */
- NI_M_Series_PXI_Star_Trigger_Clock = 0x14, /* when Gi_Src_SubSelect = 1 */
- NI_M_Series_PXI10_Clock = 0x1d,
- NI_M_Series_Timebase_3_Clock = 0x1e, /* 80MHz, when Gi_Src_SubSelect = 0 */
- NI_M_Series_Analog_Trigger_Out_Clock = 0x1e, /* when Gi_Src_SubSelect = 1 */
- NI_M_Series_Logic_Low_Clock = 0x1f,
-};
-static const unsigned ni_m_series_max_pfi_channel = 15;
-static inline unsigned NI_M_Series_PFI_Clock(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_pfi_channel);
- if (n < 10)
- return 1 + n;
- else
- return 0xb + n;
-}
-
-static const unsigned ni_m_series_max_rtsi_channel = 7;
-static inline unsigned NI_M_Series_RTSI_Clock(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_rtsi_channel);
- if (n == 7)
- return 0x1b;
- else
- return 0xb + n;
-}
-
-enum ni_660x_gate_select {
- NI_660x_Source_Pin_i_Gate_Select = 0x0,
- NI_660x_Gate_Pin_i_Gate_Select = 0x1,
- NI_660x_Next_SRC_Gate_Select = 0xa,
- NI_660x_Next_Out_Gate_Select = 0x14,
- NI_660x_Logic_Low_Gate_Select = 0x1f,
-};
-static const unsigned ni_660x_max_gate_pin = 7;
-static inline unsigned NI_660x_Gate_Pin_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_660x_max_gate_pin);
- return 0x2 + n;
-}
-
-static inline unsigned NI_660x_RTSI_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_660x_max_rtsi_channel);
- return 0xb + n;
-}
-
-enum ni_m_series_gate_select {
- NI_M_Series_Timestamp_Mux_Gate_Select = 0x0,
- NI_M_Series_AI_START2_Gate_Select = 0x12,
- NI_M_Series_PXI_Star_Trigger_Gate_Select = 0x13,
- NI_M_Series_Next_Out_Gate_Select = 0x14,
- NI_M_Series_AI_START1_Gate_Select = 0x1c,
- NI_M_Series_Next_SRC_Gate_Select = 0x1d,
- NI_M_Series_Analog_Trigger_Out_Gate_Select = 0x1e,
- NI_M_Series_Logic_Low_Gate_Select = 0x1f,
-};
-static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_rtsi_channel);
- if (n == 7)
- return 0x1b;
- return 0xb + n;
-}
-
-static inline unsigned NI_M_Series_PFI_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_m_series_max_pfi_channel);
- if (n < 10)
- return 1 + n;
- return 0xb + n;
-}
-
-static inline unsigned Gi_Source_Select_Bits(unsigned source)
-{
- return (source << Gi_Source_Select_Shift) & Gi_Source_Select_Mask;
-}
-
-static inline unsigned Gi_Gate_Select_Bits(unsigned gate_select)
-{
- return (gate_select << Gi_Gate_Select_Shift) & Gi_Gate_Select_Mask;
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ default:
+ return 0;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ return 1;
+ }
}
-enum ni_660x_second_gate_select {
- NI_660x_Source_Pin_i_Second_Gate_Select = 0x0,
- NI_660x_Up_Down_Pin_i_Second_Gate_Select = 0x1,
- NI_660x_Next_SRC_Second_Gate_Select = 0xa,
- NI_660x_Next_Out_Second_Gate_Select = 0x14,
- NI_660x_Selected_Gate_Second_Gate_Select = 0x1e,
- NI_660x_Logic_Low_Second_Gate_Select = 0x1f,
-};
-static const unsigned ni_660x_max_up_down_pin = 7;
-static inline unsigned NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned n)
+static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
{
- BUG_ON(n > ni_660x_max_up_down_pin);
- return 0x2 + n;
-}
+ unsigned cidx = counter->counter_index;
-static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n)
-{
- BUG_ON(n > ni_660x_max_rtsi_channel);
- return 0xb + n;
+ write_register(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx));
}
-static const unsigned int counter_status_mask =
- COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
-
-struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device *dev,
- void (*write_register) (struct
- ni_gpct
- *
- counter,
- unsigned
- bits,
- enum
- ni_gpct_register
- reg),
- unsigned (*read_register)
- (struct ni_gpct *counter,
- enum ni_gpct_register reg),
- enum ni_gpct_variant variant,
- unsigned num_counters)
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ unsigned generic_clock_source)
{
- unsigned i;
+ uint64_t clock_period_ps;
- struct ni_gpct_device *counter_dev =
- kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL);
- if (counter_dev == NULL)
- return NULL;
- counter_dev->dev = dev;
- counter_dev->write_register = write_register;
- counter_dev->read_register = read_register;
- counter_dev->variant = variant;
- spin_lock_init(&counter_dev->regs_lock);
- BUG_ON(num_counters == 0);
- counter_dev->counters =
- kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
- if (counter_dev->counters == NULL) {
- kfree(counter_dev);
- return NULL;
- }
- for (i = 0; i < num_counters; ++i) {
- counter_dev->counters[i].counter_dev = counter_dev;
- spin_lock_init(&counter_dev->counters[i].lock);
+ switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ clock_period_ps = 50000;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ clock_period_ps = 10000000;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ clock_period_ps = 12500;
+ break;
+ case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+ clock_period_ps = 100000;
+ break;
+ default:
+ /*
+ * clock period is specified by user with prescaling
+ * already taken into account.
+ */
+ return counter->clock_period_ps;
}
- counter_dev->num_counters = num_counters;
- return counter_dev;
-}
-EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
-
-void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
-{
- if (counter_dev->counters == NULL)
- return;
- kfree(counter_dev->counters);
- kfree(counter_dev);
-}
-EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
-static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
- *counter_dev)
-{
- switch (counter_dev->variant) {
- case ni_gpct_variant_e_series:
- return 0;
+ switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
break;
- case ni_gpct_variant_m_series:
- case ni_gpct_variant_660x:
- return 1;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ clock_period_ps *= 2;
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ clock_period_ps *= 8;
break;
default:
BUG();
break;
}
- return 0;
+ return clock_period_ps;
}
-static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
+static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
+ const unsigned counting_mode_bits =
+ ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
+ unsigned bits = 0;
- write_register(counter, Gi_Reset_Bit(cidx), NITIO_RESET_REG(cidx));
+ if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
+ GI_SRC_POL_INVERT)
+ bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
+ if (counting_mode_bits & GI_PRESCALE_X2(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
+ if (counting_mode_bits & GI_PRESCALE_X8(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
+ return bits;
}
-void ni_tio_init_counter(struct ni_gpct *counter)
+static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
+ const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
+ unsigned clock_source = 0;
+ unsigned src;
+ unsigned i;
- ni_tio_reset_count_and_disarm(counter);
-
- /* initialize counter registers */
- counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0;
- write_register(counter, counter_dev->regs[NITIO_AUTO_INC_REG(cidx)],
- NITIO_AUTO_INC_REG(cidx));
-
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- ~0, Gi_Synchronize_Gate_Bit);
-
- ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);
-
- counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0;
- write_register(counter, counter_dev->regs[NITIO_LOADA_REG(cidx)],
- NITIO_LOADA_REG(cidx));
+ src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
+ NITIO_INPUT_SEL_REG(cidx)));
- counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0;
- write_register(counter, counter_dev->regs[NITIO_LOADB_REG(cidx)],
- NITIO_LOADB_REG(cidx));
+ switch (src) {
+ case NI_M_TIMEBASE_1_CLK:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_M_TIMEBASE_2_CLK:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_M_TIMEBASE_3_CLK:
+ if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
+ clock_source =
+ NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_M_LOGIC_LOW_CLK:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_M_NEXT_GATE_CLK:
+ if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
+ clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_M_PXI10_CLK:
+ clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
+ break;
+ case NI_M_NEXT_TC_CLK:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (src == NI_M_RTSI_CLK(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_M_MAX_RTSI_CHAN)
+ break;
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (src == NI_M_PFI_CLK(i)) {
+ clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_M_MAX_PFI_CHAN)
+ break;
+ BUG();
+ break;
+ }
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
+}
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);
+static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
+{
+ unsigned clock_source = 0;
+ unsigned cidx = counter->counter_index;
+ unsigned src;
+ unsigned i;
- if (ni_tio_counting_mode_registers_present(counter_dev))
- ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);
+ src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
+ NITIO_INPUT_SEL_REG(cidx)));
- if (ni_tio_second_gate_registers_present(counter_dev)) {
- counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0;
- write_register(counter,
- counter_dev->regs[NITIO_GATE2_REG(cidx)],
- NITIO_GATE2_REG(cidx));
+ switch (src) {
+ case NI_660X_TIMEBASE_1_CLK:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_TIMEBASE_2_CLK:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_TIMEBASE_3_CLK:
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_LOGIC_LOW_CLK:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_SRC_PIN_I_CLK:
+ clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_NEXT_GATE_CLK:
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_660X_NEXT_TC_CLK:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (src == NI_660X_RTSI_CLK(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_660X_MAX_RTSI_CHAN)
+ break;
+ for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
+ if (src == NI_660X_SRC_PIN_CLK(i)) {
+ clock_source =
+ NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= NI_660X_MAX_SRC_PIN)
+ break;
+ BUG();
+ break;
}
-
- ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);
-
- ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
}
-EXPORT_SYMBOL_GPL(ni_tio_init_counter);
-static unsigned int ni_tio_counter_status(struct ni_gpct *counter)
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
{
- unsigned cidx = counter->counter_index;
- const unsigned bits = read_register(counter,
- NITIO_SHARED_STATUS_REG(cidx));
- unsigned int status = 0;
-
- if (bits & Gi_Armed_Bit(cidx)) {
- status |= COMEDI_COUNTER_ARMED;
- if (bits & Gi_Counting_Bit(cidx))
- status |= COMEDI_COUNTER_COUNTING;
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ default:
+ return ni_m_series_clock_src_select(counter);
+ case ni_gpct_variant_660x:
+ return ni_660x_clock_src_select(counter);
}
- return status;
}
static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
@@ -414,34 +387,40 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
unsigned cidx = counter->counter_index;
const unsigned counting_mode_reg = NITIO_CNT_MODE_REG(cidx);
static const uint64_t min_normal_sync_period_ps = 25000;
- const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
- ni_tio_generic_clock_src_select
- (counter));
+ unsigned mode;
+ uint64_t clock_period_ps;
if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
return;
- switch (ni_tio_get_soft_copy(counter, counting_mode_reg) & Gi_Counting_Mode_Mask) {
- case Gi_Counting_Mode_QuadratureX1_Bits:
- case Gi_Counting_Mode_QuadratureX2_Bits:
- case Gi_Counting_Mode_QuadratureX4_Bits:
- case Gi_Counting_Mode_Sync_Source_Bits:
+ mode = ni_tio_get_soft_copy(counter, counting_mode_reg);
+ switch (mode & GI_CNT_MODE_MASK) {
+ case GI_CNT_MODE_QUADX1:
+ case GI_CNT_MODE_QUADX2:
+ case GI_CNT_MODE_QUADX4:
+ case GI_CNT_MODE_SYNC_SRC:
force_alt_sync = 1;
break;
default:
break;
}
- /* It's not clear what we should do if clock_period is unknown, so we are not
- using the alt sync bit in that case, but allow the caller to decide by using the
- force_alt_sync parameter. */
+
+ clock_period_ps = ni_tio_clock_period_ps(counter,
+ ni_tio_generic_clock_src_select(counter));
+
+ /*
+ * It's not clear what we should do if clock_period is unknown, so we
+ * are not using the alt sync bit in that case, but allow the caller
+ * to decide by using the force_alt_sync parameter.
+ */
if (force_alt_sync ||
(clock_period_ps && clock_period_ps < min_normal_sync_period_ps)) {
ni_tio_set_bits(counter, counting_mode_reg,
- Gi_Alternate_Sync_Bit(counter_dev->variant),
- Gi_Alternate_Sync_Bit(counter_dev->variant));
+ GI_ALT_SYNC(counter_dev->variant),
+ GI_ALT_SYNC(counter_dev->variant));
} else {
ni_tio_set_bits(counter, counting_mode_reg,
- Gi_Alternate_Sync_Bit(counter_dev->variant),
+ GI_ALT_SYNC(counter_dev->variant),
0x0);
}
}
@@ -460,18 +439,18 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
- mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit;
+ mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING;
mode_reg_values = mode & mode_reg_direct_mask;
switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
break;
case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
- mode_reg_values |= Gi_Reload_Source_Switching_Bit;
+ mode_reg_values |= GI_RELOAD_SRC_SWITCHING;
break;
case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
- input_select_bits |= Gi_Gate_Select_Load_Source_Bit;
- mode_reg_mask |= Gi_Gating_Mode_Mask;
- mode_reg_values |= Gi_Level_Gating_Bits;
+ input_select_bits |= GI_GATE_SEL_LOAD_SRC;
+ mode_reg_mask |= GI_GATING_MODE_MASK;
+ mode_reg_values |= GI_LEVEL_GATING;
break;
default:
break;
@@ -480,33 +459,28 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
mode_reg_mask, mode_reg_values);
if (ni_tio_counting_mode_registers_present(counter_dev)) {
- unsigned counting_mode_bits = 0;
- counting_mode_bits |=
- (mode >> NI_GPCT_COUNTING_MODE_SHIFT) &
- Gi_Counting_Mode_Mask;
- counting_mode_bits |=
- ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
- Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
+ unsigned bits = 0;
+
+ bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT);
+ bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT));
if (mode & NI_GPCT_INDEX_ENABLE_BIT)
- counting_mode_bits |= Gi_Index_Mode_Bit;
+ bits |= GI_INDEX_MODE;
ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask |
- Gi_Index_Mode_Bit, counting_mode_bits);
+ GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK |
+ GI_INDEX_MODE, bits);
ni_tio_set_sync_mode(counter, 0);
}
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- Gi_Up_Down_Mask,
- (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) <<
- Gi_Up_Down_Shift);
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK,
+ GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT));
if (mode & NI_GPCT_OR_GATE_BIT)
- input_select_bits |= Gi_Or_Gate_Bit;
+ input_select_bits |= GI_OR_GATE;
if (mode & NI_GPCT_INVERT_OUTPUT_BIT)
- input_select_bits |= Gi_Output_Polarity_Bit;
+ input_select_bits |= GI_OUTPUT_POL_INVERT;
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
- Gi_Output_Polarity_Bit, input_select_bits);
+ GI_GATE_SEL_LOAD_SRC | GI_OR_GATE |
+ GI_OUTPUT_POL_INVERT, input_select_bits);
return 0;
}
@@ -520,16 +494,19 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
if (arm) {
switch (start_trigger) {
case NI_GPCT_ARM_IMMEDIATE:
- command_transient_bits |= Gi_Arm_Bit;
+ command_transient_bits |= GI_ARM;
break;
case NI_GPCT_ARM_PAIRED_IMMEDIATE:
- command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit;
+ command_transient_bits |= GI_ARM | GI_ARM_COPY;
break;
default:
break;
}
if (ni_tio_counting_mode_registers_present(counter_dev)) {
- unsigned counting_mode_bits = 0;
+ unsigned bits = 0;
+ unsigned sel_mask;
+
+ sel_mask = GI_HW_ARM_SEL_MASK(counter_dev->variant);
switch (start_trigger) {
case NI_GPCT_ARM_IMMEDIATE:
@@ -537,29 +514,24 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
break;
default:
if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
- /* pass-through the least significant bits so we can figure out what select later */
- unsigned hw_arm_select_bits =
- (start_trigger <<
- Gi_HW_Arm_Select_Shift) &
- Gi_HW_Arm_Select_Mask
- (counter_dev->variant);
-
- counting_mode_bits |=
- Gi_HW_Arm_Enable_Bit |
- hw_arm_select_bits;
+ /*
+ * pass-through the least significant
+ * bits so we can figure out what
+ * select later
+ */
+ bits |= GI_HW_ARM_ENA |
+ (GI_HW_ARM_SEL(start_trigger) &
+ sel_mask);
} else {
return -EINVAL;
}
break;
}
ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- Gi_HW_Arm_Select_Mask
- (counter_dev->variant) |
- Gi_HW_Arm_Enable_Bit,
- counting_mode_bits);
+ GI_HW_ARM_ENA | sel_mask, bits);
}
} else {
- command_transient_bits |= Gi_Disarm_Bit;
+ command_transient_bits |= GI_DISARM;
}
ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
0, 0, command_transient_bits);
@@ -567,118 +539,116 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
}
EXPORT_SYMBOL_GPL(ni_tio_arm);
-static unsigned ni_660x_source_select_bits(unsigned int clock_source)
+static unsigned ni_660x_clk_src(unsigned int clock_source)
{
+ unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
unsigned ni_660x_clock;
unsigned i;
- const unsigned clock_select_bits =
- clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
- switch (clock_select_bits) {
+ switch (clk_src) {
case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Timebase_1_Clock;
+ ni_660x_clock = NI_660X_TIMEBASE_1_CLK;
break;
case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Timebase_2_Clock;
+ ni_660x_clock = NI_660X_TIMEBASE_2_CLK;
break;
case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Timebase_3_Clock;
+ ni_660x_clock = NI_660X_TIMEBASE_3_CLK;
break;
case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Logic_Low_Clock;
+ ni_660x_clock = NI_660X_LOGIC_LOW_CLK;
break;
case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Source_Pin_i_Clock;
+ ni_660x_clock = NI_660X_SRC_PIN_I_CLK;
break;
case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Next_Gate_Clock;
+ ni_660x_clock = NI_660X_NEXT_GATE_CLK;
break;
case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
- ni_660x_clock = NI_660x_Next_TC_Clock;
+ ni_660x_clock = NI_660X_NEXT_TC_CLK;
break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
- ni_660x_clock = NI_660x_RTSI_Clock(i);
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660X_RTSI_CLK(i);
break;
}
}
- if (i <= ni_660x_max_rtsi_channel)
+ if (i <= NI_660X_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_660x_max_source_pin; ++i) {
- if (clock_select_bits ==
- NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
- ni_660x_clock = NI_660x_Source_Pin_Clock(i);
+ for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
+ if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660X_SRC_PIN_CLK(i);
break;
}
}
- if (i <= ni_660x_max_source_pin)
+ if (i <= NI_660X_MAX_SRC_PIN)
break;
ni_660x_clock = 0;
BUG();
break;
}
- return Gi_Source_Select_Bits(ni_660x_clock);
+ return GI_SRC_SEL(ni_660x_clock);
}
-static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
+static unsigned ni_m_clk_src(unsigned int clock_source)
{
+ unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
unsigned ni_m_series_clock;
unsigned i;
- const unsigned clock_select_bits =
- clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
- switch (clock_select_bits) {
+
+ switch (clk_src) {
case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Timebase_1_Clock;
+ ni_m_series_clock = NI_M_TIMEBASE_1_CLK;
break;
case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Timebase_2_Clock;
+ ni_m_series_clock = NI_M_TIMEBASE_2_CLK;
break;
case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Timebase_3_Clock;
+ ni_m_series_clock = NI_M_TIMEBASE_3_CLK;
break;
case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Logic_Low_Clock;
+ ni_m_series_clock = NI_M_LOGIC_LOW_CLK;
break;
case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Next_Gate_Clock;
+ ni_m_series_clock = NI_M_NEXT_GATE_CLK;
break;
case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Next_TC_Clock;
+ ni_m_series_clock = NI_M_NEXT_TC_CLK;
break;
case NI_GPCT_PXI10_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_PXI10_Clock;
+ ni_m_series_clock = NI_M_PXI10_CLK;
break;
case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock;
+ ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK;
break;
case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
- ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock;
+ ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK;
break;
default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
- ni_m_series_clock = NI_M_Series_RTSI_Clock(i);
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_RTSI_CLK(i);
break;
}
}
- if (i <= ni_m_series_max_rtsi_channel)
+ if (i <= NI_M_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
- ni_m_series_clock = NI_M_Series_PFI_Clock(i);
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_PFI_CLK(i);
break;
}
}
- if (i <= ni_m_series_max_pfi_channel)
+ if (i <= NI_M_MAX_PFI_CHAN)
break;
- printk(KERN_ERR "invalid clock source 0x%lx\n",
+ pr_err("invalid clock source 0x%lx\n",
(unsigned long)clock_source);
BUG();
ni_m_series_clock = 0;
break;
}
- return Gi_Source_Select_Bits(ni_m_series_clock);
+ return GI_SRC_SEL(ni_m_series_clock);
};
static void ni_tio_set_source_subselect(struct ni_gpct *counter,
@@ -694,17 +664,16 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter,
/* Gi_Source_Subselect is zero */
case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit;
+ counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL;
break;
/* Gi_Source_Subselect is one */
case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
- counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit;
+ counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL;
break;
/* Gi_Source_Subselect doesn't matter */
default:
return;
- break;
}
write_register(counter, counter_dev->regs[second_gate_reg],
second_gate_reg);
@@ -716,344 +685,109 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- unsigned input_select_bits = 0;
- static const uint64_t pico_per_nano = 1000;
+ unsigned bits = 0;
-/*FIXME: validate clock source */
+ /* FIXME: validate clock source */
switch (counter_dev->variant) {
case ni_gpct_variant_660x:
- input_select_bits |= ni_660x_source_select_bits(clock_source);
+ bits |= ni_660x_clk_src(clock_source);
break;
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- input_select_bits |=
- ni_m_series_source_select_bits(clock_source);
- break;
default:
- BUG();
+ bits |= ni_m_clk_src(clock_source);
break;
}
if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
- input_select_bits |= Gi_Source_Polarity_Bit;
+ bits |= GI_SRC_POL_INVERT;
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Source_Select_Mask | Gi_Source_Polarity_Bit,
- input_select_bits);
+ GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, bits);
ni_tio_set_source_subselect(counter, clock_source);
- if (ni_tio_counting_mode_registers_present(counter_dev)) {
- const unsigned prescaling_mode =
- clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
- unsigned counting_mode_bits = 0;
- switch (prescaling_mode) {
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ bits = 0;
+ switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
break;
case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
- counting_mode_bits |=
- Gi_Prescale_X2_Bit(counter_dev->variant);
+ bits |= GI_PRESCALE_X2(counter_dev->variant);
break;
case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
- counting_mode_bits |=
- Gi_Prescale_X8_Bit(counter_dev->variant);
+ bits |= GI_PRESCALE_X8(counter_dev->variant);
break;
default:
return -EINVAL;
- break;
}
ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
- Gi_Prescale_X2_Bit(counter_dev->variant) |
- Gi_Prescale_X8_Bit(counter_dev->variant),
- counting_mode_bits);
+ GI_PRESCALE_X2(counter_dev->variant) |
+ GI_PRESCALE_X8(counter_dev->variant), bits);
}
- counter->clock_period_ps = pico_per_nano * period_ns;
+ counter->clock_period_ps = period_ns * 1000;
ni_tio_set_sync_mode(counter, 0);
return 0;
}
-static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned cidx = counter->counter_index;
- const unsigned counting_mode_bits =
- ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
- unsigned bits = 0;
-
- if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Source_Polarity_Bit)
- bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
- if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant))
- bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
- if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant))
- bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
- return bits;
-}
-
-static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
-{
- struct ni_gpct_device *counter_dev = counter->counter_dev;
- unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- unsigned clock_source = 0;
- unsigned i;
- const unsigned input_select =
- (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Source_Select_Mask) >> Gi_Source_Select_Shift;
-
- switch (input_select) {
- case NI_M_Series_Timebase_1_Clock:
- clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Timebase_2_Clock:
- clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Timebase_3_Clock:
- if (counter_dev->regs[second_gate_reg] &
- Gi_Source_Subselect_Bit)
- clock_source =
- NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
- else
- clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Logic_Low_Clock:
- clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Next_Gate_Clock:
- if (counter_dev->regs[second_gate_reg] &
- Gi_Source_Subselect_Bit)
- clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
- else
- clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_PXI10_Clock:
- clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
- break;
- case NI_M_Series_Next_TC_Clock:
- clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
- break;
- default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (input_select == NI_M_Series_RTSI_Clock(i)) {
- clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_m_series_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (input_select == NI_M_Series_PFI_Clock(i)) {
- clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_m_series_max_pfi_channel)
- break;
- BUG();
- break;
- }
- clock_source |= ni_tio_clock_src_modifiers(counter);
- return clock_source;
-}
-
-static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
-{
- unsigned clock_source = 0;
- unsigned cidx = counter->counter_index;
- const unsigned input_select =
- (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Source_Select_Mask) >> Gi_Source_Select_Shift;
- unsigned i;
-
- switch (input_select) {
- case NI_660x_Timebase_1_Clock:
- clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
- break;
- case NI_660x_Timebase_2_Clock:
- clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
- break;
- case NI_660x_Timebase_3_Clock:
- clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
- break;
- case NI_660x_Logic_Low_Clock:
- clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
- break;
- case NI_660x_Source_Pin_i_Clock:
- clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
- break;
- case NI_660x_Next_Gate_Clock:
- clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
- break;
- case NI_660x_Next_TC_Clock:
- clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
- break;
- default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (input_select == NI_660x_RTSI_Clock(i)) {
- clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_660x_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_660x_max_source_pin; ++i) {
- if (input_select == NI_660x_Source_Pin_Clock(i)) {
- clock_source =
- NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
- break;
- }
- }
- if (i <= ni_660x_max_source_pin)
- break;
- BUG();
- break;
- }
- clock_source |= ni_tio_clock_src_modifiers(counter);
- return clock_source;
-}
-
-static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
-{
- switch (counter->counter_dev->variant) {
- case ni_gpct_variant_e_series:
- case ni_gpct_variant_m_series:
- return ni_m_series_clock_src_select(counter);
- break;
- case ni_gpct_variant_660x:
- return ni_660x_clock_src_select(counter);
- break;
- default:
- BUG();
- break;
- }
- return 0;
-}
-
-static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
- unsigned generic_clock_source)
-{
- uint64_t clock_period_ps;
-
- switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
- case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
- clock_period_ps = 50000;
- break;
- case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
- clock_period_ps = 10000000;
- break;
- case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
- clock_period_ps = 12500;
- break;
- case NI_GPCT_PXI10_CLOCK_SRC_BITS:
- clock_period_ps = 100000;
- break;
- default:
- /* clock period is specified by user with prescaling already taken into account. */
- return counter->clock_period_ps;
- break;
- }
-
- switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
- case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
- break;
- case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
- clock_period_ps *= 2;
- break;
- case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
- clock_period_ps *= 8;
- break;
- default:
- BUG();
- break;
- }
- return clock_period_ps;
-}
-
static void ni_tio_get_clock_src(struct ni_gpct *counter,
unsigned int *clock_source,
unsigned int *period_ns)
{
- static const unsigned pico_per_nano = 1000;
uint64_t temp64;
+
*clock_source = ni_tio_generic_clock_src_select(counter);
temp64 = ni_tio_clock_period_ps(counter, *clock_source);
- do_div(temp64, pico_per_nano);
+ do_div(temp64, 1000); /* ps to ns */
*period_ns = temp64;
}
-static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{
- const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
+ unsigned int chan = CR_CHAN(gate_source);
unsigned cidx = counter->counter_index;
- unsigned mode_values = 0;
-
- if (gate_source & CR_INVERT)
- mode_values |= Gi_Gate_Polarity_Bit;
- if (gate_source & CR_EDGE)
- mode_values |= Gi_Rising_Edge_Gating_Bits;
- else
- mode_values |= Gi_Level_Gating_Bits;
- ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
- mode_mask, mode_values);
-}
-
-static int ni_660x_set_first_gate(struct ni_gpct *counter,
- unsigned int gate_source)
-{
- const unsigned selected_gate = CR_CHAN(gate_source);
- unsigned cidx = counter->counter_index;
- /* bits of selected_gate that may be meaningful to input select register */
- const unsigned selected_gate_mask = 0x1f;
- unsigned ni_660x_gate_select;
+ unsigned gate_sel;
unsigned i;
- switch (selected_gate) {
+ switch (chan) {
case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select;
+ gate_sel = NI_660X_NEXT_SRC_GATE_SEL;
break;
case NI_GPCT_NEXT_OUT_GATE_SELECT:
case NI_GPCT_LOGIC_LOW_GATE_SELECT:
case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
case NI_GPCT_GATE_PIN_i_GATE_SELECT:
- ni_660x_gate_select = selected_gate & selected_gate_mask;
+ gate_sel = chan & 0x1f;
break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
- ni_660x_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_rtsi_channel)
+ if (i <= NI_660X_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
- if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
- ni_660x_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
+ if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_gate_pin)
+ if (i <= NI_660X_MAX_GATE_PIN)
break;
return -EINVAL;
- break;
}
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Gate_Select_Mask,
- Gi_Gate_Select_Bits(ni_660x_gate_select));
+ GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
return 0;
}
-static int ni_m_series_set_first_gate(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
{
- const unsigned selected_gate = CR_CHAN(gate_source);
+ unsigned int chan = CR_CHAN(gate_source);
unsigned cidx = counter->counter_index;
- /* bits of selected_gate that may be meaningful to input select register */
- const unsigned selected_gate_mask = 0x1f;
- unsigned ni_m_series_gate_select;
+ unsigned gate_sel;
unsigned i;
- switch (selected_gate) {
+ switch (chan) {
case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
case NI_GPCT_AI_START2_GATE_SELECT:
case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
@@ -1062,120 +796,99 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter,
case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- ni_m_series_gate_select = selected_gate & selected_gate_mask;
+ gate_sel = chan & 0x1f;
break;
default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
- ni_m_series_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_m_series_max_rtsi_channel)
+ if (i <= NI_M_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) {
- ni_m_series_gate_select =
- selected_gate & selected_gate_mask;
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (chan == NI_GPCT_PFI_GATE_SELECT(i)) {
+ gate_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_m_series_max_pfi_channel)
+ if (i <= NI_M_MAX_PFI_CHAN)
break;
return -EINVAL;
- break;
}
ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Gate_Select_Mask,
- Gi_Gate_Select_Bits(ni_m_series_gate_select));
+ GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
return 0;
}
-static int ni_660x_set_second_gate(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- const unsigned selected_second_gate = CR_CHAN(gate_source);
- /* bits of second_gate that may be meaningful to second gate register */
- static const unsigned selected_second_gate_mask = 0x1f;
- unsigned ni_660x_second_gate_select;
+ unsigned int chan = CR_CHAN(gate_source);
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned gate2_sel;
unsigned i;
- switch (selected_second_gate) {
+ switch (chan) {
case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
case NI_GPCT_SELECTED_GATE_GATE_SELECT:
case NI_GPCT_NEXT_OUT_GATE_SELECT:
case NI_GPCT_LOGIC_LOW_GATE_SELECT:
- ni_660x_second_gate_select =
- selected_second_gate & selected_second_gate_mask;
+ gate2_sel = chan & 0x1f;
break;
case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
- ni_660x_second_gate_select =
- NI_660x_Next_SRC_Second_Gate_Select;
+ gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL;
break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
- ni_660x_second_gate_select =
- selected_second_gate &
- selected_second_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ gate2_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_rtsi_channel)
+ if (i <= NI_660X_MAX_RTSI_CHAN)
break;
- for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
- if (selected_second_gate ==
- NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
- ni_660x_second_gate_select =
- selected_second_gate &
- selected_second_gate_mask;
+ for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
+ if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
+ gate2_sel = chan & 0x1f;
break;
}
}
- if (i <= ni_660x_max_up_down_pin)
+ if (i <= NI_660X_MAX_UP_DOWN_PIN)
break;
return -EINVAL;
- break;
}
- counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
- counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
- counter_dev->regs[second_gate_reg] |=
- Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
- write_register(counter, counter_dev->regs[second_gate_reg],
- second_gate_reg);
+ counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
+ counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
+ write_register(counter, counter_dev->regs[gate2_reg], gate2_reg);
return 0;
}
-static int ni_m_series_set_second_gate(struct ni_gpct *counter,
- unsigned int gate_source)
+static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- const unsigned selected_second_gate = CR_CHAN(gate_source);
- /* bits of second_gate that may be meaningful to second gate register */
- static const unsigned selected_second_gate_mask = 0x1f;
- unsigned ni_m_series_second_gate_select;
-
- /* FIXME: We don't know what the m-series second gate codes are, so we'll just pass
- the bits through for now. */
- switch (selected_second_gate) {
+ unsigned int chan = CR_CHAN(gate_source);
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned gate2_sel;
+
+ /*
+ * FIXME: We don't know what the m-series second gate codes are,
+ * so we'll just pass the bits through for now.
+ */
+ switch (chan) {
default:
- ni_m_series_second_gate_select =
- selected_second_gate & selected_second_gate_mask;
+ gate2_sel = chan & 0x1f;
break;
}
- counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
- counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
- counter_dev->regs[second_gate_reg] |=
- Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
- write_register(counter, counter_dev->regs[second_gate_reg],
- second_gate_reg);
+ counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
+ counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
+ write_register(counter, counter_dev->regs[gate2_reg], gate2_reg);
return 0;
}
@@ -1184,56 +897,55 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
+ unsigned int chan = CR_CHAN(gate_source);
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned mode = 0;
switch (gate_index) {
case 0:
- if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+ if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
- Gi_Gating_Mode_Mask,
- Gi_Gating_Disabled_Bits);
+ GI_GATING_MODE_MASK,
+ GI_GATING_DISABLED);
return 0;
}
- ni_tio_set_first_gate_modifiers(counter, gate_source);
+ if (gate_source & CR_INVERT)
+ mode |= GI_GATE_POL_INVERT;
+ if (gate_source & CR_EDGE)
+ mode |= GI_RISING_EDGE_GATING;
+ else
+ mode |= GI_LEVEL_GATING;
+ ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
+ GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
+ mode);
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- return ni_m_series_set_first_gate(counter, gate_source);
- break;
- case ni_gpct_variant_660x:
- return ni_660x_set_first_gate(counter, gate_source);
- break;
default:
- BUG();
- break;
+ return ni_m_set_gate(counter, gate_source);
+ case ni_gpct_variant_660x:
+ return ni_660x_set_gate(counter, gate_source);
}
break;
case 1:
- if (ni_tio_second_gate_registers_present(counter_dev) == 0)
+ if (!ni_tio_has_gate2_registers(counter_dev))
return -EINVAL;
- if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
- counter_dev->regs[second_gate_reg] &=
- ~Gi_Second_Gate_Mode_Bit;
- write_register(counter,
- counter_dev->regs[second_gate_reg],
- second_gate_reg);
+
+ if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE;
+ write_register(counter, counter_dev->regs[gate2_reg],
+ gate2_reg);
return 0;
}
- if (gate_source & CR_INVERT) {
- counter_dev->regs[second_gate_reg] |=
- Gi_Second_Gate_Polarity_Bit;
- } else {
- counter_dev->regs[second_gate_reg] &=
- ~Gi_Second_Gate_Polarity_Bit;
- }
+ if (gate_source & CR_INVERT)
+ counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT;
+ else
+ counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT;
switch (counter_dev->variant) {
case ni_gpct_variant_m_series:
- return ni_m_series_set_second_gate(counter,
- gate_source);
- break;
+ return ni_m_set_gate2(counter, gate_source);
case ni_gpct_variant_660x:
- return ni_660x_set_second_gate(counter, gate_source);
- break;
+ return ni_660x_set_gate2(counter, gate_source);
default:
BUG();
break;
@@ -1241,7 +953,6 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
break;
default:
return -EINVAL;
- break;
}
return 0;
}
@@ -1252,196 +963,142 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
+ unsigned int abz_reg, shift, mask;
- if (counter_dev->variant == ni_gpct_variant_m_series) {
- unsigned int abz_reg, shift, mask;
+ if (counter_dev->variant != ni_gpct_variant_m_series)
+ return -EINVAL;
- abz_reg = NITIO_ABZ_REG(cidx);
- switch (index) {
- case NI_GPCT_SOURCE_ENCODER_A:
- shift = 10;
- break;
- case NI_GPCT_SOURCE_ENCODER_B:
- shift = 5;
- break;
- case NI_GPCT_SOURCE_ENCODER_Z:
- shift = 0;
- break;
- default:
- return -EINVAL;
- break;
- }
- mask = 0x1f << shift;
- if (source > 0x1f) {
- /* Disable gate */
- source = 0x1f;
- }
- counter_dev->regs[abz_reg] &= ~mask;
- counter_dev->regs[abz_reg] |= (source << shift) & mask;
- write_register(counter, counter_dev->regs[abz_reg], abz_reg);
- return 0;
+ abz_reg = NITIO_ABZ_REG(cidx);
+ switch (index) {
+ case NI_GPCT_SOURCE_ENCODER_A:
+ shift = 10;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_B:
+ shift = 5;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_Z:
+ shift = 0;
+ break;
+ default:
+ return -EINVAL;
}
- return -EINVAL;
+ mask = 0x1f << shift;
+ if (source > 0x1f)
+ source = 0x1f; /* Disable gate */
+
+ counter_dev->regs[abz_reg] &= ~mask;
+ counter_dev->regs[abz_reg] |= (source << shift) & mask;
+ write_register(counter, counter_dev->regs[abz_reg], abz_reg);
+ return 0;
}
-static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
- ni_660x_gate_select)
+static unsigned ni_660x_gate_to_generic_gate(unsigned gate)
{
unsigned i;
- switch (ni_660x_gate_select) {
- case NI_660x_Source_Pin_i_Gate_Select:
+ switch (gate) {
+ case NI_660X_SRC_PIN_I_GATE_SEL:
return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Gate_Pin_i_Gate_Select:
+ case NI_660X_GATE_PIN_I_GATE_SEL:
return NI_GPCT_GATE_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Next_SRC_Gate_Select:
+ case NI_660X_NEXT_SRC_GATE_SEL:
return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_660x_Next_Out_Gate_Select:
+ case NI_660X_NEXT_OUT_GATE_SEL:
return NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_660x_Logic_Low_Gate_Select:
+ case NI_660X_LOGIC_LOW_GATE_SEL:
return NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (gate == NI_660X_RTSI_GATE_SEL(i))
return NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
- if (ni_660x_gate_select ==
- NI_660x_Gate_Pin_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
+ if (gate == NI_660X_PIN_GATE_SEL(i))
return NI_GPCT_GATE_PIN_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_gate_pin)
- break;
BUG();
break;
}
return 0;
};
-static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
- ni_m_series_gate_select)
+static unsigned ni_m_gate_to_generic_gate(unsigned gate)
{
unsigned i;
- switch (ni_m_series_gate_select) {
- case NI_M_Series_Timestamp_Mux_Gate_Select:
+ switch (gate) {
+ case NI_M_TIMESTAMP_MUX_GATE_SEL:
return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
- break;
- case NI_M_Series_AI_START2_Gate_Select:
+ case NI_M_AI_START2_GATE_SEL:
return NI_GPCT_AI_START2_GATE_SELECT;
- break;
- case NI_M_Series_PXI_Star_Trigger_Gate_Select:
+ case NI_M_PXI_STAR_TRIGGER_GATE_SEL:
return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
- break;
- case NI_M_Series_Next_Out_Gate_Select:
+ case NI_M_NEXT_OUT_GATE_SEL:
return NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_M_Series_AI_START1_Gate_Select:
+ case NI_M_AI_START1_GATE_SEL:
return NI_GPCT_AI_START1_GATE_SELECT;
- break;
- case NI_M_Series_Next_SRC_Gate_Select:
+ case NI_M_NEXT_SRC_GATE_SEL:
return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_M_Series_Analog_Trigger_Out_Gate_Select:
+ case NI_M_ANALOG_TRIG_OUT_GATE_SEL:
return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
- break;
- case NI_M_Series_Logic_Low_Gate_Select:
+ case NI_M_LOGIC_LOW_GATE_SEL:
return NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
default:
- for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
- if (ni_m_series_gate_select ==
- NI_M_Series_RTSI_Gate_Select(i)) {
+ for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
+ if (gate == NI_M_RTSI_GATE_SEL(i))
return NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_m_series_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
- if (ni_m_series_gate_select ==
- NI_M_Series_PFI_Gate_Select(i)) {
+ for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
+ if (gate == NI_M_PFI_GATE_SEL(i))
return NI_GPCT_PFI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_m_series_max_pfi_channel)
- break;
BUG();
break;
}
return 0;
};
-static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
- ni_660x_gate_select)
+static unsigned ni_660x_gate2_to_generic_gate(unsigned gate)
{
unsigned i;
- switch (ni_660x_gate_select) {
- case NI_660x_Source_Pin_i_Second_Gate_Select:
+ switch (gate) {
+ case NI_660X_SRC_PIN_I_GATE2_SEL:
return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Up_Down_Pin_i_Second_Gate_Select:
+ case NI_660X_UD_PIN_I_GATE2_SEL:
return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
- break;
- case NI_660x_Next_SRC_Second_Gate_Select:
+ case NI_660X_NEXT_SRC_GATE2_SEL:
return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
- break;
- case NI_660x_Next_Out_Second_Gate_Select:
+ case NI_660X_NEXT_OUT_GATE2_SEL:
return NI_GPCT_NEXT_OUT_GATE_SELECT;
- break;
- case NI_660x_Selected_Gate_Second_Gate_Select:
+ case NI_660X_SELECTED_GATE2_SEL:
return NI_GPCT_SELECTED_GATE_GATE_SELECT;
- break;
- case NI_660x_Logic_Low_Second_Gate_Select:
+ case NI_660X_LOGIC_LOW_GATE2_SEL:
return NI_GPCT_LOGIC_LOW_GATE_SELECT;
- break;
default:
- for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
- if (ni_660x_gate_select ==
- NI_660x_RTSI_Second_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
+ if (gate == NI_660X_RTSI_GATE2_SEL(i))
return NI_GPCT_RTSI_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_rtsi_channel)
- break;
- for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
- if (ni_660x_gate_select ==
- NI_660x_Up_Down_Pin_Second_Gate_Select(i)) {
+ for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
+ if (gate == NI_660X_UD_PIN_GATE2_SEL(i))
return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
- break;
- }
}
- if (i <= ni_660x_max_up_down_pin)
- break;
BUG();
break;
}
return 0;
};
-static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
- ni_m_series_gate_select)
+static unsigned ni_m_gate2_to_generic_gate(unsigned gate)
{
- /*FIXME: the second gate sources for the m series are undocumented, so we just return
- * the raw bits for now. */
- switch (ni_m_series_gate_select) {
+ /*
+ * FIXME: the second gate sources for the m series are undocumented,
+ * so we just return the raw bits for now.
+ */
+ switch (gate) {
default:
- return ni_m_series_gate_select;
- break;
+ return gate;
}
return 0;
};
@@ -1451,84 +1108,62 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- const unsigned mode_bits =
- ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
- const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
- unsigned gate_select_bits;
+ unsigned mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
+ unsigned gate2_reg = NITIO_GATE2_REG(cidx);
+ unsigned gate;
switch (gate_index) {
case 0:
- if ((mode_bits & Gi_Gating_Mode_Mask) ==
- Gi_Gating_Disabled_Bits) {
+ if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) {
*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
return 0;
- } else {
- gate_select_bits =
- (ni_tio_get_soft_copy(counter,
- NITIO_INPUT_SEL_REG(cidx)) &
- Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift;
}
+
+ gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter,
+ NITIO_INPUT_SEL_REG(cidx)));
+
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- *gate_source =
- ni_m_series_first_gate_to_generic_gate_source
- (gate_select_bits);
+ default:
+ *gate_source = ni_m_gate_to_generic_gate(gate);
break;
case ni_gpct_variant_660x:
- *gate_source =
- ni_660x_first_gate_to_generic_gate_source
- (gate_select_bits);
- break;
- default:
- BUG();
+ *gate_source = ni_660x_gate_to_generic_gate(gate);
break;
}
- if (mode_bits & Gi_Gate_Polarity_Bit)
+ if (mode & GI_GATE_POL_INVERT)
*gate_source |= CR_INVERT;
- if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits)
+ if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
*gate_source |= CR_EDGE;
break;
case 1:
- if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits
- || (counter_dev->regs[second_gate_reg] &
- Gi_Second_Gate_Mode_Bit)
- == 0) {
+ if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED ||
+ !(counter_dev->regs[gate2_reg] & GI_GATE2_MODE)) {
*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
return 0;
- } else {
- gate_select_bits =
- (counter_dev->regs[second_gate_reg] &
- Gi_Second_Gate_Select_Mask) >>
- Gi_Second_Gate_Select_Shift;
}
+
+ gate = GI_BITS_TO_GATE2(counter_dev->regs[gate2_reg]);
+
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
case ni_gpct_variant_m_series:
- *gate_source =
- ni_m_series_second_gate_to_generic_gate_source
- (gate_select_bits);
+ default:
+ *gate_source = ni_m_gate2_to_generic_gate(gate);
break;
case ni_gpct_variant_660x:
- *gate_source =
- ni_660x_second_gate_to_generic_gate_source
- (gate_select_bits);
- break;
- default:
- BUG();
+ *gate_source = ni_660x_gate2_to_generic_gate(gate);
break;
}
- if (counter_dev->regs[second_gate_reg] &
- Gi_Second_Gate_Polarity_Bit) {
+ if (counter_dev->regs[gate2_reg] & GI_GATE2_POL_INVERT)
*gate_source |= CR_INVERT;
- }
/* second gate can't have edge/level mode set independently */
- if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits)
+ if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
*gate_source |= CR_EDGE;
break;
default:
return -EINVAL;
- break;
}
return 0;
}
@@ -1539,43 +1174,41 @@ int ni_tio_insn_config(struct comedi_device *dev,
unsigned int *data)
{
struct ni_gpct *counter = s->private;
+ unsigned cidx = counter->counter_index;
+ unsigned status;
switch (data[0]) {
case INSN_CONFIG_SET_COUNTER_MODE:
return ni_tio_set_counter_mode(counter, data[1]);
- break;
case INSN_CONFIG_ARM:
return ni_tio_arm(counter, 1, data[1]);
- break;
case INSN_CONFIG_DISARM:
ni_tio_arm(counter, 0, 0);
return 0;
- break;
case INSN_CONFIG_GET_COUNTER_STATUS:
- data[1] = ni_tio_counter_status(counter);
- data[2] = counter_status_mask;
+ data[1] = 0;
+ status = read_register(counter, NITIO_SHARED_STATUS_REG(cidx));
+ if (status & GI_ARMED(cidx)) {
+ data[1] |= COMEDI_COUNTER_ARMED;
+ if (status & GI_COUNTING(cidx))
+ data[1] |= COMEDI_COUNTER_COUNTING;
+ }
+ data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
return 0;
- break;
case INSN_CONFIG_SET_CLOCK_SRC:
return ni_tio_set_clock_src(counter, data[1], data[2]);
- break;
case INSN_CONFIG_GET_CLOCK_SRC:
ni_tio_get_clock_src(counter, &data[1], &data[2]);
return 0;
- break;
case INSN_CONFIG_SET_GATE_SRC:
return ni_tio_set_gate_src(counter, data[1], data[2]);
- break;
case INSN_CONFIG_GET_GATE_SRC:
return ni_tio_get_gate_src(counter, data[1], &data[2]);
- break;
case INSN_CONFIG_SET_OTHER_SRC:
return ni_tio_set_other_src(counter, data[1], data[2]);
- break;
case INSN_CONFIG_RESET:
ni_tio_reset_count_and_disarm(counter);
return 0;
- break;
default:
break;
}
@@ -1583,6 +1216,33 @@ int ni_tio_insn_config(struct comedi_device *dev,
}
EXPORT_SYMBOL_GPL(ni_tio_insn_config);
+static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ struct ni_gpct *counter = s->private;
+ unsigned cidx = counter->counter_index;
+ unsigned int val;
+
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
+ GI_SAVE_TRACE, GI_SAVE_TRACE);
+
+ /*
+ * The count doesn't get latched until the next clock edge, so it is
+ * possible the count may change (once) while we are reading. Since
+ * the read of the SW_Save_Reg isn't atomic (apparently even when it's
+ * a 32 bit register according to 660x docs), we need to read twice
+ * and make sure the reading hasn't changed. If it has, a third read
+ * will be correct since the count value will definitely have latched
+ * by then.
+ */
+ val = read_register(counter, NITIO_SW_SAVE_REG(cidx));
+ if (val != read_register(counter, NITIO_SW_SAVE_REG(cidx)))
+ val = read_register(counter, NITIO_SW_SAVE_REG(cidx));
+
+ return val;
+}
+
int ni_tio_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
@@ -1590,43 +1250,24 @@ int ni_tio_insn_read(struct comedi_device *dev,
{
struct ni_gpct *counter = s->private;
struct ni_gpct_device *counter_dev = counter->counter_dev;
- const unsigned channel = CR_CHAN(insn->chanspec);
+ unsigned int channel = CR_CHAN(insn->chanspec);
unsigned cidx = counter->counter_index;
- unsigned first_read;
- unsigned second_read;
- unsigned correct_read;
+ int i;
- if (insn->n < 1)
- return 0;
- switch (channel) {
- case 0:
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- Gi_Save_Trace_Bit, 0);
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
- Gi_Save_Trace_Bit, Gi_Save_Trace_Bit);
- /* The count doesn't get latched until the next clock edge, so it is possible the count
- may change (once) while we are reading. Since the read of the SW_Save_Reg isn't
- atomic (apparently even when it's a 32 bit register according to 660x docs),
- we need to read twice and make sure the reading hasn't changed. If it has,
- a third read will be correct since the count value will definitely have latched by then. */
- first_read = read_register(counter, NITIO_SW_SAVE_REG(cidx));
- second_read = read_register(counter, NITIO_SW_SAVE_REG(cidx));
- if (first_read != second_read)
- correct_read =
- read_register(counter, NITIO_SW_SAVE_REG(cidx));
- else
- correct_read = first_read;
- data[0] = correct_read;
- return 0;
- break;
- case 1:
- data[0] = counter_dev->regs[NITIO_LOADA_REG(cidx)];
- break;
- case 2:
- data[0] = counter_dev->regs[NITIO_LOADB_REG(cidx)];
- break;
+ for (i = 0; i < insn->n; i++) {
+ switch (channel) {
+ case 0:
+ data[i] = ni_tio_read_sw_save_reg(dev, s);
+ break;
+ case 1:
+ data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)];
+ break;
+ case 2:
+ data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)];
+ break;
+ }
}
- return 0;
+ return insn->n;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_read);
@@ -1636,10 +1277,9 @@ static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
const unsigned bits =
read_register(counter, NITIO_SHARED_STATUS_REG(cidx));
- if (bits & Gi_Next_Load_Source_Bit(cidx))
- return NITIO_LOADB_REG(cidx);
- else
- return NITIO_LOADA_REG(cidx);
+ return (bits & GI_NEXT_LOAD_SRC(cidx))
+ ? NITIO_LOADB_REG(cidx)
+ : NITIO_LOADA_REG(cidx);
}
int ni_tio_insn_write(struct comedi_device *dev,
@@ -1657,13 +1297,20 @@ int ni_tio_insn_write(struct comedi_device *dev,
return 0;
switch (channel) {
case 0:
- /* Unsafe if counter is armed. Should probably check status and return -EBUSY if armed. */
- /* Don't disturb load source select, just use whichever load register is already selected. */
+ /*
+ * Unsafe if counter is armed.
+ * Should probably check status and return -EBUSY if armed.
+ */
+
+ /*
+ * Don't disturb load source select, just use whichever
+ * load register is already selected.
+ */
load_reg = ni_tio_next_load_register(counter);
write_register(counter, data[0], load_reg);
ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
- 0, 0, Gi_Load_Bit);
- /* restore state of load reg to whatever the user set last set it to */
+ 0, 0, GI_LOAD);
+ /* restore load reg */
write_register(counter, counter_dev->regs[load_reg], load_reg);
break;
case 1:
@@ -1676,12 +1323,104 @@ int ni_tio_insn_write(struct comedi_device *dev,
break;
default:
return -EINVAL;
- break;
}
return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_insn_write);
+void ni_tio_init_counter(struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned cidx = counter->counter_index;
+
+ ni_tio_reset_count_and_disarm(counter);
+
+ /* initialize counter registers */
+ counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_AUTO_INC_REG(cidx));
+
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
+ ~0, GI_SYNC_GATE);
+
+ ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);
+
+ counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_LOADA_REG(cidx));
+
+ counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_LOADB_REG(cidx));
+
+ ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);
+
+ if (ni_tio_counting_mode_registers_present(counter_dev))
+ ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);
+
+ if (ni_tio_has_gate2_registers(counter_dev)) {
+ counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0;
+ write_register(counter, 0x0, NITIO_GATE2_REG(cidx));
+ }
+
+ ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);
+
+ ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
+}
+EXPORT_SYMBOL_GPL(ni_tio_init_counter);
+
+struct ni_gpct_device *
+ni_gpct_device_construct(struct comedi_device *dev,
+ void (*write_register)(struct ni_gpct *counter,
+ unsigned bits,
+ enum ni_gpct_register reg),
+ unsigned (*read_register)(struct ni_gpct *counter,
+ enum ni_gpct_register reg),
+ enum ni_gpct_variant variant,
+ unsigned num_counters)
+{
+ struct ni_gpct_device *counter_dev;
+ struct ni_gpct *counter;
+ unsigned i;
+
+ if (num_counters == 0)
+ return NULL;
+
+ counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL);
+ if (!counter_dev)
+ return NULL;
+
+ counter_dev->dev = dev;
+ counter_dev->write_register = write_register;
+ counter_dev->read_register = read_register;
+ counter_dev->variant = variant;
+
+ spin_lock_init(&counter_dev->regs_lock);
+
+ counter_dev->counters = kcalloc(num_counters, sizeof(*counter),
+ GFP_KERNEL);
+ if (!counter_dev->counters) {
+ kfree(counter_dev);
+ return NULL;
+ }
+
+ for (i = 0; i < num_counters; ++i) {
+ counter = &counter_dev->counters[i];
+ counter->counter_dev = counter_dev;
+ spin_lock_init(&counter->lock);
+ }
+ counter_dev->num_counters = num_counters;
+
+ return counter_dev;
+}
+EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
+
+void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
+{
+ if (!counter_dev->counters)
+ return;
+ kfree(counter_dev->counters);
+ kfree(counter_dev);
+}
+EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
+
static int __init ni_tio_init_module(void)
{
return 0;
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
index 1056bf001e5e..25aedd0e5867 100644
--- a/drivers/staging/comedi/drivers/ni_tio.h
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -149,8 +149,6 @@ int ni_tio_cmdtest(struct comedi_device *, struct comedi_subdevice *,
int ni_tio_cancel(struct ni_gpct *);
void ni_tio_handle_interrupt(struct ni_gpct *, struct comedi_subdevice *);
void ni_tio_set_mite_channel(struct ni_gpct *, struct mite_channel *);
-void ni_tio_acknowledge_and_confirm(struct ni_gpct *,
- int *gate_error, int *tc_error,
- int *perm_stale_data, int *stale_data);
+void ni_tio_acknowledge(struct ni_gpct *);
#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
index 15b81b8fc5c4..2bceae493e23 100644
--- a/drivers/staging/comedi/drivers/ni_tio_internal.h
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -22,296 +22,139 @@
#include "ni_tio.h"
#define NITIO_AUTO_INC_REG(x) (NITIO_G0_AUTO_INC + (x))
+#define GI_AUTO_INC_MASK 0xff
#define NITIO_CMD_REG(x) (NITIO_G0_CMD + (x))
+#define GI_ARM (1 << 0)
+#define GI_SAVE_TRACE (1 << 1)
+#define GI_LOAD (1 << 2)
+#define GI_DISARM (1 << 4)
+#define GI_CNT_DIR(x) (((x) & 0x3) << 5)
+#define GI_CNT_DIR_MASK (3 << 5)
+#define GI_WRITE_SWITCH (1 << 7)
+#define GI_SYNC_GATE (1 << 8)
+#define GI_LITTLE_BIG_ENDIAN (1 << 9)
+#define GI_BANK_SWITCH_START (1 << 10)
+#define GI_BANK_SWITCH_MODE (1 << 11)
+#define GI_BANK_SWITCH_ENABLE (1 << 12)
+#define GI_ARM_COPY (1 << 13)
+#define GI_SAVE_TRACE_COPY (1 << 14)
+#define GI_DISARM_COPY (1 << 15)
#define NITIO_HW_SAVE_REG(x) (NITIO_G0_HW_SAVE + (x))
#define NITIO_SW_SAVE_REG(x) (NITIO_G0_SW_SAVE + (x))
#define NITIO_MODE_REG(x) (NITIO_G0_MODE + (x))
+#define GI_GATING_DISABLED (0 << 0)
+#define GI_LEVEL_GATING (1 << 0)
+#define GI_RISING_EDGE_GATING (2 << 0)
+#define GI_FALLING_EDGE_GATING (3 << 0)
+#define GI_GATING_MODE_MASK (3 << 0)
+#define GI_GATE_ON_BOTH_EDGES (1 << 2)
+#define GI_EDGE_GATE_STARTS_STOPS (0 << 3)
+#define GI_EDGE_GATE_STOPS_STARTS (1 << 3)
+#define GI_EDGE_GATE_STARTS (2 << 3)
+#define GI_EDGE_GATE_NO_STARTS_OR_STOPS (3 << 3)
+#define GI_EDGE_GATE_MODE_MASK (3 << 3)
+#define GI_STOP_ON_GATE (0 << 5)
+#define GI_STOP_ON_GATE_OR_TC (1 << 5)
+#define GI_STOP_ON_GATE_OR_SECOND_TC (2 << 5)
+#define GI_STOP_MODE_MASK (3 << 5)
+#define GI_LOAD_SRC_SEL (1 << 7)
+#define GI_OUTPUT_TC_PULSE (1 << 8)
+#define GI_OUTPUT_TC_TOGGLE (2 << 8)
+#define GI_OUTPUT_TC_OR_GATE_TOGGLE (3 << 8)
+#define GI_OUTPUT_MODE_MASK (3 << 8)
+#define GI_NO_HARDWARE_DISARM (0 << 10)
+#define GI_DISARM_AT_TC (1 << 10)
+#define GI_DISARM_AT_GATE (2 << 10)
+#define GI_DISARM_AT_TC_OR_GATE (3 << 10)
+#define GI_COUNTING_ONCE_MASK (3 << 10)
+#define GI_LOADING_ON_TC (1 << 12)
+#define GI_GATE_POL_INVERT (1 << 13)
+#define GI_LOADING_ON_GATE (1 << 14)
+#define GI_RELOAD_SRC_SWITCHING (1 << 15)
#define NITIO_LOADA_REG(x) (NITIO_G0_LOADA + (x))
#define NITIO_LOADB_REG(x) (NITIO_G0_LOADB + (x))
#define NITIO_INPUT_SEL_REG(x) (NITIO_G0_INPUT_SEL + (x))
+#define GI_READ_ACKS_IRQ (1 << 0)
+#define GI_WRITE_ACKS_IRQ (1 << 1)
+#define GI_BITS_TO_SRC(x) (((x) >> 2) & 0x1f)
+#define GI_SRC_SEL(x) (((x) & 0x1f) << 2)
+#define GI_SRC_SEL_MASK (0x1f << 2)
+#define GI_BITS_TO_GATE(x) (((x) >> 7) & 0x1f)
+#define GI_GATE_SEL(x) (((x) & 0x1f) << 7)
+#define GI_GATE_SEL_MASK (0x1f << 7)
+#define GI_GATE_SEL_LOAD_SRC (1 << 12)
+#define GI_OR_GATE (1 << 13)
+#define GI_OUTPUT_POL_INVERT (1 << 14)
+#define GI_SRC_POL_INVERT (1 << 15)
#define NITIO_CNT_MODE_REG(x) (NITIO_G0_CNT_MODE + (x))
+#define GI_CNT_MODE(x) (((x) & 0x7) << 0)
+#define GI_CNT_MODE_NORMAL GI_CNT_MODE(0)
+#define GI_CNT_MODE_QUADX1 GI_CNT_MODE(1)
+#define GI_CNT_MODE_QUADX2 GI_CNT_MODE(2)
+#define GI_CNT_MODE_QUADX4 GI_CNT_MODE(3)
+#define GI_CNT_MODE_TWO_PULSE GI_CNT_MODE(4)
+#define GI_CNT_MODE_SYNC_SRC GI_CNT_MODE(6)
+#define GI_CNT_MODE_MASK (7 << 0)
+#define GI_INDEX_MODE (1 << 4)
+#define GI_INDEX_PHASE(x) (((x) & 0x3) << 5)
+#define GI_INDEX_PHASE_MASK (3 << 5)
+#define GI_HW_ARM_ENA (1 << 7)
+#define GI_HW_ARM_SEL(x) ((x) << 8)
+#define GI_660X_HW_ARM_SEL_MASK (0x7 << 8)
+#define GI_M_HW_ARM_SEL_MASK (0x1f << 8)
+#define GI_660X_PRESCALE_X8 (1 << 12)
+#define GI_M_PRESCALE_X8 (1 << 13)
+#define GI_660X_ALT_SYNC (1 << 13)
+#define GI_M_ALT_SYNC (1 << 14)
+#define GI_660X_PRESCALE_X2 (1 << 14)
+#define GI_M_PRESCALE_X2 (1 << 15)
#define NITIO_GATE2_REG(x) (NITIO_G0_GATE2 + (x))
+#define GI_GATE2_MODE (1 << 0)
+#define GI_BITS_TO_GATE2(x) (((x) >> 7) & 0x1f)
+#define GI_GATE2_SEL(x) (((x) & 0x1f) << 7)
+#define GI_GATE2_SEL_MASK (0x1f << 7)
+#define GI_GATE2_POL_INVERT (1 << 13)
+#define GI_GATE2_SUBSEL (1 << 14)
+#define GI_SRC_SUBSEL (1 << 15)
#define NITIO_SHARED_STATUS_REG(x) (NITIO_G01_STATUS + ((x) / 2))
+#define GI_SAVE(x) (((x) % 2) ? (1 << 1) : (1 << 0))
+#define GI_COUNTING(x) (((x) % 2) ? (1 << 3) : (1 << 2))
+#define GI_NEXT_LOAD_SRC(x) (((x) % 2) ? (1 << 5) : (1 << 4))
+#define GI_STALE_DATA(x) (((x) % 2) ? (1 << 7) : (1 << 6))
+#define GI_ARMED(x) (((x) % 2) ? (1 << 9) : (1 << 8))
+#define GI_NO_LOAD_BETWEEN_GATES(x) (((x) % 2) ? (1 << 11) : (1 << 10))
+#define GI_TC_ERROR(x) (((x) % 2) ? (1 << 13) : (1 << 12))
+#define GI_GATE_ERROR(x) (((x) % 2) ? (1 << 15) : (1 << 14))
#define NITIO_RESET_REG(x) (NITIO_G01_RESET + ((x) / 2))
+#define GI_RESET(x) (1 << (2 + ((x) % 2)))
#define NITIO_STATUS1_REG(x) (NITIO_G01_STATUS1 + ((x) / 2))
#define NITIO_STATUS2_REG(x) (NITIO_G01_STATUS2 + ((x) / 2))
+#define GI_OUTPUT(x) (((x) % 2) ? (1 << 1) : (1 << 0))
+#define GI_HW_SAVE(x) (((x) % 2) ? (1 << 13) : (1 << 12))
+#define GI_PERMANENT_STALE(x) (((x) % 2) ? (1 << 15) : (1 << 14))
#define NITIO_DMA_CFG_REG(x) (NITIO_G0_DMA_CFG + (x))
+#define GI_DMA_ENABLE (1 << 0)
+#define GI_DMA_WRITE (1 << 1)
+#define GI_DMA_INT_ENA (1 << 2)
+#define GI_DMA_RESET (1 << 3)
+#define GI_DMA_BANKSW_ERROR (1 << 4)
#define NITIO_DMA_STATUS_REG(x) (NITIO_G0_DMA_STATUS + (x))
+#define GI_DMA_READBANK (1 << 13)
+#define GI_DRQ_ERROR (1 << 14)
+#define GI_DRQ_STATUS (1 << 15)
#define NITIO_ABZ_REG(x) (NITIO_G0_ABZ + (x))
#define NITIO_INT_ACK_REG(x) (NITIO_G0_INT_ACK + (x))
+#define GI_GATE_ERROR_CONFIRM(x) (((x) % 2) ? (1 << 1) : (1 << 5))
+#define GI_TC_ERROR_CONFIRM(x) (((x) % 2) ? (1 << 2) : (1 << 6))
+#define GI_TC_INTERRUPT_ACK (1 << 14)
+#define GI_GATE_INTERRUPT_ACK (1 << 15)
#define NITIO_STATUS_REG(x) (NITIO_G0_STATUS + (x))
+#define GI_GATE_INTERRUPT (1 << 2)
+#define GI_TC (1 << 3)
+#define GI_INTERRUPT (1 << 15)
#define NITIO_INT_ENA_REG(x) (NITIO_G0_INT_ENA + (x))
-
-enum Gi_Auto_Increment_Reg_Bits {
- Gi_Auto_Increment_Mask = 0xff
-};
-
-#define Gi_Up_Down_Shift 5
-enum Gi_Command_Reg_Bits {
- Gi_Arm_Bit = 0x1,
- Gi_Save_Trace_Bit = 0x2,
- Gi_Load_Bit = 0x4,
- Gi_Disarm_Bit = 0x10,
- Gi_Up_Down_Mask = 0x3 << Gi_Up_Down_Shift,
- Gi_Always_Down_Bits = 0x0 << Gi_Up_Down_Shift,
- Gi_Always_Up_Bits = 0x1 << Gi_Up_Down_Shift,
- Gi_Up_Down_Hardware_IO_Bits = 0x2 << Gi_Up_Down_Shift,
- Gi_Up_Down_Hardware_Gate_Bits = 0x3 << Gi_Up_Down_Shift,
- Gi_Write_Switch_Bit = 0x80,
- Gi_Synchronize_Gate_Bit = 0x100,
- Gi_Little_Big_Endian_Bit = 0x200,
- Gi_Bank_Switch_Start_Bit = 0x400,
- Gi_Bank_Switch_Mode_Bit = 0x800,
- Gi_Bank_Switch_Enable_Bit = 0x1000,
- Gi_Arm_Copy_Bit = 0x2000,
- Gi_Save_Trace_Copy_Bit = 0x4000,
- Gi_Disarm_Copy_Bit = 0x8000
-};
-
-#define Gi_Index_Phase_Bitshift 5
-#define Gi_HW_Arm_Select_Shift 8
-enum Gi_Counting_Mode_Reg_Bits {
- Gi_Counting_Mode_Mask = 0x7,
- Gi_Counting_Mode_Normal_Bits = 0x0,
- Gi_Counting_Mode_QuadratureX1_Bits = 0x1,
- Gi_Counting_Mode_QuadratureX2_Bits = 0x2,
- Gi_Counting_Mode_QuadratureX4_Bits = 0x3,
- Gi_Counting_Mode_Two_Pulse_Bits = 0x4,
- Gi_Counting_Mode_Sync_Source_Bits = 0x6,
- Gi_Index_Mode_Bit = 0x10,
- Gi_Index_Phase_Mask = 0x3 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_LowA_LowB = 0x0 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift,
- Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift,
- /* from m-series example code, not documented in 660x register level
- * manual */
- Gi_HW_Arm_Enable_Bit = 0x80,
- /* from m-series example code, not documented in 660x register level
- * manual */
- Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift,
- Gi_660x_Prescale_X8_Bit = 0x1000,
- Gi_M_Series_Prescale_X8_Bit = 0x2000,
- Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift,
- /* must be set for clocks over 40MHz, which includes synchronous
- * counting and quadrature modes */
- Gi_660x_Alternate_Sync_Bit = 0x2000,
- Gi_M_Series_Alternate_Sync_Bit = 0x4000,
- /* from m-series example code, not documented in 660x register level
- * manual */
- Gi_660x_Prescale_X2_Bit = 0x4000,
- Gi_M_Series_Prescale_X2_Bit = 0x8000,
-};
-
-#define Gi_Source_Select_Shift 2
-#define Gi_Gate_Select_Shift 7
-enum Gi_Input_Select_Bits {
- Gi_Read_Acknowledges_Irq = 0x1, /* not present on 660x */
- Gi_Write_Acknowledges_Irq = 0x2, /* not present on 660x */
- Gi_Source_Select_Mask = 0x7c,
- Gi_Gate_Select_Mask = 0x1f << Gi_Gate_Select_Shift,
- Gi_Gate_Select_Load_Source_Bit = 0x1000,
- Gi_Or_Gate_Bit = 0x2000,
- Gi_Output_Polarity_Bit = 0x4000, /* set to invert */
- Gi_Source_Polarity_Bit = 0x8000 /* set to invert */
-};
-
-enum Gi_Mode_Bits {
- Gi_Gating_Mode_Mask = 0x3,
- Gi_Gating_Disabled_Bits = 0x0,
- Gi_Level_Gating_Bits = 0x1,
- Gi_Rising_Edge_Gating_Bits = 0x2,
- Gi_Falling_Edge_Gating_Bits = 0x3,
- Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with
- * rising edge gating mode */
- Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18,
- Gi_Edge_Gate_Starts_Stops_Bits = 0x0,
- Gi_Edge_Gate_Stops_Starts_Bits = 0x8,
- Gi_Edge_Gate_Starts_Bits = 0x10,
- Gi_Edge_Gate_No_Starts_or_Stops_Bits = 0x18,
- Gi_Stop_Mode_Mask = 0x60,
- Gi_Stop_on_Gate_Bits = 0x00,
- Gi_Stop_on_Gate_or_TC_Bits = 0x20,
- Gi_Stop_on_Gate_or_Second_TC_Bits = 0x40,
- Gi_Load_Source_Select_Bit = 0x80,
- Gi_Output_Mode_Mask = 0x300,
- Gi_Output_TC_Pulse_Bits = 0x100,
- Gi_Output_TC_Toggle_Bits = 0x200,
- Gi_Output_TC_or_Gate_Toggle_Bits = 0x300,
- Gi_Counting_Once_Mask = 0xc00,
- Gi_No_Hardware_Disarm_Bits = 0x000,
- Gi_Disarm_at_TC_Bits = 0x400,
- Gi_Disarm_at_Gate_Bits = 0x800,
- Gi_Disarm_at_TC_or_Gate_Bits = 0xc00,
- Gi_Loading_On_TC_Bit = 0x1000,
- Gi_Gate_Polarity_Bit = 0x2000,
- Gi_Loading_On_Gate_Bit = 0x4000,
- Gi_Reload_Source_Switching_Bit = 0x8000
-};
-
-#define Gi_Second_Gate_Select_Shift 7
-/*FIXME: m-series has a second gate subselect bit */
-/*FIXME: m-series second gate sources are undocumented (by NI)*/
-enum Gi_Second_Gate_Bits {
- Gi_Second_Gate_Mode_Bit = 0x1,
- Gi_Second_Gate_Select_Mask = 0x1f << Gi_Second_Gate_Select_Shift,
- Gi_Second_Gate_Polarity_Bit = 0x2000,
- Gi_Second_Gate_Subselect_Bit = 0x4000, /* m-series only */
- Gi_Source_Subselect_Bit = 0x8000 /* m-series only */
-};
-static inline unsigned Gi_Second_Gate_Select_Bits(unsigned second_gate_select)
-{
- return (second_gate_select << Gi_Second_Gate_Select_Shift) &
- Gi_Second_Gate_Select_Mask;
-}
-
-enum Gxx_Status_Bits {
- G0_Save_Bit = 0x1,
- G1_Save_Bit = 0x2,
- G0_Counting_Bit = 0x4,
- G1_Counting_Bit = 0x8,
- G0_Next_Load_Source_Bit = 0x10,
- G1_Next_Load_Source_Bit = 0x20,
- G0_Stale_Data_Bit = 0x40,
- G1_Stale_Data_Bit = 0x80,
- G0_Armed_Bit = 0x100,
- G1_Armed_Bit = 0x200,
- G0_No_Load_Between_Gates_Bit = 0x400,
- G1_No_Load_Between_Gates_Bit = 0x800,
- G0_TC_Error_Bit = 0x1000,
- G1_TC_Error_Bit = 0x2000,
- G0_Gate_Error_Bit = 0x4000,
- G1_Gate_Error_Bit = 0x8000
-};
-static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Counting_Bit;
- return G0_Counting_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Armed_Bit;
- return G0_Armed_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned
- counter_index)
-{
- if (counter_index % 2)
- return G1_Next_Load_Source_Bit;
- return G0_Next_Load_Source_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Stale_Data_Bit;
- return G0_Stale_Data_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_TC_Error_Bit;
- return G0_TC_Error_Bit;
-}
-
-static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Gate_Error_Bit;
- return G0_Gate_Error_Bit;
-}
-
-/* joint reset register bits */
-static inline unsigned Gi_Reset_Bit(unsigned counter_index)
-{
- return 0x1 << (2 + (counter_index % 2));
-}
-
-enum Gxx_Joint_Status2_Bits {
- G0_Output_Bit = 0x1,
- G1_Output_Bit = 0x2,
- G0_HW_Save_Bit = 0x1000,
- G1_HW_Save_Bit = 0x2000,
- G0_Permanent_Stale_Bit = 0x4000,
- G1_Permanent_Stale_Bit = 0x8000
-};
-static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned
- counter_index)
-{
- if (counter_index % 2)
- return G1_Permanent_Stale_Bit;
- return G0_Permanent_Stale_Bit;
-}
-
-enum Gi_DMA_Config_Reg_Bits {
- Gi_DMA_Enable_Bit = 0x1,
- Gi_DMA_Write_Bit = 0x2,
- Gi_DMA_Int_Bit = 0x4
-};
-
-enum Gi_DMA_Status_Reg_Bits {
- Gi_DMA_Readbank_Bit = 0x2000,
- Gi_DRQ_Error_Bit = 0x4000,
- Gi_DRQ_Status_Bit = 0x8000
-};
-
-enum G02_Interrupt_Acknowledge_Bits {
- G0_Gate_Error_Confirm_Bit = 0x20,
- G0_TC_Error_Confirm_Bit = 0x40
-};
-enum G13_Interrupt_Acknowledge_Bits {
- G1_Gate_Error_Confirm_Bit = 0x2,
- G1_TC_Error_Confirm_Bit = 0x4
-};
-static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_Gate_Error_Confirm_Bit;
- return G0_Gate_Error_Confirm_Bit;
-}
-
-static inline unsigned Gi_TC_Error_Confirm_Bit(unsigned counter_index)
-{
- if (counter_index % 2)
- return G1_TC_Error_Confirm_Bit;
- return G0_TC_Error_Confirm_Bit;
-}
-
-/* bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers */
-enum Gxx_Interrupt_Acknowledge_Bits {
- Gi_TC_Interrupt_Ack_Bit = 0x4000,
- Gi_Gate_Interrupt_Ack_Bit = 0x8000
-};
-
-enum Gi_Status_Bits {
- Gi_Gate_Interrupt_Bit = 0x4,
- Gi_TC_Bit = 0x8,
- Gi_Interrupt_Bit = 0x8000
-};
-
-enum G02_Interrupt_Enable_Bits {
- G0_TC_Interrupt_Enable_Bit = 0x40,
- G0_Gate_Interrupt_Enable_Bit = 0x100
-};
-enum G13_Interrupt_Enable_Bits {
- G1_TC_Interrupt_Enable_Bit = 0x200,
- G1_Gate_Interrupt_Enable_Bit = 0x400
-};
-static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index)
-{
- unsigned bit;
-
- if (counter_index % 2)
- bit = G1_Gate_Interrupt_Enable_Bit;
- else
- bit = G0_Gate_Interrupt_Enable_Bit;
- return bit;
-}
+#define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? (1 << 9) : (1 << 6))
+#define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? (1 << 10) : (1 << 8))
static inline void write_register(struct ni_gpct *counter, unsigned bits,
enum ni_gpct_register reg)
@@ -334,11 +177,9 @@ static inline int ni_tio_counting_mode_registers_present(const struct
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
return 0;
- break;
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
return 1;
- break;
default:
BUG();
break;
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
index 2557ab48cb6c..299ceddfb233 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -49,40 +49,38 @@ TODO:
#include "ni_tio_internal.h"
#include "mite.h"
-static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
- short read_not_write)
+static void ni_tio_configure_dma(struct ni_gpct *counter,
+ bool enable, bool read)
{
struct ni_gpct_device *counter_dev = counter->counter_dev;
unsigned cidx = counter->counter_index;
- unsigned input_select_bits = 0;
+ unsigned mask;
+ unsigned bits;
+
+ mask = GI_READ_ACKS_IRQ | GI_WRITE_ACKS_IRQ;
+ bits = 0;
if (enable) {
- if (read_not_write)
- input_select_bits |= Gi_Read_Acknowledges_Irq;
+ if (read)
+ bits |= GI_READ_ACKS_IRQ;
else
- input_select_bits |= Gi_Write_Acknowledges_Irq;
+ bits |= GI_WRITE_ACKS_IRQ;
}
- ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
- Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
- input_select_bits);
+ ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), mask, bits);
+
switch (counter_dev->variant) {
case ni_gpct_variant_e_series:
break;
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
- {
- unsigned gi_dma_config_bits = 0;
-
- if (enable) {
- gi_dma_config_bits |= Gi_DMA_Enable_Bit;
- gi_dma_config_bits |= Gi_DMA_Int_Bit;
- }
- if (read_not_write == 0)
- gi_dma_config_bits |= Gi_DMA_Write_Bit;
- ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx),
- Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit |
- Gi_DMA_Write_Bit, gi_dma_config_bits);
- }
+ mask = GI_DMA_ENABLE | GI_DMA_INT_ENA | GI_DMA_WRITE;
+ bits = 0;
+
+ if (enable)
+ bits |= GI_DMA_ENABLE | GI_DMA_INT_ENA;
+ if (!read)
+ bits |= GI_DMA_WRITE;
+ ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), mask, bits);
break;
}
}
@@ -94,9 +92,7 @@ static int ni_tio_input_inttrig(struct comedi_device *dev,
struct ni_gpct *counter = s->private;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned long flags;
- int retval = 0;
-
- BUG_ON(counter == NULL);
+ int ret = 0;
if (trig_num != cmd->start_src)
return -EINVAL;
@@ -105,14 +101,14 @@ static int ni_tio_input_inttrig(struct comedi_device *dev,
if (counter->mite_chan)
mite_dma_arm(counter->mite_chan);
else
- retval = -EIO;
+ ret = -EIO;
spin_unlock_irqrestore(&counter->lock, flags);
- if (retval < 0)
- return retval;
- retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ if (ret < 0)
+ return ret;
+ ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
s->async->inttrig = NULL;
- return retval;
+ return ret;
}
static int ni_tio_input_cmd(struct comedi_subdevice *s)
@@ -122,7 +118,7 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s)
unsigned cidx = counter->counter_index;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- int retval = 0;
+ int ret = 0;
/* write alloc the entire buffer */
comedi_buf_write_alloc(s, async->prealloc_bufsz);
@@ -139,31 +135,21 @@ static int ni_tio_input_cmd(struct comedi_subdevice *s)
BUG();
break;
}
- ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, 0);
- ni_tio_configure_dma(counter, 1, 1);
- switch (cmd->start_src) {
- case TRIG_NOW:
- async->inttrig = NULL;
- mite_dma_arm(counter->mite_chan);
- retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
- break;
- case TRIG_INT:
+ ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
+ ni_tio_configure_dma(counter, true, true);
+
+ if (cmd->start_src == TRIG_INT) {
async->inttrig = &ni_tio_input_inttrig;
- break;
- case TRIG_EXT:
+ } else { /* TRIG_NOW || TRIG_EXT || TRIG_OTHER */
async->inttrig = NULL;
mite_dma_arm(counter->mite_chan);
- retval = ni_tio_arm(counter, 1, cmd->start_arg);
- break;
- case TRIG_OTHER:
- async->inttrig = NULL;
- mite_dma_arm(counter->mite_chan);
- break;
- default:
- BUG();
- break;
+
+ if (cmd->start_src == TRIG_NOW)
+ ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ else if (cmd->start_src == TRIG_EXT)
+ ret = ni_tio_arm(counter, 1, cmd->start_arg);
}
- return retval;
+ return ret;
}
static int ni_tio_output_cmd(struct comedi_subdevice *s)
@@ -176,7 +162,7 @@ static int ni_tio_output_cmd(struct comedi_subdevice *s)
counter->mite_chan->dir = COMEDI_OUTPUT;
mite_prep_dma(counter->mite_chan, 32, 32);
- ni_tio_configure_dma(counter, 1, 0);
+ ni_tio_configure_dma(counter, true, false);
mite_dma_arm(counter->mite_chan);
return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
}
@@ -201,8 +187,8 @@ static int ni_tio_cmd_setup(struct comedi_subdevice *s)
retval = ni_tio_set_gate_src(counter, 0, gate_source);
if (cmd->flags & TRIG_WAKE_EOS) {
ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
- Gi_Gate_Interrupt_Enable_Bit(cidx),
- Gi_Gate_Interrupt_Enable_Bit(cidx));
+ GI_GATE_INTERRUPT_ENABLE(cidx),
+ GI_GATE_INTERRUPT_ENABLE(cidx));
}
return retval;
}
@@ -319,10 +305,10 @@ int ni_tio_cancel(struct ni_gpct *counter)
if (counter->mite_chan)
mite_dma_disarm(counter->mite_chan);
spin_unlock_irqrestore(&counter->lock, flags);
- ni_tio_configure_dma(counter, 0, 0);
+ ni_tio_configure_dma(counter, false, false);
ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx),
- Gi_Gate_Interrupt_Enable_Bit(cidx), 0x0);
+ GI_GATE_INTERRUPT_ENABLE(cidx), 0x0);
return 0;
}
EXPORT_SYMBOL_GPL(ni_tio_cancel);
@@ -342,7 +328,6 @@ static int should_ack_gate(struct ni_gpct *counter)
in register-level manual) */
case ni_gpct_variant_660x:
return 1;
- break;
case ni_gpct_variant_e_series:
spin_lock_irqsave(&counter->lock, flags);
{
@@ -358,9 +343,11 @@ static int should_ack_gate(struct ni_gpct *counter)
return retval;
}
-void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
- int *tc_error, int *perm_stale_data,
- int *stale_data)
+static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter,
+ int *gate_error,
+ int *tc_error,
+ int *perm_stale_data,
+ int *stale_data)
{
unsigned cidx = counter->counter_index;
const unsigned short gxx_status = read_register(counter,
@@ -378,8 +365,8 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
if (stale_data)
*stale_data = 0;
- if (gxx_status & Gi_Gate_Error_Bit(cidx)) {
- ack |= Gi_Gate_Error_Confirm_Bit(cidx);
+ if (gxx_status & GI_GATE_ERROR(cidx)) {
+ ack |= GI_GATE_ERROR_CONFIRM(cidx);
if (gate_error) {
/*660x don't support automatic acknowledgement
of gate interrupt via dma read/write
@@ -390,27 +377,27 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
}
}
}
- if (gxx_status & Gi_TC_Error_Bit(cidx)) {
- ack |= Gi_TC_Error_Confirm_Bit(cidx);
+ if (gxx_status & GI_TC_ERROR(cidx)) {
+ ack |= GI_TC_ERROR_CONFIRM(cidx);
if (tc_error)
*tc_error = 1;
}
- if (gi_status & Gi_TC_Bit)
- ack |= Gi_TC_Interrupt_Ack_Bit;
- if (gi_status & Gi_Gate_Interrupt_Bit) {
+ if (gi_status & GI_TC)
+ ack |= GI_TC_INTERRUPT_ACK;
+ if (gi_status & GI_GATE_INTERRUPT) {
if (should_ack_gate(counter))
- ack |= Gi_Gate_Interrupt_Ack_Bit;
+ ack |= GI_GATE_INTERRUPT_ACK;
}
if (ack)
write_register(counter, ack, NITIO_INT_ACK_REG(cidx));
if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) &
- Gi_Loading_On_Gate_Bit) {
- if (gxx_status & Gi_Stale_Data_Bit(cidx)) {
+ GI_LOADING_ON_GATE) {
+ if (gxx_status & GI_STALE_DATA(cidx)) {
if (stale_data)
*stale_data = 1;
}
if (read_register(counter, NITIO_STATUS2_REG(cidx)) &
- Gi_Permanent_Stale_Bit(cidx)) {
+ GI_PERMANENT_STALE(cidx)) {
dev_info(counter->counter_dev->dev->class_dev,
"%s: Gi_Permanent_Stale_Data detected.\n",
__func__);
@@ -419,7 +406,12 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
}
}
}
-EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm);
+
+void ni_tio_acknowledge(struct ni_gpct *counter)
+{
+ ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(ni_tio_acknowledge);
void ni_tio_handle_interrupt(struct ni_gpct *counter,
struct comedi_subdevice *s)
@@ -444,7 +436,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter,
case ni_gpct_variant_m_series:
case ni_gpct_variant_660x:
if (read_register(counter, NITIO_DMA_STATUS_REG(cidx)) &
- Gi_DRQ_Error_Bit) {
+ GI_DRQ_ERROR) {
dev_notice(counter->counter_dev->dev->class_dev,
"%s: Gi_DRQ_Error detected.\n", __func__);
s->async->events |= COMEDI_CB_OVERFLOW;
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index c38d97a9a899..40f9136f0bb6 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -206,7 +206,7 @@ static irqreturn_t pcl711_interrupt(int irq, void *d)
unsigned int data;
if (!dev->attached) {
- comedi_error(dev, "spurious interrupt");
+ dev_err(dev->class_dev, "spurious interrupt\n");
return IRQ_HANDLED;
}
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index 8af13e790ad1..c7f8eb1cf8de 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -15,6 +15,7 @@
* (ADLink) ACL-7124 [acl7124]
* (ADLink) PET-48DIO [pet48dio]
* (WinSystems) PCM-IO48 [pcmio48]
+ * (Diamond Systems) ONYX-MM-DIO [onyx-mm-dio]
* Author: Michal Dobes <dobes@tesnet.cz>
* Status: untested
*
@@ -73,6 +74,10 @@ static const struct pcl724_board boardtypes[] = {
.name = "pcmio48",
.io_range = 0x08,
.numofports = 2, /* 48 DIO channels */
+ }, {
+ .name = "onyx-mm-dio",
+ .io_range = 0x10,
+ .numofports = 2, /* 48 DIO channels */
},
};
@@ -83,14 +88,12 @@ static int pcl724_8255mapped_io(int dir, int port, int data,
iobase &= 0x0fff;
+ outb(port + movport, iobase);
if (dir) {
- outb(port + movport, iobase);
outb(data, iobase + 1);
return 0;
- } else {
- outb(port + movport, iobase);
- return inb(iobase + 1);
}
+ return inb(iobase + 1);
}
static int pcl724_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index 7fb044ce399b..bdce24c42940 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -19,6 +19,7 @@
* (Advantech) PCL-734 [pcl734]
* (Diamond Systems) OPMM-1616-XT [opmm-1616-xt]
* (Diamond Systems) PEARL-MM-P [prearl-mm-p]
+ * (Diamond Systems) IR104-PBF [ir104-pbf]
* Author: José Luis Sánchez (jsanchezv@teleline.es)
* Status: untested
*
@@ -93,6 +94,15 @@
*
* BASE+0 Isolated outputs 0-7 (write)
* BASE+1 Isolated outputs 8-15 (write)
+ *
+ * The ir104-pbf board has this register mapping:
+ *
+ * BASE+0 Isolated outputs 0-7 (write) (read back)
+ * BASE+1 Isolated outputs 8-15 (write) (read back)
+ * BASE+2 Isolated outputs 16-19 (write) (read back)
+ * BASE+4 Isolated inputs 0-7 (read)
+ * BASE+5 Isolated inputs 8-15 (read)
+ * BASE+6 Isolated inputs 16-19 (read)
*/
struct pcl730_board {
@@ -100,6 +110,7 @@ struct pcl730_board {
unsigned int io_range;
unsigned is_pcl725:1;
unsigned is_acl7225b:1;
+ unsigned is_ir104:1;
unsigned has_readback:1;
unsigned has_ttl_io:1;
int n_subdevs;
@@ -194,6 +205,13 @@ static const struct pcl730_board pcl730_boards[] = {
.io_range = 0x02,
.n_subdevs = 1,
.n_iso_out_chan = 16,
+ }, {
+ .name = "ir104-pbf",
+ .io_range = 0x08,
+ .is_ir104 = 1,
+ .has_readback = 1,
+ .n_iso_out_chan = 20,
+ .n_iso_in_chan = 20,
},
};
@@ -292,7 +310,8 @@ static int pcl730_attach(struct comedi_device *dev,
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = pcl730_di_insn_bits;
- s->private = board->is_acl7225b ? (void *)2 :
+ s->private = board->is_ir104 ? (void *)4 :
+ board->is_acl7225b ? (void *)2 :
board->is_pcl725 ? (void *)1 : (void *)0;
}
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 4c1b94706478..803e7790538c 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -985,7 +985,7 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
spin_unlock_irqrestore(&dev->spinlock, flags);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static int pcl812_ai_cancel(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index d9ca7fe16c96..54732c5cab97 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -130,10 +130,6 @@ struct pcl816_private {
unsigned int ai_cmd_canceled:1;
};
-static int check_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s,
- unsigned int *chanlist, unsigned int chanlen);
-
static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters)
{
struct pcl816_private *devpriv = dev->private;
@@ -363,6 +359,62 @@ static irqreturn_t pcl816_interrupt(int irq, void *d)
return IRQ_HANDLED;
}
+static int check_channel_list(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int *chanlist,
+ unsigned int chanlen)
+{
+ unsigned int chansegment[16];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (chanlen < 1) {
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
+ return 0;
+ }
+
+ if (chanlen > 1) {
+ /* first channel is every time ok */
+ chansegment[0] = chanlist[0];
+ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
+ /* we detect loop, this must by finish */
+ if (chanlist[0] == chanlist[i])
+ break;
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) {
+ /* channel list isn't continuous :-( */
+ dev_dbg(dev->class_dev,
+ "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
+ i, CR_CHAN(chanlist[i]), nowmustbechan,
+ CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ /* well, this is next correct channel in list */
+ chansegment[i] = chanlist[i];
+ }
+
+ /* check whole chanlist */
+ for (i = 0, segpos = 0; i < chanlen; i++) {
+ if (chanlist[i] != chansegment[i % seglen]) {
+ dev_dbg(dev->class_dev,
+ "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; /* chan/gain list is strange */
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+
+ return seglen; /* we can serve this with MUX logic */
+}
+
static int pcl816_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
@@ -516,7 +568,7 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
cfc_handle_events(dev, s);
- return s->async->buf_write_count - s->async->buf_read_count;
+ return comedi_buf_n_bytes_ready(s);
}
static int pcl816_ai_cancel(struct comedi_device *dev,
@@ -542,62 +594,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
return 0;
}
-static int
-check_channel_list(struct comedi_device *dev,
- struct comedi_subdevice *s, unsigned int *chanlist,
- unsigned int chanlen)
-{
- unsigned int chansegment[16];
- unsigned int i, nowmustbechan, seglen, segpos;
-
- /* correct channel and range number check itself comedi/range.c */
- if (chanlen < 1) {
- comedi_error(dev, "range/channel list is empty!");
- return 0;
- }
-
- if (chanlen > 1) {
- /* first channel is every time ok */
- chansegment[0] = chanlist[0];
- for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
- /* we detect loop, this must by finish */
- if (chanlist[0] == chanlist[i])
- break;
- nowmustbechan =
- (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
- if (nowmustbechan != CR_CHAN(chanlist[i])) {
- /* channel list isn't continuous :-( */
- dev_dbg(dev->class_dev,
- "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
- i, CR_CHAN(chanlist[i]), nowmustbechan,
- CR_CHAN(chanlist[0]));
- return 0;
- }
- /* well, this is next correct channel in list */
- chansegment[i] = chanlist[i];
- }
-
- /* check whole chanlist */
- for (i = 0, segpos = 0; i < chanlen; i++) {
- if (chanlist[i] != chansegment[i % seglen]) {
- dev_dbg(dev->class_dev,
- "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
- i, CR_CHAN(chansegment[i]),
- CR_RANGE(chansegment[i]),
- CR_AREF(chansegment[i]),
- CR_CHAN(chanlist[i % seglen]),
- CR_RANGE(chanlist[i % seglen]),
- CR_AREF(chansegment[i % seglen]));
- return 0; /* chan/gain list is strange */
- }
- }
- } else {
- seglen = 1;
- }
-
- return seglen; /* we can serve this with MUX logic */
-}
-
static int pcl816_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 7d00ae639d38..000dbf841e45 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -551,7 +551,7 @@ static void pcl818_handle_eoc(struct comedi_device *dev,
unsigned int val;
if (pcl818_ai_eoc(dev, s, NULL, 0)) {
- comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+ dev_err(dev->class_dev, "A/D mode1/3 IRQ without DRDY!\n");
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
return;
}
@@ -608,13 +608,14 @@ static void pcl818_handle_fifo(struct comedi_device *dev,
status = inb(dev->iobase + PCL818_FI_STATUS);
if (status & 4) {
- comedi_error(dev, "A/D mode1/3 FIFO overflow!");
+ dev_err(dev->class_dev, "A/D mode1/3 FIFO overflow!\n");
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
return;
}
if (status & 1) {
- comedi_error(dev, "A/D mode1/3 FIFO interrupt without data!");
+ dev_err(dev->class_dev,
+ "A/D mode1/3 FIFO interrupt without data!\n");
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
return;
}
@@ -682,7 +683,7 @@ static int check_channel_list(struct comedi_device *dev,
/* correct channel and range number check itself comedi/range.c */
if (n_chan < 1) {
- comedi_error(dev, "range/channel list is empty!");
+ dev_err(dev->class_dev, "range/channel list is empty!\n");
return 0;
}
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index 53e73737a906..6e0d78f6095b 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -33,7 +33,6 @@ Copy/pasted/hacked from pcm724.c
#include "8255.h"
-#define PCM3724_SIZE 16
#define SIZE_8255 4
#define BUF_C0 0x1
@@ -66,19 +65,6 @@ struct priv_pcm3724 {
int dio_2;
};
-static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
-{
- unsigned long iobase = arg;
- unsigned char inbres;
- if (dir) {
- outb(data, iobase + port);
- return 0;
- } else {
- inbres = inb(iobase + port);
- return inbres;
- }
-}
-
static int compute_buffer(int config, int devno, struct comedi_subdevice *s)
{
/* 1 in io_bits indicates output */
@@ -215,7 +201,7 @@ static int pcm3724_attach(struct comedi_device *dev,
if (!priv)
return -ENOMEM;
- ret = comedi_request_region(dev, it->options[0], PCM3724_SIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
@@ -225,7 +211,7 @@ static int pcm3724_attach(struct comedi_device *dev,
for (i = 0; i < dev->n_subdevices; i++) {
s = &dev->subdevices[i];
- ret = subdev_8255_init(dev, s, subdev_8255_cb,
+ ret = subdev_8255_init(dev, s, NULL,
dev->iobase + SIZE_8255 * i);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 62914bb342d2..1bca3fba0950 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -333,6 +333,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
for (i = 0; i < cmd->chanlist_len; i++) {
unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+
if (triggered & (1 << chan))
val |= (1 << i);
}
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index b3bbec0a0d23..b1db61d9d834 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -351,7 +351,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev,
* time that the device will use.
*/
-static int daqp_ns_to_timer(unsigned int *ns, int round)
+static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags)
{
int timer;
@@ -436,13 +436,13 @@ static int daqp_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- daqp_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ daqp_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- daqp_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ daqp_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
}
@@ -488,15 +488,13 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
*/
if (cmd->convert_src == TRIG_TIMER) {
- counter = daqp_ns_to_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ counter = daqp_ns_to_timer(&cmd->convert_arg, cmd->flags);
outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
scanlist_start_on_every_entry = 1;
} else {
- counter = daqp_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ counter = daqp_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index d55c5893203b..6fc4ed33f66c 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -373,7 +373,6 @@ static const struct rtd_boardinfo rtd520Boards[] = {
struct rtd_private {
/* memory mapped board structures */
- void __iomem *las0;
void __iomem *las1;
void __iomem *lcfg;
@@ -397,11 +396,11 @@ struct rtd_private {
Note: you have to check if the value is larger than the counter range!
*/
static int rtd_ns_to_timer_base(unsigned int *nanosec,
- int round_mode, int base)
+ unsigned int flags, int base)
{
int divider;
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (*nanosec + base / 2) / base;
@@ -428,9 +427,9 @@ static int rtd_ns_to_timer_base(unsigned int *nanosec,
return the proper counter value (divider-1) for the internal clock.
Sets the original period to be the true value.
*/
-static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
+static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
{
- return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
+ return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
}
/*
@@ -490,21 +489,19 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
static void rtd_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
- struct rtd_private *devpriv = dev->private;
-
if (n_chan > 1) { /* setup channel gain table */
int ii;
- writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
- writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
+ writel(0, dev->mmio + LAS0_CGT_CLEAR);
+ writel(1, dev->mmio + LAS0_CGT_ENABLE);
for (ii = 0; ii < n_chan; ii++) {
writel(rtd_convert_chan_gain(dev, list[ii], ii),
- devpriv->las0 + LAS0_CGT_WRITE);
+ dev->mmio + LAS0_CGT_WRITE);
}
} else { /* just use the channel gain latch */
- writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
+ writel(0, dev->mmio + LAS0_CGT_ENABLE);
writel(rtd_convert_chan_gain(dev, list[0], 0),
- devpriv->las0 + LAS0_CGL_WRITE);
+ dev->mmio + LAS0_CGL_WRITE);
}
}
@@ -512,23 +509,22 @@ 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 rtd_private *devpriv = dev->private;
unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
unsigned i;
static const unsigned limit = 0x2000;
unsigned fifo_size = 0;
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
rtd_load_channelgain_list(dev, 1, &chanspec);
/* ADC conversion trigger source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
/* convert samples */
for (i = 0; i < limit; ++i) {
unsigned fifo_status;
/* trigger conversion */
- writew(0, devpriv->las0 + LAS0_ADC);
+ writew(0, dev->mmio + LAS0_ADC);
udelay(1);
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(dev->mmio + LAS0_ADC);
if ((fifo_status & FS_ADC_HEMPTY) == 0) {
fifo_size = 2 * i;
break;
@@ -538,7 +534,7 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev)
dev_info(dev->class_dev, "failed to probe fifo size.\n");
return -EIO;
}
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
if (fifo_size != 0x400 && fifo_size != 0x2000) {
dev_info(dev->class_dev,
"unexpected fifo size of %i, expected 1024 or 8192.\n",
@@ -553,10 +549,9 @@ static int rtd_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct rtd_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->las0 + LAS0_ADC);
+ status = readl(dev->mmio + LAS0_ADC);
if (status & FS_ADC_NOT_EMPTY)
return 0;
return -EBUSY;
@@ -571,19 +566,19 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
int n;
/* clear any old fifo data */
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
/* write channel to multiplexer and clear channel gain table */
rtd_load_channelgain_list(dev, 1, &insn->chanspec);
/* ADC conversion trigger source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
/* convert n samples */
for (n = 0; n < insn->n; n++) {
unsigned short d;
/* trigger conversion */
- writew(0, devpriv->las0 + LAS0_ADC);
+ writew(0, dev->mmio + LAS0_ADC);
ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
if (ret)
@@ -645,7 +640,7 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct rtd_private *devpriv = dev->private;
- while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
+ while (readl(dev->mmio + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO);
if (0 == devpriv->ai_count) { /* done */
@@ -685,12 +680,12 @@ static irqreturn_t rtd_interrupt(int irq, void *d)
if (!dev->attached)
return IRQ_NONE;
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(dev->mmio + LAS0_ADC);
/* check for FIFO full, this automatically halts the ADC! */
if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */
goto xfer_abort;
- status = readw(devpriv->las0 + LAS0_IT);
+ status = readw(dev->mmio + LAS0_IT);
/* if interrupt was not caused by our board, or handled above */
if (0 == status)
return IRQ_HANDLED;
@@ -725,30 +720,30 @@ static irqreturn_t rtd_interrupt(int irq, void *d)
}
}
- overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
+ overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
if (overrun)
goto xfer_abort;
/* clear the interrupt */
- writew(status, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ writew(status, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
return IRQ_HANDLED;
xfer_abort:
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
s->async->events |= COMEDI_CB_ERROR;
devpriv->ai_count = 0; /* stop and don't transfer any more */
/* fall into xfer_done */
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);
- writew(0, devpriv->las0 + LAS0_IT);
+ writel(0, dev->mmio + LAS0_PACER_STOP);
+ writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
+ writew(0, dev->mmio + LAS0_IT);
if (devpriv->ai_count > 0) { /* there shouldn't be anything left */
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
+ fifo_status = readl(dev->mmio + LAS0_ADC);
ai_read_dregs(dev, s); /* read anything left in FIFO */
}
@@ -756,12 +751,12 @@ xfer_done:
comedi_event(dev, s);
/* clear the interrupt */
- status = readw(devpriv->las0 + LAS0_IT);
- writew(status, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ status = readw(dev->mmio + LAS0_IT);
+ writew(status, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
- fifo_status = readl(devpriv->las0 + LAS0_ADC);
- overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
+ fifo_status = readl(dev->mmio + LAS0_ADC);
+ overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
return IRQ_HANDLED;
}
@@ -895,13 +890,13 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- rtd_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ rtd_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- rtd_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ rtd_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -931,12 +926,12 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* stop anything currently running */
/* 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);
- writew(0, devpriv->las0 + LAS0_IT);
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
- writel(0, devpriv->las0 + LAS0_OVERRUN);
+ writel(0, dev->mmio + LAS0_PACER_STOP);
+ writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
+ writew(0, dev->mmio + LAS0_IT);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_OVERRUN);
/* start configuration */
/* load channel list and reset CGT */
@@ -945,18 +940,18 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
/* setup the common case and override if needed */
if (cmd->chanlist_len > 1) {
/* pacer start source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_START);
+ writel(0, dev->mmio + LAS0_PACER_START);
/* burst trigger source: PACER */
- writel(1, devpriv->las0 + LAS0_BURST_START);
+ writel(1, dev->mmio + LAS0_BURST_START);
/* ADC conversion trigger source: BURST */
- writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(2, dev->mmio + LAS0_ADC_CONVERSION);
} else { /* single channel */
/* pacer start source: SOFTWARE */
- writel(0, devpriv->las0 + LAS0_PACER_START);
+ writel(0, dev->mmio + LAS0_PACER_START);
/* ADC conversion trigger source: PACER */
- writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
+ writel(1, dev->mmio + LAS0_ADC_CONVERSION);
}
- writel((devpriv->fifosz / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
+ writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
if (TRIG_TIMER == cmd->scan_begin_src) {
/* scan_begin_arg is in nanoseconds */
@@ -993,16 +988,16 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
} else {
/* interrupt for each transfer */
writel((devpriv->xfer_count - 1) & 0xffff,
- devpriv->las0 + LAS0_ACNT);
+ dev->mmio + LAS0_ACNT);
}
} else { /* unknown timing, just use 1/2 FIFO */
devpriv->xfer_count = 0;
devpriv->flags &= ~SEND_EOS;
}
/* pacer clock source: INTERNAL 8MHz */
- writel(1, devpriv->las0 + LAS0_PACER_SELECT);
+ writel(1, dev->mmio + LAS0_PACER_SELECT);
/* just interrupt, don't stop */
- writel(1, devpriv->las0 + LAS0_ACNT_STOP_ENABLE);
+ writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
/* BUG??? these look like enumerated values, but they are bit fields */
@@ -1027,13 +1022,13 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
TRIG_ROUND_NEAREST);
/* set PACER clock */
- writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
+ writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
break;
case TRIG_EXT:
/* pacer start source: EXTERNAL */
- writel(1, devpriv->las0 + LAS0_PACER_START);
+ writel(1, dev->mmio + LAS0_PACER_START);
break;
}
@@ -1045,33 +1040,32 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
timer = rtd_ns_to_timer(&cmd->convert_arg,
TRIG_ROUND_NEAREST);
/* setup BURST clock */
- writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
+ writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
}
break;
case TRIG_EXT: /* external */
/* burst trigger source: EXTERNAL */
- writel(2, devpriv->las0 + LAS0_BURST_START);
+ writel(2, dev->mmio + LAS0_BURST_START);
break;
}
/* end configuration */
/* This doesn't seem to work. There is no way to clear an interrupt
that the priority controller has queued! */
- writew(~0, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ writew(~0, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
/* TODO: allow multiple interrupt sources */
- if (devpriv->xfer_count > 0) { /* transfer every N samples */
- writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
- } else { /* 1/2 FIFO transfers */
- writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
- }
+ if (devpriv->xfer_count > 0) /* transfer every N samples */
+ writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
+ else /* 1/2 FIFO transfers */
+ writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
/* BUG: start_src is ASSUMED to be TRIG_NOW */
/* BUG? it seems like things are running before the "start" */
- readl(devpriv->las0 + LAS0_PACER); /* start pacer */
+ readl(dev->mmio + LAS0_PACER); /* start pacer */
return 0;
}
@@ -1085,13 +1079,13 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
u16 status;
/* 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);
- writew(0, devpriv->las0 + LAS0_IT);
+ writel(0, dev->mmio + LAS0_PACER_STOP);
+ writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
+ writel(0, dev->mmio + LAS0_ADC_CONVERSION);
+ writew(0, dev->mmio + 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;
+ status = readw(dev->mmio + LAS0_IT);
+ overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
return 0;
}
@@ -1100,12 +1094,11 @@ static int rtd_ao_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct rtd_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
unsigned int status;
- status = readl(devpriv->las0 + LAS0_ADC);
+ status = readl(dev->mmio + LAS0_ADC);
if (status & bit)
return 0;
return -EBUSY;
@@ -1122,8 +1115,8 @@ static int rtd_ao_winsn(struct comedi_device *dev,
int ret;
/* Configure the output range (table index matches the range values) */
- writew(range & 7, devpriv->las0 +
- ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
+ writew(range & 7,
+ dev->mmio + ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
@@ -1143,8 +1136,7 @@ static int rtd_ao_winsn(struct comedi_device *dev,
/* a typical programming sequence */
writew(val, devpriv->las1 +
((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
- writew(0, devpriv->las0 +
- ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
+ writew(0, dev->mmio + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
devpriv->ao_readback[chan] = data[i];
@@ -1179,12 +1171,10 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct rtd_private *devpriv = dev->private;
-
if (comedi_dio_update_state(s, data))
- writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
+ writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
- data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
+ data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
return insn->n;
}
@@ -1194,7 +1184,6 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned int *data)
{
- struct rtd_private *devpriv = dev->private;
int ret;
ret = comedi_dio_insn_config(dev, s, insn, data, 0);
@@ -1204,11 +1193,11 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
/* TODO support digital match interrupts and strobes */
/* set direction */
- writew(0x01, devpriv->las0 + LAS0_DIO_STATUS);
- writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
+ writew(0x01, dev->mmio + LAS0_DIO_STATUS);
+ writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
/* clear interrupts */
- writew(0x00, devpriv->las0 + LAS0_DIO_STATUS);
+ writew(0x00, dev->mmio + LAS0_DIO_STATUS);
/* port1 can only be all input or all output */
@@ -1221,12 +1210,12 @@ static void rtd_reset(struct comedi_device *dev)
{
struct rtd_private *devpriv = dev->private;
- writel(0, devpriv->las0 + LAS0_BOARD_RESET);
+ writel(0, dev->mmio + LAS0_BOARD_RESET);
udelay(100); /* needed? */
writel(0, devpriv->lcfg + PLX_INTRCS_REG);
- writew(0, devpriv->las0 + LAS0_IT);
- writew(~0, devpriv->las0 + LAS0_CLEAR);
- readw(devpriv->las0 + LAS0_CLEAR);
+ writew(0, dev->mmio + LAS0_IT);
+ writew(~0, dev->mmio + LAS0_CLEAR);
+ readw(dev->mmio + LAS0_CLEAR);
}
/*
@@ -1235,21 +1224,19 @@ static void rtd_reset(struct comedi_device *dev)
*/
static void rtd_init_board(struct comedi_device *dev)
{
- struct rtd_private *devpriv = dev->private;
-
rtd_reset(dev);
- writel(0, devpriv->las0 + LAS0_OVERRUN);
- writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
- writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
- writel(0, devpriv->las0 + LAS0_DAC1_RESET);
- writel(0, devpriv->las0 + LAS0_DAC2_RESET);
+ writel(0, dev->mmio + LAS0_OVERRUN);
+ writel(0, dev->mmio + LAS0_CGT_CLEAR);
+ writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
+ writel(0, dev->mmio + LAS0_DAC1_RESET);
+ writel(0, dev->mmio + LAS0_DAC2_RESET);
/* clear digital IO fifo */
- 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);
+ writew(0, dev->mmio + LAS0_DIO_STATUS);
+ writeb((0 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
+ writeb((1 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
+ writeb((2 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
+ writeb((3 << 6) | 0x00, dev->mmio + LAS0_UTC_CTRL);
/* TODO: set user out source ??? */
}
@@ -1292,10 +1279,10 @@ static int rtd_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->las0 = pci_ioremap_bar(pcidev, 2);
+ dev->mmio = 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)
+ if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
return -ENOMEM;
rtd_pci_latency_quirk(dev, pcidev);
@@ -1375,7 +1362,7 @@ static void rtd_detach(struct comedi_device *dev)
if (devpriv) {
/* Shut down any board ops by resetting it */
- if (devpriv->las0 && devpriv->lcfg)
+ if (dev->mmio && devpriv->lcfg)
rtd_reset(dev);
if (dev->irq) {
writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
@@ -1383,8 +1370,8 @@ static void rtd_detach(struct comedi_device *dev)
devpriv->lcfg + PLX_INTRCS_REG);
free_irq(dev->irq, dev);
}
- if (devpriv->las0)
- iounmap(devpriv->las0);
+ if (dev->mmio)
+ iounmap(dev->mmio);
if (devpriv->las1)
iounmap(devpriv->las1);
if (devpriv->lcfg)
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index bd447b2add7b..2b1db9783bd6 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -81,8 +81,6 @@
#define RTI800_9513A_CNTRL 0x0d
#define RTI800_9513A_STATUS 0x0d
-#define RTI800_IOSIZE 0x10
-
static const struct comedi_lrange range_rti800_ai_10_bipolar = {
4, {
BIP_RANGE(10),
@@ -281,7 +279,7 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], RTI800_IOSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x10);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index 85d2b7a3c125..83f7433c2452 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -40,13 +40,10 @@ comedi_config /dev/comedi0 s526 0x2C0,0x3
#include "../comedidev.h"
#include <asm/byteorder.h>
-#define S526_SIZE 64
-
#define S526_START_AI_CONV 0
#define S526_AI_READ 0
/* Ports */
-#define S526_IOSIZE 0x40
#define S526_NUM_PORTS 27
/* registers */
@@ -345,7 +342,6 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
default:
return -EINVAL;
- break;
}
return insn->n;
@@ -557,7 +553,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
struct comedi_subdevice *s;
int ret;
- ret = comedi_request_region(dev, it->options[0], S526_IOSIZE);
+ ret = comedi_request_region(dev, it->options[0], 0x40);
if (ret)
return ret;
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 0838f8aa6951..080608a840ac 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -77,7 +77,6 @@ struct s626_buffer_dma {
};
struct s626_private {
- void __iomem *mmio;
uint8_t ai_cmd_running; /* ai_cmd is running */
uint8_t ai_continuous; /* continuous acquisition */
int ai_sample_count; /* number of samples to acquire */
@@ -102,60 +101,9 @@ struct s626_private {
unsigned int ao_readback[S626_DAC_CHANNELS];
};
-/* COUNTER OBJECT ------------------------------------------------ */
-struct s626_enc_info {
- /* Pointers to functions that differ for A and B counters: */
- /* Return clock enable. */
- uint16_t (*get_enable)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Return interrupt source. */
- uint16_t (*get_int_src)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Return preload trigger source. */
- uint16_t (*get_load_trig)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Return standardized operating mode. */
- uint16_t (*get_mode)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Generate soft index strobe. */
- void (*pulse_index)(struct comedi_device *dev,
- const struct s626_enc_info *k);
- /* Program clock enable. */
- void (*set_enable)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t enab);
- /* Program interrupt source. */
- void (*set_int_src)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t int_source);
- /* Program preload trigger source. */
- void (*set_load_trig)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t trig);
- /* Program standardized operating mode. */
- void (*set_mode)(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t setup,
- uint16_t disable_int_src);
- /* Reset event capture flags. */
- void (*reset_cap_flags)(struct comedi_device *dev,
- const struct s626_enc_info *k);
-
- uint16_t my_cra; /* address of CRA register */
- uint16_t my_crb; /* address of CRB register */
- uint16_t my_latch_lsw; /* address of Latch least-significant-word
- * register */
- uint16_t my_event_bits[4]; /* bit translations for IntSrc -->RDMISC2 */
-};
-
/* Counter overflow/index event flag masks for RDMISC2. */
#define S626_INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
#define S626_OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
-#define S626_EVBITS(C) { 0, S626_OVERMASK(C), S626_INDXMASK(C), \
- S626_OVERMASK(C) | S626_INDXMASK(C) }
-
-/*
- * Translation table to map IntSrc into equivalent RDMISC2 event flag bits.
- * static const uint16_t s626_event_bits[][4] =
- * { S626_EVBITS(0), S626_EVBITS(1), S626_EVBITS(2), S626_EVBITS(3),
- * S626_EVBITS(4), S626_EVBITS(5) };
- */
/*
* Enable/disable a function or test status bit(s) that are accessed
@@ -164,29 +112,25 @@ struct s626_enc_info {
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;
mmiowb();
- writel(val, devpriv->mmio + reg);
+ writel(val, dev->mmio + reg);
}
static void s626_mc_disable(struct comedi_device *dev,
unsigned int cmd, unsigned int reg)
{
- struct s626_private *devpriv = dev->private;
-
- writel(cmd << 16 , devpriv->mmio + reg);
+ writel(cmd << 16 , dev->mmio + reg);
mmiowb();
}
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);
+ val = readl(dev->mmio + reg);
return (val & cmd) ? true : false;
}
@@ -208,7 +152,6 @@ static const struct comedi_lrange s626_range_table = {
*/
static void s626_debi_transfer(struct comedi_device *dev)
{
- struct s626_private *devpriv = dev->private;
static const int timeout = 10000;
int i;
@@ -225,17 +168,17 @@ static void s626_debi_transfer(struct comedi_device *dev)
udelay(1);
}
if (i == timeout)
- comedi_error(dev,
- "Timeout while uploading to DEBI control register.");
+ dev_err(dev->class_dev,
+ "Timeout while uploading to DEBI control register\n");
/* Wait until DEBI transfer is done */
for (i = 0; i < timeout; i++) {
- if (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_DEBI_S))
+ if (!(readl(dev->mmio + S626_P_PSR) & S626_PSR_DEBI_S))
break;
udelay(1);
}
if (i == timeout)
- comedi_error(dev, "DEBI transfer timeout.");
+ dev_err(dev->class_dev, "DEBI transfer timeout\n");
}
/*
@@ -243,15 +186,13 @@ static void s626_debi_transfer(struct comedi_device *dev)
*/
static uint16_t s626_debi_read(struct comedi_device *dev, uint16_t addr)
{
- struct s626_private *devpriv = dev->private;
-
/* Set up DEBI control register value in shadow RAM */
- writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+ writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD);
/* Execute the DEBI transfer. */
s626_debi_transfer(dev);
- return readl(devpriv->mmio + S626_P_DEBIAD);
+ return readl(dev->mmio + S626_P_DEBIAD);
}
/*
@@ -260,11 +201,9 @@ static uint16_t s626_debi_read(struct comedi_device *dev, uint16_t addr)
static void s626_debi_write(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 */
- writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
- writel(wdata, devpriv->mmio + S626_P_DEBIAD);
+ writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD);
+ writel(wdata, dev->mmio + S626_P_DEBIAD);
/* Execute the DEBI transfer. */
s626_debi_transfer(dev);
@@ -278,18 +217,17 @@ static void s626_debi_write(struct comedi_device *dev, uint16_t addr,
static void s626_debi_replace(struct comedi_device *dev, unsigned int addr,
unsigned int mask, unsigned int wdata)
{
- struct s626_private *devpriv = dev->private;
unsigned int val;
addr &= 0xffff;
- writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+ writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD);
s626_debi_transfer(dev);
- writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
- val = readl(devpriv->mmio + S626_P_DEBIAD);
+ writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD);
+ val = readl(dev->mmio + S626_P_DEBIAD);
val &= mask;
val |= wdata;
- writel(val & 0xffff, devpriv->mmio + S626_P_DEBIAD);
+ writel(val & 0xffff, dev->mmio + S626_P_DEBIAD);
s626_debi_transfer(dev);
}
@@ -310,12 +248,11 @@ static int s626_i2c_handshake_eoc(struct comedi_device *dev,
static int s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
{
- struct s626_private *devpriv = dev->private;
unsigned int ctrl;
int ret;
/* Write I2C command to I2C Transfer Control shadow register */
- writel(val, devpriv->mmio + S626_P_I2CCTRL);
+ writel(val, dev->mmio + S626_P_I2CCTRL);
/*
* Upload I2C shadow registers into working registers and
@@ -328,7 +265,7 @@ static int s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
/* Wait until I2C bus transfer is finished or an error occurs */
do {
- ctrl = readl(devpriv->mmio + S626_P_I2CCTRL);
+ ctrl = readl(dev->mmio + S626_P_I2CCTRL);
} while ((ctrl & (S626_I2C_BUSY | S626_I2C_ERR)) == S626_I2C_BUSY);
/* Return non-zero if I2C error occurred */
@@ -366,7 +303,7 @@ static uint8_t s626_i2c_read(struct comedi_device *dev, uint8_t addr)
/* Abort function and declare error if handshake failed. */
return 0;
- return (readl(devpriv->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
+ return (readl(dev->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
}
/* *********** DAC FUNCTIONS *********** */
@@ -391,27 +328,26 @@ static int s626_send_dac_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct s626_private *devpriv = dev->private;
unsigned int status;
switch (context) {
case s626_send_dac_wait_not_mc1_a2out:
- status = readl(devpriv->mmio + S626_P_MC1);
+ status = readl(dev->mmio + S626_P_MC1);
if (!(status & S626_MC1_A2OUT))
return 0;
break;
case s626_send_dac_wait_ssr_af2_out:
- status = readl(devpriv->mmio + S626_P_SSR);
+ status = readl(dev->mmio + S626_P_SSR);
if (status & S626_SSR_AF2_OUT)
return 0;
break;
case s626_send_dac_wait_fb_buffer2_msb_00:
- status = readl(devpriv->mmio + S626_P_FB_BUFFER2);
+ status = readl(dev->mmio + S626_P_FB_BUFFER2);
if (!(status & 0xff000000))
return 0;
break;
case s626_send_dac_wait_fb_buffer2_msb_ff:
- status = readl(devpriv->mmio + S626_P_FB_BUFFER2);
+ status = readl(dev->mmio + S626_P_FB_BUFFER2);
if (status & 0xff000000)
return 0;
break;
@@ -448,7 +384,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
/* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
/* Copy DAC setpoint value to DAC's output DMA buffer. */
- /* writel(val, devpriv->mmio + (uint32_t)devpriv->dac_wbuf); */
+ /* writel(val, dev->mmio + (uint32_t)devpriv->dac_wbuf); */
*devpriv->dac_wbuf = val;
/*
@@ -466,7 +402,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* other FIFO underflow/overflow flags). When set, this flag
* will indicate that we have emerged from slot 0.
*/
- writel(S626_ISR_AFOU, devpriv->mmio + S626_P_ISR);
+ writel(S626_ISR_AFOU, dev->mmio + S626_P_ISR);
/*
* Wait for the DMA transfer to finish so that there will be data
@@ -478,7 +414,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_not_mc1_a2out);
if (ret) {
- comedi_error(dev, "DMA transfer timeout.");
+ dev_err(dev->class_dev, "DMA transfer timeout\n");
return ret;
}
@@ -491,7 +427,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* detection.
*/
writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/*
* Wait for slot 1 to execute to ensure that the Packet will be
@@ -503,7 +439,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_ssr_af2_out);
if (ret) {
- comedi_error(dev, "TSL timeout waiting for slot 1 to execute.");
+ dev_err(dev->class_dev,
+ "TSL timeout waiting for slot 1 to execute\n");
return ret;
}
@@ -515,7 +452,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* buffer register.
*/
writel(S626_XSD2 | S626_XFIFO_2 | S626_RSD2 | S626_SIB_A2 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
@@ -537,7 +474,7 @@ static int s626_send_dac(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 (readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000) {
+ if (readl(dev->mmio + S626_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
@@ -548,8 +485,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_fb_buffer2_msb_00);
if (ret) {
- comedi_error(dev,
- "TSL timeout waiting for slot 0 to execute.");
+ dev_err(dev->class_dev,
+ "TSL timeout waiting for slot 0 to execute\n");
return ret;
}
}
@@ -563,7 +500,7 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
* SD3, which is driven only by a pull-up resistor.
*/
writel(S626_RSD3 | S626_SIB_A2 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/*
* Wait for slot 0 to execute, at which time the TSL is setup for
@@ -573,7 +510,8 @@ static int s626_send_dac(struct comedi_device *dev, uint32_t val)
ret = comedi_timeout(dev, NULL, NULL, s626_send_dac_eoc,
s626_send_dac_wait_fb_buffer2_msb_ff);
if (ret) {
- comedi_error(dev, "TSL timeout waiting for slot 0 to execute.");
+ dev_err(dev->class_dev,
+ "TSL timeout waiting for slot 0 to execute\n");
return ret;
}
return 0;
@@ -620,16 +558,16 @@ static int s626_set_dac(struct comedi_device *dev, uint16_t chan,
ws_image = (chan & 2) ? S626_WS1 : S626_WS2;
/* Slot 2: Transmit high data byte to target DAC */
writel(S626_XSD2 | S626_XFIFO_1 | ws_image,
- devpriv->mmio + S626_VECTPORT(2));
+ dev->mmio + S626_VECTPORT(2));
/* Slot 3: Transmit low data byte to target DAC */
writel(S626_XSD2 | S626_XFIFO_0 | ws_image,
- devpriv->mmio + S626_VECTPORT(3));
+ dev->mmio + S626_VECTPORT(3));
/* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
writel(S626_XSD2 | S626_XFIFO_3 | S626_WS3,
- devpriv->mmio + S626_VECTPORT(4));
+ dev->mmio + S626_VECTPORT(4));
/* Slot 5: running after writing target DAC's low data byte */
writel(S626_XSD2 | S626_XFIFO_2 | S626_WS3 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(5));
+ dev->mmio + S626_VECTPORT(5));
/*
* Construct and transmit target DAC's serial packet:
@@ -671,16 +609,16 @@ static int s626_write_trim_dac(struct comedi_device *dev, uint8_t logical_chan,
/* Slot 2: Send high uint8_t to target TrimDac */
writel(S626_XSD2 | S626_XFIFO_1 | S626_WS3,
- devpriv->mmio + S626_VECTPORT(2));
+ dev->mmio + S626_VECTPORT(2));
/* Slot 3: Send low uint8_t to target TrimDac */
writel(S626_XSD2 | S626_XFIFO_0 | S626_WS3,
- devpriv->mmio + S626_VECTPORT(3));
+ dev->mmio + S626_VECTPORT(3));
/* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */
writel(S626_XSD2 | S626_XFIFO_3 | S626_WS1,
- devpriv->mmio + S626_VECTPORT(4));
+ dev->mmio + S626_VECTPORT(4));
/* Slot 5: Send NOP low uint8_t to DAC0 */
writel(S626_XSD2 | S626_XFIFO_2 | S626_WS1 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(5));
+ dev->mmio + S626_VECTPORT(5));
/*
* Construct and transmit target DAC's serial packet:
@@ -723,32 +661,14 @@ static int s626_load_trim_dacs(struct comedi_device *dev)
*/
/*
- * Read a counter's output latch.
- */
-static uint32_t s626_read_latch(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- uint32_t value;
-
- /* Latch counts and fetch LSW of latched counts value. */
- value = s626_debi_read(dev, k->my_latch_lsw);
-
- /* Fetch MSW of latched counts and combine with LSW. */
- value |= ((uint32_t)s626_debi_read(dev, k->my_latch_lsw + 2) << 16);
-
- /* Return latched counts. */
- return value;
-}
-
-/*
* Return/set a counter pair's latch trigger source. 0: On read
* access, 1: A index latches A, 2: B index latches B, 3: A overflow
* latches B.
*/
static void s626_set_latch_source(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- s626_debi_replace(dev, k->my_crb,
+ s626_debi_replace(dev, S626_LP_CRB(chan),
~(S626_CRBMSK_INTCTRL | S626_CRBMSK_LATCHSRC),
S626_SET_CRB_LATCHSRC(value));
}
@@ -757,10 +677,10 @@ static void s626_set_latch_source(struct comedi_device *dev,
* Write value into counter preload register.
*/
static void s626_preload(struct comedi_device *dev,
- const struct s626_enc_info *k, uint32_t value)
+ unsigned int chan, uint32_t value)
{
- s626_debi_write(dev, k->my_latch_lsw, value);
- s626_debi_write(dev, k->my_latch_lsw + 2, value >> 16);
+ s626_debi_write(dev, S626_LP_CNTR(chan), value);
+ s626_debi_write(dev, S626_LP_CNTR(chan) + 2, value >> 16);
}
/* ****** PRIVATE COUNTER FUNCTIONS ****** */
@@ -768,28 +688,27 @@ static void s626_preload(struct comedi_device *dev,
/*
* Reset a counter's index and overflow event capture flags.
*/
-static void s626_reset_cap_flags_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+static void s626_reset_cap_flags(struct comedi_device *dev,
+ unsigned int chan)
{
- s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
- (S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_A(1)));
-}
+ uint16_t set;
-static void s626_reset_cap_flags_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
- (S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_B(1)));
+ set = S626_SET_CRB_INTRESETCMD(1);
+ if (chan < 3)
+ set |= S626_SET_CRB_INTRESET_A(1);
+ else
+ set |= S626_SET_CRB_INTRESET_B(1);
+
+ s626_debi_replace(dev, S626_LP_CRB(chan), ~S626_CRBMSK_INTCTRL, set);
}
+#ifdef unused
/*
* Return counter setup in a format (COUNTER_SETUP) that is consistent
* for both A and B counters.
*/
static uint16_t s626_get_mode_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
uint16_t cra;
uint16_t crb;
@@ -797,8 +716,8 @@ static uint16_t s626_get_mode_a(struct comedi_device *dev,
unsigned cntsrc, clkmult, clkpol, encmode;
/* Fetch CRA and CRB register images. */
- cra = s626_debi_read(dev, k->my_cra);
- crb = s626_debi_read(dev, k->my_crb);
+ cra = s626_debi_read(dev, S626_LP_CRA(chan));
+ crb = s626_debi_read(dev, S626_LP_CRB(chan));
/*
* Populate the standardized counter setup bit fields.
@@ -844,7 +763,7 @@ static uint16_t s626_get_mode_a(struct comedi_device *dev,
}
static uint16_t s626_get_mode_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
uint16_t cra;
uint16_t crb;
@@ -852,8 +771,8 @@ static uint16_t s626_get_mode_b(struct comedi_device *dev,
unsigned cntsrc, clkmult, clkpol, encmode;
/* Fetch CRA and CRB register images. */
- cra = s626_debi_read(dev, k->my_cra);
- crb = s626_debi_read(dev, k->my_crb);
+ cra = s626_debi_read(dev, S626_LP_CRA(chan));
+ crb = s626_debi_read(dev, S626_LP_CRB(chan));
/*
* Populate the standardized counter setup bit fields.
@@ -903,6 +822,14 @@ static uint16_t s626_get_mode_b(struct comedi_device *dev,
return setup;
}
+static uint16_t s626_get_mode(struct comedi_device *dev,
+ unsigned int chan)
+{
+ return (chan < 3) ? s626_get_mode_a(dev, chan)
+ : s626_get_mode_b(dev, chan);
+}
+#endif
+
/*
* Set the operating mode for the specified counter. The setup
* parameter is treated as a COUNTER_SETUP data type. The following
@@ -910,7 +837,7 @@ static uint16_t s626_get_mode_b(struct comedi_device *dev,
* ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
*/
static void s626_set_mode_a(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t setup,
+ unsigned int chan, uint16_t setup,
uint16_t disable_int_src)
{
struct s626_private *devpriv = dev->private;
@@ -974,20 +901,21 @@ static void s626_set_mode_a(struct comedi_device *dev,
* enable mask to indicate the counter interrupt is disabled.
*/
if (disable_int_src)
- devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+ devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
/*
* While retaining CounterB and LatchSrc configurations, program the
* new counter operating mode.
*/
- s626_debi_replace(dev, k->my_cra,
+ s626_debi_replace(dev, S626_LP_CRA(chan),
S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B, cra);
- s626_debi_replace(dev, k->my_crb,
+ s626_debi_replace(dev, S626_LP_CRB(chan),
~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A), crb);
}
static void s626_set_mode_b(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t setup,
+ unsigned int chan, uint16_t setup,
uint16_t disable_int_src)
{
struct s626_private *devpriv = dev->private;
@@ -1058,54 +986,64 @@ static void s626_set_mode_b(struct comedi_device *dev,
* enable mask to indicate the counter interrupt is disabled.
*/
if (disable_int_src)
- devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+ devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
/*
* While retaining CounterA and LatchSrc configurations, program the
* new counter operating mode.
*/
- s626_debi_replace(dev, k->my_cra,
+ s626_debi_replace(dev, S626_LP_CRA(chan),
~(S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B), cra);
- s626_debi_replace(dev, k->my_crb,
+ s626_debi_replace(dev, S626_LP_CRB(chan),
S626_CRBMSK_CLKENAB_A | S626_CRBMSK_LATCHSRC, crb);
}
+static void s626_set_mode(struct comedi_device *dev,
+ unsigned int chan,
+ uint16_t setup, uint16_t disable_int_src)
+{
+ if (chan < 3)
+ s626_set_mode_a(dev, chan, setup, disable_int_src);
+ else
+ s626_set_mode_b(dev, chan, setup, disable_int_src);
+}
+
/*
* Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index.
*/
-static void s626_set_enable_a(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t enab)
+static void s626_set_enable(struct comedi_device *dev,
+ unsigned int chan, uint16_t enab)
{
- s626_debi_replace(dev, k->my_crb,
- ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A),
- S626_SET_CRB_CLKENAB_A(enab));
-}
+ unsigned int mask = S626_CRBMSK_INTCTRL;
+ unsigned int set;
-static void s626_set_enable_b(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t enab)
-{
- s626_debi_replace(dev, k->my_crb,
- ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_B),
- S626_SET_CRB_CLKENAB_B(enab));
+ if (chan < 3) {
+ mask |= S626_CRBMSK_CLKENAB_A;
+ set = S626_SET_CRB_CLKENAB_A(enab);
+ } else {
+ mask |= S626_CRBMSK_CLKENAB_B;
+ set = S626_SET_CRB_CLKENAB_B(enab);
+ }
+ s626_debi_replace(dev, S626_LP_CRB(chan), ~mask, set);
}
-static uint16_t s626_get_enable_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+#ifdef unused
+static uint16_t s626_get_enable(struct comedi_device *dev,
+ unsigned int chan)
{
- return S626_GET_CRB_CLKENAB_A(s626_debi_read(dev, k->my_crb));
-}
+ uint16_t crb = s626_debi_read(dev, S626_LP_CRB(chan));
-static uint16_t s626_get_enable_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- return S626_GET_CRB_CLKENAB_B(s626_debi_read(dev, k->my_crb));
+ return (chan < 3) ? S626_GET_CRB_CLKENAB_A(crb)
+ : S626_GET_CRB_CLKENAB_B(crb);
}
+#endif
#ifdef unused
static uint16_t s626_get_latch_source(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_CRB_LATCHSRC(s626_debi_read(dev, k->my_crb));
+ return S626_GET_CRB_LATCHSRC(s626_debi_read(dev, S626_LP_CRB(chan)));
}
#endif
@@ -1114,295 +1052,244 @@ static uint16_t s626_get_latch_source(struct comedi_device *dev,
* register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
* 2=OverflowA (B counters only), 3=disabled.
*/
-static void s626_set_load_trig_a(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t trig)
-{
- s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_LOADSRC_A,
- S626_SET_CRA_LOADSRC_A(trig));
-}
-
-static void s626_set_load_trig_b(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t trig)
+static void s626_set_load_trig(struct comedi_device *dev,
+ unsigned int chan, uint16_t trig)
{
- s626_debi_replace(dev, k->my_crb,
- ~(S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL),
- S626_SET_CRB_LOADSRC_B(trig));
-}
+ uint16_t reg;
+ uint16_t mask;
+ uint16_t set;
-static uint16_t s626_get_load_trig_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- return S626_GET_CRA_LOADSRC_A(s626_debi_read(dev, k->my_cra));
+ if (chan < 3) {
+ reg = S626_LP_CRA(chan);
+ mask = S626_CRAMSK_LOADSRC_A;
+ set = S626_SET_CRA_LOADSRC_A(trig);
+ } else {
+ reg = S626_LP_CRB(chan);
+ mask = S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL;
+ set = S626_SET_CRB_LOADSRC_B(trig);
+ }
+ s626_debi_replace(dev, reg, ~mask, set);
}
-static uint16_t s626_get_load_trig_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
+#ifdef unused
+static uint16_t s626_get_load_trig(struct comedi_device *dev,
+ unsigned int chan)
{
- return S626_GET_CRB_LOADSRC_B(s626_debi_read(dev, k->my_crb));
+ if (chan < 3)
+ return S626_GET_CRA_LOADSRC_A(s626_debi_read(dev,
+ S626_LP_CRA(chan)));
+ else
+ return S626_GET_CRB_LOADSRC_B(s626_debi_read(dev,
+ S626_LP_CRB(chan)));
}
+#endif
/*
* Return/set counter interrupt source and clear any captured
* index/overflow events. int_source: 0=Disabled, 1=OverflowOnly,
* 2=IndexOnly, 3=IndexAndOverflow.
*/
-static void s626_set_int_src_a(struct comedi_device *dev,
- const struct s626_enc_info *k,
- uint16_t int_source)
-{
- struct s626_private *devpriv = dev->private;
-
- /* Reset any pending counter overflow or index captures. */
- s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
- (S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_A(1)));
-
- /* Program counter interrupt source. */
- s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_INTSRC_A,
- S626_SET_CRA_INTSRC_A(int_source));
-
- /* Update MISC2 interrupt enable mask. */
- devpriv->counter_int_enabs =
- (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
- k->my_event_bits[int_source];
-}
-
-static void s626_set_int_src_b(struct comedi_device *dev,
- const struct s626_enc_info *k,
- uint16_t int_source)
+static void s626_set_int_src(struct comedi_device *dev,
+ unsigned int chan, uint16_t int_source)
{
struct s626_private *devpriv = dev->private;
- uint16_t crb;
+ uint16_t cra_reg = S626_LP_CRA(chan);
+ uint16_t crb_reg = S626_LP_CRB(chan);
+
+ if (chan < 3) {
+ /* Reset any pending counter overflow or index captures */
+ s626_debi_replace(dev, crb_reg, ~S626_CRBMSK_INTCTRL,
+ S626_SET_CRB_INTRESETCMD(1) |
+ S626_SET_CRB_INTRESET_A(1));
+
+ /* Program counter interrupt source */
+ s626_debi_replace(dev, cra_reg, ~S626_CRAMSK_INTSRC_A,
+ S626_SET_CRA_INTSRC_A(int_source));
+ } else {
+ uint16_t crb;
- /* Cache writeable CRB register image. */
- crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
+ /* Cache writeable CRB register image */
+ crb = s626_debi_read(dev, crb_reg);
+ crb &= ~S626_CRBMSK_INTCTRL;
- /* Reset any pending counter overflow or index captures. */
- s626_debi_write(dev, k->my_crb, (crb | S626_SET_CRB_INTRESETCMD(1) |
- S626_SET_CRB_INTRESET_B(1)));
+ /* Reset any pending counter overflow or index captures */
+ s626_debi_write(dev, crb_reg,
+ crb | S626_SET_CRB_INTRESETCMD(1) |
+ S626_SET_CRB_INTRESET_B(1));
- /* Program counter interrupt source. */
- s626_debi_write(dev, k->my_crb, ((crb & ~S626_CRBMSK_INTSRC_B) |
- S626_SET_CRB_INTSRC_B(int_source)));
+ /* Program counter interrupt source */
+ s626_debi_write(dev, crb_reg,
+ (crb & ~S626_CRBMSK_INTSRC_B) |
+ S626_SET_CRB_INTSRC_B(int_source));
+ }
/* Update MISC2 interrupt enable mask. */
- devpriv->counter_int_enabs =
- (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
- k->my_event_bits[int_source];
-}
-
-static uint16_t s626_get_int_src_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- return S626_GET_CRA_INTSRC_A(s626_debi_read(dev, k->my_cra));
+ devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
+ switch (int_source) {
+ case 0:
+ default:
+ break;
+ case 1:
+ devpriv->counter_int_enabs |= S626_OVERMASK(chan);
+ break;
+ case 2:
+ devpriv->counter_int_enabs |= S626_INDXMASK(chan);
+ break;
+ case 3:
+ devpriv->counter_int_enabs |= (S626_OVERMASK(chan) |
+ S626_INDXMASK(chan));
+ break;
+ }
}
-static uint16_t s626_get_int_src_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
+#ifdef unused
+static uint16_t s626_get_int_src(struct comedi_device *dev,
+ unsigned int chan)
{
- return S626_GET_CRB_INTSRC_B(s626_debi_read(dev, k->my_crb));
+ if (chan < 3)
+ return S626_GET_CRA_INTSRC_A(s626_debi_read(dev,
+ S626_LP_CRA(chan)));
+ else
+ return S626_GET_CRB_INTSRC_B(s626_debi_read(dev,
+ S626_LP_CRB(chan)));
}
+#endif
#ifdef unused
/*
* Return/set the clock multiplier.
*/
static void s626_set_clk_mult(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKMULT) |
- S626_SET_STD_CLKMULT(value)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_CLKMULT;
+ mode |= S626_SET_STD_CLKMULT(value);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_clk_mult(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_CLKMULT(k->get_mode(dev, k));
+ return S626_GET_STD_CLKMULT(s626_get_mode(dev, chan));
}
/*
* Return/set the clock polarity.
*/
static void s626_set_clk_pol(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKPOL) |
- S626_SET_STD_CLKPOL(value)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_CLKPOL;
+ mode |= S626_SET_STD_CLKPOL(value);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_clk_pol(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_CLKPOL(k->get_mode(dev, k));
+ return S626_GET_STD_CLKPOL(s626_get_mode(dev, chan));
}
/*
* Return/set the encoder mode.
*/
static void s626_set_enc_mode(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_ENCMODE) |
- S626_SET_STD_ENCMODE(value)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_ENCMODE;
+ mode |= S626_SET_STD_ENCMODE(value);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_enc_mode(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_ENCMODE(k->get_mode(dev, k));
+ return S626_GET_STD_ENCMODE(s626_get_mode(dev, chan));
}
/*
* Return/set the index polarity.
*/
static void s626_set_index_pol(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXPOL) |
- S626_SET_STD_INDXPOL(value != 0)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_INDXPOL;
+ mode |= S626_SET_STD_INDXPOL(value != 0);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_index_pol(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_INDXPOL(k->get_mode(dev, k));
+ return S626_GET_STD_INDXPOL(s626_get_mode(dev, chan));
}
/*
* Return/set the index source.
*/
static void s626_set_index_src(struct comedi_device *dev,
- const struct s626_enc_info *k, uint16_t value)
+ unsigned int chan, uint16_t value)
{
- k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXSRC) |
- S626_SET_STD_INDXSRC(value != 0)), false);
+ uint16_t mode;
+
+ mode = s626_get_mode(dev, chan);
+ mode &= ~S626_STDMSK_INDXSRC;
+ mode |= S626_SET_STD_INDXSRC(value != 0);
+
+ s626_set_mode(dev, chan, mode, false);
}
static uint16_t s626_get_index_src(struct comedi_device *dev,
- const struct s626_enc_info *k)
+ unsigned int chan)
{
- return S626_GET_STD_INDXSRC(k->get_mode(dev, k));
+ return S626_GET_STD_INDXSRC(s626_get_mode(dev, chan));
}
#endif
/*
* Generate an index pulse.
*/
-static void s626_pulse_index_a(struct comedi_device *dev,
- const struct s626_enc_info *k)
+static void s626_pulse_index(struct comedi_device *dev,
+ unsigned int chan)
{
- uint16_t cra;
+ if (chan < 3) {
+ uint16_t cra;
- cra = s626_debi_read(dev, k->my_cra);
- /* Pulse index. */
- s626_debi_write(dev, k->my_cra, (cra ^ S626_CRAMSK_INDXPOL_A));
- s626_debi_write(dev, k->my_cra, cra);
-}
+ cra = s626_debi_read(dev, S626_LP_CRA(chan));
-static void s626_pulse_index_b(struct comedi_device *dev,
- const struct s626_enc_info *k)
-{
- uint16_t crb;
+ /* Pulse index */
+ s626_debi_write(dev, S626_LP_CRA(chan),
+ (cra ^ S626_CRAMSK_INDXPOL_A));
+ s626_debi_write(dev, S626_LP_CRA(chan), cra);
+ } else {
+ uint16_t crb;
- crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
- /* Pulse index. */
- s626_debi_write(dev, k->my_crb, (crb ^ S626_CRBMSK_INDXPOL_B));
- s626_debi_write(dev, k->my_crb, crb);
-}
+ crb = s626_debi_read(dev, S626_LP_CRB(chan));
+ crb &= ~S626_CRBMSK_INTCTRL;
-static const struct s626_enc_info s626_enc_chan_info[] = {
- {
- .get_enable = s626_get_enable_a,
- .get_int_src = s626_get_int_src_a,
- .get_load_trig = s626_get_load_trig_a,
- .get_mode = s626_get_mode_a,
- .pulse_index = s626_pulse_index_a,
- .set_enable = s626_set_enable_a,
- .set_int_src = s626_set_int_src_a,
- .set_load_trig = s626_set_load_trig_a,
- .set_mode = s626_set_mode_a,
- .reset_cap_flags = s626_reset_cap_flags_a,
- .my_cra = S626_LP_CR0A,
- .my_crb = S626_LP_CR0B,
- .my_latch_lsw = S626_LP_CNTR0ALSW,
- .my_event_bits = S626_EVBITS(0),
- }, {
- .get_enable = s626_get_enable_a,
- .get_int_src = s626_get_int_src_a,
- .get_load_trig = s626_get_load_trig_a,
- .get_mode = s626_get_mode_a,
- .pulse_index = s626_pulse_index_a,
- .set_enable = s626_set_enable_a,
- .set_int_src = s626_set_int_src_a,
- .set_load_trig = s626_set_load_trig_a,
- .set_mode = s626_set_mode_a,
- .reset_cap_flags = s626_reset_cap_flags_a,
- .my_cra = S626_LP_CR1A,
- .my_crb = S626_LP_CR1B,
- .my_latch_lsw = S626_LP_CNTR1ALSW,
- .my_event_bits = S626_EVBITS(1),
- }, {
- .get_enable = s626_get_enable_a,
- .get_int_src = s626_get_int_src_a,
- .get_load_trig = s626_get_load_trig_a,
- .get_mode = s626_get_mode_a,
- .pulse_index = s626_pulse_index_a,
- .set_enable = s626_set_enable_a,
- .set_int_src = s626_set_int_src_a,
- .set_load_trig = s626_set_load_trig_a,
- .set_mode = s626_set_mode_a,
- .reset_cap_flags = s626_reset_cap_flags_a,
- .my_cra = S626_LP_CR2A,
- .my_crb = S626_LP_CR2B,
- .my_latch_lsw = S626_LP_CNTR2ALSW,
- .my_event_bits = S626_EVBITS(2),
- }, {
- .get_enable = s626_get_enable_b,
- .get_int_src = s626_get_int_src_b,
- .get_load_trig = s626_get_load_trig_b,
- .get_mode = s626_get_mode_b,
- .pulse_index = s626_pulse_index_b,
- .set_enable = s626_set_enable_b,
- .set_int_src = s626_set_int_src_b,
- .set_load_trig = s626_set_load_trig_b,
- .set_mode = s626_set_mode_b,
- .reset_cap_flags = s626_reset_cap_flags_b,
- .my_cra = S626_LP_CR0A,
- .my_crb = S626_LP_CR0B,
- .my_latch_lsw = S626_LP_CNTR0BLSW,
- .my_event_bits = S626_EVBITS(3),
- }, {
- .get_enable = s626_get_enable_b,
- .get_int_src = s626_get_int_src_b,
- .get_load_trig = s626_get_load_trig_b,
- .get_mode = s626_get_mode_b,
- .pulse_index = s626_pulse_index_b,
- .set_enable = s626_set_enable_b,
- .set_int_src = s626_set_int_src_b,
- .set_load_trig = s626_set_load_trig_b,
- .set_mode = s626_set_mode_b,
- .reset_cap_flags = s626_reset_cap_flags_b,
- .my_cra = S626_LP_CR1A,
- .my_crb = S626_LP_CR1B,
- .my_latch_lsw = S626_LP_CNTR1BLSW,
- .my_event_bits = S626_EVBITS(4),
- }, {
- .get_enable = s626_get_enable_b,
- .get_int_src = s626_get_int_src_b,
- .get_load_trig = s626_get_load_trig_b,
- .get_mode = s626_get_mode_b,
- .pulse_index = s626_pulse_index_b,
- .set_enable = s626_set_enable_b,
- .set_int_src = s626_set_int_src_b,
- .set_load_trig = s626_set_load_trig_b,
- .set_mode = s626_set_mode_b,
- .reset_cap_flags = s626_reset_cap_flags_b,
- .my_cra = S626_LP_CR2A,
- .my_crb = S626_LP_CR2B,
- .my_latch_lsw = S626_LP_CNTR2BLSW,
- .my_event_bits = S626_EVBITS(5),
- },
-};
+ /* Pulse index */
+ s626_debi_write(dev, S626_LP_CRB(chan),
+ (crb ^ S626_CRBMSK_INDXPOL_B));
+ s626_debi_write(dev, S626_LP_CRB(chan), crb);
+ }
+}
static unsigned int s626_ai_reg_to_uint(unsigned int data)
{
@@ -1490,11 +1377,8 @@ static void s626_handle_dio_interrupt(struct comedi_device *dev,
}
if (cmd->convert_src == TRIG_TIMER) {
- const struct s626_enc_info *k =
- &s626_enc_chan_info[5];
-
devpriv->ai_convert_count = cmd->chanlist_len;
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_set_enable(dev, 5, S626_CLKENAB_ALWAYS);
}
}
if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 &&
@@ -1533,7 +1417,6 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- const struct s626_enc_info *k;
uint16_t irqbit;
/* read interrupt type */
@@ -1541,39 +1424,29 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
/* check interrupt on counters */
if (irqbit & S626_IRQ_COINT1A) {
- k = &s626_enc_chan_info[0];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 0);
}
if (irqbit & S626_IRQ_COINT2A) {
- k = &s626_enc_chan_info[1];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 1);
}
if (irqbit & S626_IRQ_COINT3A) {
- k = &s626_enc_chan_info[2];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 2);
}
if (irqbit & S626_IRQ_COINT1B) {
- k = &s626_enc_chan_info[3];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 3);
}
if (irqbit & S626_IRQ_COINT2B) {
- k = &s626_enc_chan_info[4];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 4);
if (devpriv->ai_convert_count > 0) {
devpriv->ai_convert_count--;
if (devpriv->ai_convert_count == 0)
- k->set_enable(dev, k, S626_CLKENAB_INDEX);
+ s626_set_enable(dev, 4, S626_CLKENAB_INDEX);
if (cmd->convert_src == TRIG_TIMER) {
/* Trigger ADC scan loop start */
@@ -1583,10 +1456,8 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
}
}
if (irqbit & S626_IRQ_COINT3B) {
- k = &s626_enc_chan_info[5];
-
/* clear interrupt capture flag */
- k->reset_cap_flags(dev, k);
+ s626_reset_cap_flags(dev, 5);
if (cmd->scan_begin_src == TRIG_TIMER) {
/* Trigger ADC scan loop start */
@@ -1594,9 +1465,8 @@ static void s626_check_counter_interrupts(struct comedi_device *dev)
}
if (cmd->convert_src == TRIG_TIMER) {
- k = &s626_enc_chan_info[4];
devpriv->ai_convert_count = cmd->chanlist_len;
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_set_enable(dev, 4, S626_CLKENAB_ALWAYS);
}
}
}
@@ -1661,7 +1531,6 @@ static bool s626_handle_eos_interrupt(struct comedi_device *dev)
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;
@@ -1671,16 +1540,16 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
spin_lock_irqsave(&dev->spinlock, flags);
/* save interrupt enable register state */
- irqstatus = readl(devpriv->mmio + S626_P_IER);
+ irqstatus = readl(dev->mmio + S626_P_IER);
/* read interrupt type */
- irqtype = readl(devpriv->mmio + S626_P_ISR);
+ irqtype = readl(dev->mmio + S626_P_ISR);
/* disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* clear interrupt */
- writel(irqtype, devpriv->mmio + S626_P_ISR);
+ writel(irqtype, dev->mmio + S626_P_ISR);
switch (irqtype) {
case S626_IRQ_RPS1: /* end_of_scan occurs */
@@ -1695,7 +1564,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
}
/* enable interrupt */
- writel(irqstatus, devpriv->mmio + S626_P_IER);
+ writel(irqstatus, dev->mmio + S626_P_IER);
spin_unlock_irqrestore(&dev->spinlock, flags);
return IRQ_HANDLED;
@@ -1723,7 +1592,7 @@ static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl)
/* Initialize RPS instruction pointer */
writel((uint32_t)devpriv->rps_buf.physical_base,
- devpriv->mmio + S626_P_RPSADDR1);
+ dev->mmio + S626_P_RPSADDR1);
/* Construct RPS program in rps_buf DMA buffer */
if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
@@ -1944,10 +1813,9 @@ static int s626_ai_eoc(struct comedi_device *dev,
struct comedi_insn *insn,
unsigned long context)
{
- struct s626_private *devpriv = dev->private;
unsigned int status;
- status = readl(devpriv->mmio + S626_P_PSR);
+ status = readl(dev->mmio + S626_P_PSR);
if (status & S626_PSR_GPIO2)
return 0;
return -EBUSY;
@@ -1955,9 +1823,9 @@ static int s626_ai_eoc(struct comedi_device *dev,
static int s626_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 s626_private *devpriv = dev->private;
uint16_t chan = CR_CHAN(insn->chanspec);
uint16_t range = CR_RANGE(insn->chanspec);
uint16_t adc_spec = 0;
@@ -1986,17 +1854,14 @@ static int s626_ai_insn_read(struct comedi_device *dev,
udelay(10);
/* Start ADC by pulsing GPIO1 low */
- gpio_image = readl(devpriv->mmio + S626_P_GPIO);
+ gpio_image = readl(dev->mmio + S626_P_GPIO);
/* Assert ADC Start command */
- writel(gpio_image & ~S626_GPIO1_HI,
- devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* and stretch it out */
- writel(gpio_image & ~S626_GPIO1_HI,
- devpriv->mmio + S626_P_GPIO);
- writel(gpio_image & ~S626_GPIO1_HI,
- devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* Negate ADC Start command */
- writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/*
* Wait for ADC to complete (GPIO2 is asserted high when
@@ -2011,7 +1876,7 @@ static int s626_ai_insn_read(struct comedi_device *dev,
/* Fetch ADC data */
if (n != 0) {
- tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
+ tmp = readl(dev->mmio + S626_P_FB_BUFFER1);
data[n - 1] = s626_ai_reg_to_uint(tmp);
}
@@ -2031,14 +1896,14 @@ 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.
*/
- gpio_image = readl(devpriv->mmio + S626_P_GPIO);
+ gpio_image = readl(dev->mmio + S626_P_GPIO);
/* Assert ADC Start command */
- writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* and stretch it out */
- writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
- writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
+ writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* Negate ADC Start command */
- writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* Wait for the data to arrive in FB BUFFER 1 register. */
@@ -2051,7 +1916,7 @@ static int s626_ai_insn_read(struct comedi_device *dev,
/* Fetch ADC data */
if (n != 0) {
- tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
+ tmp = readl(dev->mmio + S626_P_FB_BUFFER1);
data[n - 1] = s626_ai_reg_to_uint(tmp);
}
@@ -2098,13 +1963,13 @@ static int s626_ai_inttrig(struct comedi_device *dev,
* Also, it should adjust ns so that it cooresponds to the actual time
* that the device will use.
*/
-static int s626_ns_to_timer(unsigned int *nanosec, int round_mode)
+static int s626_ns_to_timer(unsigned int *nanosec, unsigned int flags)
{
int divider, base;
base = 500; /* 2MHz internal clock */
- switch (round_mode) {
+ switch (flags & TRIG_ROUND_MASK) {
case TRIG_ROUND_NEAREST:
default:
divider = (*nanosec + base / 2) / base;
@@ -2122,7 +1987,7 @@ static int s626_ns_to_timer(unsigned int *nanosec, int round_mode)
}
static void s626_timer_load(struct comedi_device *dev,
- const struct s626_enc_info *k, int tick)
+ unsigned int chan, int tick)
{
uint16_t setup =
/* Preload upon index. */
@@ -2140,26 +2005,26 @@ static void s626_timer_load(struct comedi_device *dev,
uint16_t value_latchsrc = S626_LATCHSRC_A_INDXA;
/* uint16_t enab = S626_CLKENAB_ALWAYS; */
- k->set_mode(dev, k, setup, false);
+ s626_set_mode(dev, chan, setup, false);
/* Set the preload register */
- s626_preload(dev, k, tick);
+ s626_preload(dev, chan, tick);
/*
* Software index pulse forces the preload register to load
* into the counter
*/
- k->set_load_trig(dev, k, 0);
- k->pulse_index(dev, k);
+ s626_set_load_trig(dev, chan, 0);
+ s626_pulse_index(dev, chan);
/* set reload on counter overflow */
- k->set_load_trig(dev, k, 1);
+ s626_set_load_trig(dev, chan, 1);
/* set interrupt on overflow */
- k->set_int_src(dev, k, S626_INTSRC_OVER);
+ s626_set_int_src(dev, chan, S626_INTSRC_OVER);
- s626_set_latch_source(dev, k, value_latchsrc);
- /* k->set_enable(dev, k, (uint16_t)(enab != 0)); */
+ s626_set_latch_source(dev, chan, value_latchsrc);
+ /* s626_set_enable(dev, chan, (uint16_t)(enab != 0)); */
}
/* TO COMPLETE */
@@ -2168,7 +2033,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
struct s626_private *devpriv = dev->private;
uint8_t ppl[16];
struct comedi_cmd *cmd = &s->async->cmd;
- const struct s626_enc_info *k;
int tick;
if (devpriv->ai_cmd_running) {
@@ -2177,10 +2041,10 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
return -EBUSY;
}
/* disable interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* clear interrupt request */
- writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, devpriv->mmio + S626_P_ISR);
+ writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, dev->mmio + S626_P_ISR);
/* clear any pending interrupt */
s626_dio_clear_irq(dev);
@@ -2205,13 +2069,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* set a counter to generate adc trigger at scan_begin_arg
* interval
*/
- k = &s626_enc_chan_info[5];
- tick = s626_ns_to_timer(&cmd->scan_begin_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ tick = s626_ns_to_timer(&cmd->scan_begin_arg, cmd->flags);
/* load timer value and enable interrupt */
- s626_timer_load(dev, k, tick);
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_timer_load(dev, 5, tick);
+ s626_set_enable(dev, 5, S626_CLKENAB_ALWAYS);
break;
case TRIG_EXT:
/* set the digital line and interrupt for scan trigger */
@@ -2228,13 +2090,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
* set a counter to generate adc trigger at convert_arg
* interval
*/
- k = &s626_enc_chan_info[4];
- tick = s626_ns_to_timer(&cmd->convert_arg,
- cmd->flags & TRIG_ROUND_MASK);
+ tick = s626_ns_to_timer(&cmd->convert_arg, cmd->flags);
/* load timer value and enable interrupt */
- s626_timer_load(dev, k, tick);
- k->set_enable(dev, k, S626_CLKENAB_INDEX);
+ s626_timer_load(dev, 4, tick);
+ s626_set_enable(dev, 4, S626_CLKENAB_INDEX);
break;
case TRIG_EXT:
/* set the digital line and interrupt for convert trigger */
@@ -2279,7 +2139,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
}
/* enable interrupt */
- writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, devpriv->mmio + S626_P_IER);
+ writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, dev->mmio + S626_P_IER);
return 0;
}
@@ -2372,13 +2232,13 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- s626_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ s626_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- s626_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ s626_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -2402,7 +2262,7 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
/* disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
devpriv->ai_cmd_running = 0;
@@ -2516,6 +2376,7 @@ static int s626_enc_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
+ unsigned int chan = CR_CHAN(insn->chanspec);
uint16_t setup =
/* Preload upon index. */
S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
@@ -2533,51 +2394,58 @@ static int s626_enc_insn_config(struct comedi_device *dev,
/* uint32_t Preloadvalue; //Counter initial value */
uint16_t value_latchsrc = S626_LATCHSRC_AB_READ;
uint16_t enab = S626_CLKENAB_ALWAYS;
- const struct s626_enc_info *k =
- &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
/* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
- k->set_mode(dev, k, setup, true);
- s626_preload(dev, k, data[0]);
- k->pulse_index(dev, k);
- s626_set_latch_source(dev, k, value_latchsrc);
- k->set_enable(dev, k, (enab != 0));
+ s626_set_mode(dev, chan, setup, true);
+ s626_preload(dev, chan, data[0]);
+ s626_pulse_index(dev, chan);
+ s626_set_latch_source(dev, chan, value_latchsrc);
+ s626_set_enable(dev, chan, (enab != 0));
return insn->n;
}
static int s626_enc_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
- struct comedi_insn *insn, unsigned int *data)
+ struct comedi_insn *insn,
+ unsigned int *data)
{
- int n;
- const struct s626_enc_info *k =
- &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ uint16_t cntr_latch_reg = S626_LP_CNTR(chan);
+ int i;
- for (n = 0; n < insn->n; n++)
- data[n] = s626_read_latch(dev, k);
+ for (i = 0; i < insn->n; i++) {
+ unsigned int val;
- return n;
+ /*
+ * Read the counter's output latch LSW/MSW.
+ * Latches on LSW read.
+ */
+ val = s626_debi_read(dev, cntr_latch_reg);
+ val |= (s626_debi_read(dev, cntr_latch_reg + 2) << 16);
+ data[i] = val;
+ }
+
+ return insn->n;
}
static int s626_enc_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
- const struct s626_enc_info *k =
- &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
+ unsigned int chan = CR_CHAN(insn->chanspec);
/* Set the preload register */
- s626_preload(dev, k, data[0]);
+ s626_preload(dev, chan, data[0]);
/*
* Software index pulse forces the preload register to load
* into the counter
*/
- k->set_load_trig(dev, k, 0);
- k->pulse_index(dev, k);
- k->set_load_trig(dev, k, 2);
+ s626_set_load_trig(dev, chan, 0);
+ s626_pulse_index(dev, chan);
+ s626_set_load_trig(dev, chan, 2);
return 1;
}
@@ -2612,7 +2480,6 @@ static void s626_close_dma_b(struct comedi_device *dev,
static void s626_counters_init(struct comedi_device *dev)
{
int chan;
- const struct s626_enc_info *k;
uint16_t setup =
/* Preload upon index. */
S626_SET_STD_LOADSRC(S626_LOADSRC_INDX) |
@@ -2631,11 +2498,10 @@ static void s626_counters_init(struct comedi_device *dev)
* Disable all counter interrupts and clear any captured counter events.
*/
for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
- k = &s626_enc_chan_info[chan];
- k->set_mode(dev, k, setup, true);
- k->set_int_src(dev, k, 0);
- k->reset_cap_flags(dev, k);
- k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
+ s626_set_mode(dev, chan, setup, true);
+ s626_set_int_src(dev, chan, 0);
+ s626_reset_cap_flags(dev, chan);
+ s626_set_enable(dev, chan, S626_CLKENAB_ALWAYS);
}
}
@@ -2683,13 +2549,13 @@ static int s626_initialize(struct comedi_device *dev)
*/
writel(S626_DEBI_CFG_SLAVE16 |
(S626_DEBI_TOUT << S626_DEBI_CFG_TOUT_BIT) | S626_DEBI_SWAP |
- S626_DEBI_CFG_INTEL, devpriv->mmio + S626_P_DEBICFG);
+ S626_DEBI_CFG_INTEL, dev->mmio + S626_P_DEBICFG);
/* Disable MMU paging */
- writel(S626_DEBI_PAGE_DISABLE, devpriv->mmio + S626_P_DEBIPAGE);
+ writel(S626_DEBI_PAGE_DISABLE, dev->mmio + S626_P_DEBIPAGE);
/* Init GPIO so that ADC Start* is negated */
- writel(S626_GPIO_BASE | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+ writel(S626_GPIO_BASE | S626_GPIO1_HI, dev->mmio + S626_P_GPIO);
/* I2C device address for onboard eeprom (revb) */
devpriv->i2c_adrs = 0xA0;
@@ -2699,7 +2565,7 @@ static int s626_initialize(struct comedi_device *dev)
* operation in progress and reset BUSY flag.
*/
writel(S626_I2C_CLKSEL | S626_I2C_ABORT,
- devpriv->mmio + S626_P_I2CSTAT);
+ dev->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
if (ret)
@@ -2710,7 +2576,7 @@ static int s626_initialize(struct comedi_device *dev)
* reg twice to reset all I2C error flags.
*/
for (i = 0; i < 2; i++) {
- writel(S626_I2C_CLKSEL, devpriv->mmio + S626_P_I2CSTAT);
+ writel(S626_I2C_CLKSEL, dev->mmio + S626_P_I2CSTAT);
s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
ret = comedi_timeout(dev, NULL, NULL, s626_i2c_handshake_eoc, 0);
if (ret)
@@ -2723,7 +2589,7 @@ static int s626_initialize(struct comedi_device *dev)
* DAC data setup times are satisfied, enable DAC serial
* clock out.
*/
- writel(S626_ACON2_INIT, devpriv->mmio + S626_P_ACON2);
+ writel(S626_ACON2_INIT, dev->mmio + S626_P_ACON2);
/*
* Set up TSL1 slot list, which is used to control the
@@ -2731,12 +2597,12 @@ static int s626_initialize(struct comedi_device *dev)
* S626_SIB_A1 = store data uint8_t at next available location
* in FB BUFFER1 register.
*/
- writel(S626_RSD1 | S626_SIB_A1, devpriv->mmio + S626_P_TSL1);
+ writel(S626_RSD1 | S626_SIB_A1, dev->mmio + S626_P_TSL1);
writel(S626_RSD1 | S626_SIB_A1 | S626_EOS,
- devpriv->mmio + S626_P_TSL1 + 4);
+ dev->mmio + S626_P_TSL1 + 4);
/* Enable TSL1 slot list so that it executes all the time */
- writel(S626_ACON1_ADCSTART, devpriv->mmio + S626_P_ACON1);
+ writel(S626_ACON1_ADCSTART, dev->mmio + S626_P_ACON1);
/*
* Initialize RPS registers used for ADC
@@ -2744,11 +2610,11 @@ static int s626_initialize(struct comedi_device *dev)
/* Physical start of RPS program */
writel((uint32_t)devpriv->rps_buf.physical_base,
- devpriv->mmio + S626_P_RPSADDR1);
+ dev->mmio + S626_P_RPSADDR1);
/* RPS program performs no explicit mem writes */
- writel(0, devpriv->mmio + S626_P_RPSPAGE1);
+ writel(0, dev->mmio + S626_P_RPSPAGE1);
/* Disable RPS timeouts */
- writel(0, devpriv->mmio + S626_P_RPS1_TOUT);
+ writel(0, dev->mmio + S626_P_RPS1_TOUT);
#if 0
/*
@@ -2804,7 +2670,7 @@ static int s626_initialize(struct comedi_device *dev)
* burst length = 1 DWORD
* threshold = 1 DWORD.
*/
- writel(0, devpriv->mmio + S626_P_PCI_BT_A);
+ writel(0, dev->mmio + S626_P_PCI_BT_A);
/*
* Init Audio2's output DMA physical addresses. The protection
@@ -2814,9 +2680,9 @@ static int s626_initialize(struct comedi_device *dev)
*/
phys_buf = devpriv->ana_buf.physical_base +
(S626_DAC_WDMABUF_OS * sizeof(uint32_t));
- writel((uint32_t)phys_buf, devpriv->mmio + S626_P_BASEA2_OUT);
+ writel((uint32_t)phys_buf, dev->mmio + S626_P_BASEA2_OUT);
writel((uint32_t)(phys_buf + sizeof(uint32_t)),
- devpriv->mmio + S626_P_PROTA2_OUT);
+ dev->mmio + S626_P_PROTA2_OUT);
/*
* Cache Audio2's output DMA buffer logical address. This is
@@ -2831,7 +2697,7 @@ static int s626_initialize(struct comedi_device *dev)
* DMAC will automatically halt and its PCI address pointer
* will be reset when the protection address is reached.
*/
- writel(8, devpriv->mmio + S626_P_PAGEA2_OUT);
+ writel(8, dev->mmio + S626_P_PAGEA2_OUT);
/*
* Initialize time slot list 2 (TSL2), which is used to control
@@ -2847,7 +2713,7 @@ static int s626_initialize(struct comedi_device *dev)
/* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */
writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2 | S626_EOS,
- devpriv->mmio + S626_VECTPORT(0));
+ dev->mmio + S626_VECTPORT(0));
/*
* Initialize slot 1, which is constant. Slot 1 causes a
@@ -2859,10 +2725,10 @@ static int s626_initialize(struct comedi_device *dev)
*/
/* Slot 1: Fetch DWORD from Audio2's output FIFO */
- writel(S626_LF_A2, devpriv->mmio + S626_VECTPORT(1));
+ writel(S626_LF_A2, dev->mmio + S626_VECTPORT(1));
/* Start DAC's audio interface (TSL2) running */
- writel(S626_ACON1_DACSTART, devpriv->mmio + S626_P_ACON1);
+ writel(S626_ACON1_DACSTART, dev->mmio + S626_P_ACON1);
/*
* Init Trim DACs to calibrated values. Do it twice because the
@@ -2926,15 +2792,15 @@ static int s626_auto_attach(struct comedi_device *dev,
if (ret)
return ret;
- devpriv->mmio = pci_ioremap_bar(pcidev, 0);
- if (!devpriv->mmio)
+ dev->mmio = pci_ioremap_bar(pcidev, 0);
+ if (!dev->mmio)
return -ENOMEM;
/* disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* soft reset */
- writel(S626_MC1_SOFT_RESET, devpriv->mmio + S626_P_MC1);
+ writel(S626_MC1_SOFT_RESET, dev->mmio + S626_P_MC1);
/* DMA FIXME DMA// */
@@ -3043,20 +2909,20 @@ static void s626_detach(struct comedi_device *dev)
/* stop ai_command */
devpriv->ai_cmd_running = 0;
- if (devpriv->mmio) {
+ if (dev->mmio) {
/* interrupt mask */
/* Disable master interrupt */
- writel(0, devpriv->mmio + S626_P_IER);
+ writel(0, dev->mmio + S626_P_IER);
/* Clear board's IRQ status flag */
writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1,
- devpriv->mmio + S626_P_ISR);
+ dev->mmio + S626_P_ISR);
/* Disable the watchdog timer and battery charger. */
s626_write_misc2(dev, 0);
/* Close all interfaces on 7146 device */
- writel(S626_MC1_SHUTDOWN, devpriv->mmio + S626_P_MC1);
- writel(S626_ACON1_BASE, devpriv->mmio + S626_P_ACON1);
+ writel(S626_MC1_SHUTDOWN, dev->mmio + S626_P_MC1);
+ writel(S626_ACON1_BASE, dev->mmio + S626_P_ACON1);
s626_close_dma_b(dev, &devpriv->rps_buf,
S626_DMABUF_SIZE);
@@ -3066,8 +2932,8 @@ static void s626_detach(struct comedi_device *dev)
if (dev->irq)
free_irq(dev->irq, dev);
- if (devpriv->mmio)
- iounmap(devpriv->mmio);
+ if (dev->mmio)
+ iounmap(dev->mmio);
}
comedi_pci_disable(dev);
}
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 33b72739c1cb..b83424e7507b 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -229,27 +229,13 @@
#define S626_LP_RDEDGSEL(x) (0x004c + (x) * 0x10) /* R: edge selection */
#define S626_LP_RDCAPSEL(x) (0x004e + (x) * 0x10) /* R: capture enable */
-/* Counter Registers (read/write): */
-#define S626_LP_CR0A 0x0000 /* 0A setup register. */
-#define S626_LP_CR0B 0x0002 /* 0B setup register. */
-#define S626_LP_CR1A 0x0004 /* 1A setup register. */
-#define S626_LP_CR1B 0x0006 /* 1B setup register. */
-#define S626_LP_CR2A 0x0008 /* 2A setup register. */
-#define S626_LP_CR2B 0x000A /* 2B setup register. */
-
-/* Counter PreLoad (write) and Latch (read) Registers: */
-#define S626_LP_CNTR0ALSW 0x000C /* 0A lsw. */
-#define S626_LP_CNTR0AMSW 0x000E /* 0A msw. */
-#define S626_LP_CNTR0BLSW 0x0010 /* 0B lsw. */
-#define S626_LP_CNTR0BMSW 0x0012 /* 0B msw. */
-#define S626_LP_CNTR1ALSW 0x0014 /* 1A lsw. */
-#define S626_LP_CNTR1AMSW 0x0016 /* 1A msw. */
-#define S626_LP_CNTR1BLSW 0x0018 /* 1B lsw. */
-#define S626_LP_CNTR1BMSW 0x001A /* 1B msw. */
-#define S626_LP_CNTR2ALSW 0x001C /* 2A lsw. */
-#define S626_LP_CNTR2AMSW 0x001E /* 2A msw. */
-#define S626_LP_CNTR2BLSW 0x0020 /* 2B lsw. */
-#define S626_LP_CNTR2BMSW 0x0022 /* 2B msw. */
+/* Counter registers (read/write): 0A 1A 2A 0B 1B 2B */
+#define S626_LP_CRA(x) (0x0000 + (((x) % 3) * 0x4))
+#define S626_LP_CRB(x) (0x0002 + (((x) % 3) * 0x4))
+
+/* Counter PreLoad (write) and Latch (read) Registers: 0A 1A 2A 0B 1B 2B */
+#define S626_LP_CNTR(x) (0x000c + (((x) < 3) ? 0x0 : 0x4) + \
+ (((x) % 3) * 0x8))
/* Miscellaneous Registers (read/write): */
#define S626_LP_MISC1 0x0088 /* Read/write Misc1. */
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index 441813ffb175..167f82418cb4 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -174,6 +174,7 @@ static int serial2002_tty_read(struct file *f, int timeout)
} else {
/* Device does not support poll, busy wait */
int retries = 0;
+
while (1) {
retries++;
if (retries >= timeout)
@@ -311,6 +312,7 @@ static void serial2002_write(struct file *f, struct serial_data data)
} else {
unsigned char ch[6];
int i = 0;
+
if (data.value >= (1L << 30)) {
ch[i] = 0x80 | ((data.value >> 30) & 0x03);
i++;
@@ -359,7 +361,8 @@ static int serial2002_setup_subdevice(struct comedi_subdevice *s,
s->n_chan = chan;
s->maxdata = 0;
kfree(s->maxdata_list);
- maxdata_list = kmalloc(sizeof(unsigned int) * s->n_chan, GFP_KERNEL);
+ maxdata_list = kmalloc_array(s->n_chan, sizeof(unsigned int),
+ GFP_KERNEL);
if (!maxdata_list)
return -ENOMEM;
s->maxdata_list = maxdata_list;
@@ -369,9 +372,8 @@ static int serial2002_setup_subdevice(struct comedi_subdevice *s,
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);
+ range_table_list = kmalloc_array(s->n_chan, sizeof(*range),
+ GFP_KERNEL);
if (!range_table_list)
return -ENOMEM;
s->range_table_list = range_table_list;
@@ -420,67 +422,65 @@ static int serial2002_setup_subdevs(struct comedi_device *dev)
serial2002_tty_setspeed(devpriv->tty, devpriv->speed);
serial2002_poll_channel(devpriv->tty, 31);
while (1) {
- struct serial_data data;
+ struct serial_data data = serial2002_read(devpriv->tty, 1000);
+ int kind = S2002_CFG_KIND(data.value);
+ int channel = S2002_CFG_CHAN(data.value);
+ int range = S2002_CFG_BASE(data.value);
+ int cmd = S2002_CFG_CMD(data.value);
- data = serial2002_read(devpriv->tty, 1000);
if (data.kind != is_channel || data.index != 31 ||
- S2002_CFG_KIND(data.value) == S2002_CFG_KIND_INVALID) {
+ kind == 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 S2002_CFG_KIND_DIGITAL_OUT:
- cfg = do_cfg;
- break;
- case S2002_CFG_KIND_ANALOG_IN:
- cfg = ai_cfg;
- break;
- case S2002_CFG_KIND_ANALOG_OUT:
- cfg = ao_cfg;
- break;
- case S2002_CFG_KIND_ENCODER_IN:
- cfg = ai_cfg;
- break;
- default:
- cfg = NULL;
- break;
- }
- if (!cfg)
- continue; /* unknown kind, skip it */
+ switch (kind) {
+ case S2002_CFG_KIND_DIGITAL_IN:
+ cfg = di_cfg;
+ break;
+ case S2002_CFG_KIND_DIGITAL_OUT:
+ cfg = do_cfg;
+ break;
+ case S2002_CFG_KIND_ANALOG_IN:
+ cfg = ai_cfg;
+ break;
+ case S2002_CFG_KIND_ANALOG_OUT:
+ cfg = ao_cfg;
+ break;
+ case S2002_CFG_KIND_ENCODER_IN:
+ cfg = ai_cfg;
+ break;
+ default:
+ cfg = NULL;
+ break;
+ }
+ if (!cfg)
+ continue; /* unknown kind, skip it */
- cfg[channel].kind = S2002_CFG_KIND(data.value);
+ cfg[channel].kind = kind;
- switch (S2002_CFG_CMD(data.value)) {
- case S2002_CFG_CMD_BITS:
- cfg[channel].bits = S2002_CFG_BITS(data.value);
+ switch (cmd) {
+ 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 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;
+ case 1:
+ range *= 1000;
+ break;
+ case 2:
+ range *= 1;
break;
}
+ if (S2002_CFG_SIGN(data.value))
+ range = -range;
+ if (cmd == S2002_CFG_CMD_MIN)
+ cfg[channel].min = range;
+ else
+ cfg[channel].max = range;
+ break;
}
}
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index 3bfa221faf4d..a118678c24a1 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -75,9 +75,6 @@ Configuration Options:
#include "comedi_fc.h"
/* Imaginary registers for the imaginary board */
-
-#define SKEL_SIZE 0
-
#define SKEL_START_AI_CONV 0
#define SKEL_AI_READ 0
@@ -129,7 +126,7 @@ struct skel_private {
* convert ns nanoseconds to a counter value suitable for programming
* the device. Also, it should adjust ns so that it cooresponds to
* the actual time that the device will use. */
-static int skel_ns_to_timer(unsigned int *ns, int round)
+static int skel_ns_to_timer(unsigned int *ns, unsigned int flags)
{
/* trivial timer */
/* if your timing is done through two cascaded timers, the
@@ -287,12 +284,12 @@ static int skel_ai_cmdtest(struct comedi_device *dev,
if (cmd->scan_begin_src == TRIG_TIMER) {
arg = cmd->scan_begin_arg;
- skel_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ skel_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
}
if (cmd->convert_src == TRIG_TIMER) {
arg = cmd->convert_arg;
- skel_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+ skel_ns_to_timer(&arg, cmd->flags);
err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
if (cmd->scan_begin_src == TRIG_TIMER) {
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
index adf7cb7086cc..7c2276a086ac 100644
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -43,7 +43,6 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5),
#include <linux/delay.h>
#include "../comedidev.h"
-#define DRIVER_NAME "unioxx5"
#define UNIOXX5_SIZE 0x10
#define UNIOXX5_SUBDEV_BASE 0xA000 /* base addr of first subdev */
#define UNIOXX5_SUBDEV_ODDS 0x400
@@ -496,7 +495,7 @@ static void unioxx5_detach(struct comedi_device *dev)
}
static struct comedi_driver unioxx5_driver = {
- .driver_name = DRIVER_NAME,
+ .driver_name = "unioxx5",
.module = THIS_MODULE,
.attach = unioxx5_attach,
.detach = unioxx5_detach,
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 5f65e4213c6e..053bc5090530 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1327,13 +1327,13 @@ static int usbdux_pwm_period(struct comedi_device *dev,
struct usbdux_private *devpriv = dev->private;
int fx2delay = 255;
- if (period < MIN_PWM_PERIOD) {
+ if (period < MIN_PWM_PERIOD)
return -EAGAIN;
- } else {
- fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
- if (fx2delay > 255)
- return -EAGAIN;
- }
+
+ fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
+ if (fx2delay > 255)
+ return -EAGAIN;
+
devpriv->pwm_delay = fx2delay;
devpriv->pwm_period = period;
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 85f9dcf59403..f85818dd5e11 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -33,8 +33,6 @@
* udev coldplug problem
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -275,8 +273,9 @@ static void usbduxfast_ai_interrupt(struct urb *urb)
return;
default:
- pr_err("non-zero urb status received in ai intr context: %d\n",
- urb->status);
+ dev_err(dev->class_dev,
+ "non-zero urb status received in ai intr context: %d\n",
+ urb->status);
async->events |= COMEDI_CB_EOA;
async->events |= COMEDI_CB_ERROR;
comedi_event(dev, s);
@@ -746,6 +745,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev,
0x00, (0xff - 0x02) & rngmask, 0x00);
usbduxfast_cmd_data(dev, 6, 0x01, 0x00, rngmask, 0x00);
+ break;
case 16:
if (CR_RANGE(cmd->chanlist[0]) > 0)
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index ccc3ef7ba55c..94a09c16de8b 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -136,7 +136,7 @@
static const struct comedi_lrange usbduxsigma_ai_range = {
1, {
- BIP_RANGE(2.65 / 2.0)
+ BIP_RANGE(2.5 * 0x800000 / 0x780000 / 2.0)
}
};
@@ -1176,13 +1176,13 @@ static int usbduxsigma_pwm_period(struct comedi_device *dev,
struct usbduxsigma_private *devpriv = dev->private;
int fx2delay = 255;
- if (period < MIN_PWM_PERIOD) {
+ if (period < MIN_PWM_PERIOD)
return -EAGAIN;
- } else {
- fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
- if (fx2delay > 255)
- return -EAGAIN;
- }
+
+ fx2delay = (period / (6 * 512 * 1000 / 33)) - 6;
+ if (fx2delay > 255)
+ return -EAGAIN;
+
devpriv->pwm_delay = fx2delay;
devpriv->pwm_period = period;
return 0;
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 0adf3cffddb0..831c3b702899 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -959,5 +959,4 @@ module_comedi_usb_driver(vmk80xx_driver, vmk80xx_usb_driver);
MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
-MODULE_VERSION("0.8.01");
MODULE_LICENSE("GPL");