summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 18:36:12 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 18:36:12 -0700
commit53ee983378ff23e8f3ff95ecf99dea7c6c221900 (patch)
tree85e09b2bf6317a155f1405be0d45c69051b6e041 /drivers/staging/comedi/drivers
parent29b88e23a9212136d39b0161a39afe587d0170a5 (diff)
parentb9aaea39f65e242303103b5283abeaefd8e538a4 (diff)
Merge tag 'staging-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH: "Here's the big pull request for the staging driver tree for 3.17-rc1. Lots of things in here, over 2000 patches, but the best part is this: 1480 files changed, 39070 insertions(+), 254659 deletions(-) Thanks to the great work of Kristina Martšenko, 14 different staging drivers have been removed from the tree as they were obsolete and no one was willing to work on cleaning them up. Other than the driver removals, loads of cleanups are in here (comedi, lustre, etc.) as well as the usual IIO driver updates and additions. All of this has been in the linux-next tree for a while" * tag 'staging-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (2199 commits) staging: comedi: addi_apci_1564: remove diagnostic interrupt support code staging: comedi: addi_apci_1564: add subdevice to check diagnostic status staging: wlan-ng: coding style problem fix staging: wlan-ng: fixing coding style problems staging: comedi: ii_pci20kc: request and ioremap memory staging: lustre: bitwise vs logical typo staging: dgnc: Remove unneeded dgnc_trace.c and dgnc_trace.h staging: dgnc: rephrase comment staging: comedi: ni_tio: remove some dead code staging: rtl8723au: Fix static symbol sparse warning staging: rtl8723au: usb_dvobj_init(): Remove unused variable 'pdev_desc' staging: rtl8723au: Do not duplicate kernel provided USB macros staging: rtl8723au: Remove never set struct pwrctrl_priv.bHWPowerdown staging: rtl8723au: Remove two never set variables staging: rtl8723au: RSSI_test is never set staging:r8190: coding style: Fixed checkpatch reported Error staging:r8180: coding style: Fixed too long lines staging:r8180: coding style: Fixed commenting style staging: lustre: ptlrpc: lproc_ptlrpc.c - fix dereferenceing user space buffer staging: lustre: ldlm: ldlm_resource.c - fix dereferenceing user space buffer ...
Diffstat (limited to 'drivers/staging/comedi/drivers')
-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
115 files changed, 8587 insertions, 10222 deletions
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");