#include "../comedi_pcmcia.h"
-struct daqp_private {
- int stop;
-
- enum { semaphore, buffer } interrupt_mode;
-
- struct completion eos;
-};
-
-/* The DAQP communicates with the system through a 16 byte I/O window. */
-
-#define DAQP_FIFO_SIZE 4096
-
-#define DAQP_FIFO 0
-#define DAQP_SCANLIST 1
-#define DAQP_CONTROL 2
-#define DAQP_STATUS 2
-#define DAQP_DIGITAL_IO 3
-#define DAQP_PACER_LOW 4
-#define DAQP_PACER_MID 5
-#define DAQP_PACER_HIGH 6
-#define DAQP_COMMAND 7
-#define DAQP_DA 8
-#define DAQP_TIMER 10
-#define DAQP_AUX 15
+/*
+ * Register I/O map
+ *
+ * The D/A and timer registers can be accessed with 16-bit or 8-bit I/O
+ * instructions. All other registers can only use 8-bit instructions.
+ *
+ * The FIFO and scanlist registers require two 8-bit instructions to
+ * access the 16-bit data. Data is transferred LSB then MSB.
+ */
+#define DAQP_AI_FIFO_REG 0x00
+#define DAQP_SCANLIST_REG 0x01
+#define DAQP_CTRL_REG 0x02
+#define DAQP_STATUS_REG 0x02
+#define DAQP_DI_REG 0x03
+#define DAQP_DO_REG 0x03
+#define DAQP_PACER_LOW_REG 0x04
+#define DAQP_PACER_MID_REG 0x05
+#define DAQP_PACER_HIGH_REG 0x06
+#define DAQP_CMD_REG 0x07
+#define DAQP_AO_REG 0x08
+#define DAQP_TIMER_REG 0x0a
+#define DAQP_AUX_REG 0x0f
#define DAQP_SCANLIST_DIFFERENTIAL 0x4000
#define DAQP_SCANLIST_GAIN(x) ((x) << 12)
#define DAQP_AUX_FIFO_NEARFULL 0x02
#define DAQP_AUX_FIFO_EMPTY 0x01
+#define DAQP_FIFO_SIZE 4096
+
+struct daqp_private {
+ int stop;
+
+ enum { semaphore, buffer } interrupt_mode;
+
+ struct completion eos;
+};
+
static const struct comedi_lrange range_daqp_ai = {
4, {
BIP_RANGE(10),
* require multiple reads on the status register to achieve this).
*/
while (--loops) {
- status = inb(dev->iobase + DAQP_STATUS);
+ status = inb(dev->iobase + DAQP_STATUS_REG);
if ((status & DAQP_STATUS_EVENTS) == 0)
return 0;
}
if (devpriv->stop)
return -EIO;
- outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
+ outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_CMD_REG);
/* flush any linguring data in FIFO - superfluous here */
- /* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
+ /* outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_CMD_REG); */
devpriv->interrupt_mode = semaphore;
* Get a two's complement sample from the FIFO and
* return the munged offset binary value.
*/
- val = inb(dev->iobase + DAQP_FIFO);
- val |= inb(dev->iobase + DAQP_FIFO) << 8;
+ val = inb(dev->iobase + DAQP_AI_FIFO_REG);
+ val |= inb(dev->iobase + DAQP_AI_FIFO_REG) << 8;
return comedi_offset_munge(s, val);
}
break;
case buffer:
- while (!((status = inb(dev->iobase + DAQP_STATUS))
+ while (!((status = inb(dev->iobase + DAQP_STATUS_REG))
& DAQP_STATUS_FIFO_EMPTY)) {
unsigned short data;
if (start)
val |= DAQP_SCANLIST_START;
- outb(val & 0xff, dev->iobase + DAQP_SCANLIST);
- outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST);
+ outb(val & 0xff, dev->iobase + DAQP_SCANLIST_REG);
+ outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST_REG);
}
/* One-shot analog data acquisition routine */
/* Stop any running conversion */
daqp_ai_cancel(dev, s);
- outb(0, dev->iobase + DAQP_AUX);
+ outb(0, dev->iobase + DAQP_AUX_REG);
/* Reset scan list queue */
- outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+ outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_CMD_REG);
/* Program one scan list entry */
daqp_ai_set_one_scanlist_entry(dev, insn->chanspec, 1);
/* Reset data FIFO (see page 28 of DAQP User's Manual) */
- outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+ outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_CMD_REG);
/* Set trigger */
outb(DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL |
DAQP_CONTROL_PACER_CLK_100KHZ | DAQP_CONTROL_EOS_INT_ENABLE,
- dev->iobase + DAQP_CONTROL);
+ dev->iobase + DAQP_CTRL_REG);
ret = daqp_clear_events(dev, 10000);
if (ret)
for (i = 0; i < insn->n; i++) {
/* Start conversion */
outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
- dev->iobase + DAQP_COMMAND);
+ dev->iobase + DAQP_CMD_REG);
/* Wait for interrupt service routine to unblock completion */
/* Maybe could use a timeout here, but it's interruptible */
/* Stop any running conversion */
daqp_ai_cancel(dev, s);
- outb(0, dev->iobase + DAQP_AUX);
+ outb(0, dev->iobase + DAQP_AUX_REG);
/* Reset scan list queue */
- outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+ outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_CMD_REG);
/* Program pacer clock
*
if (cmd->convert_src == TRIG_TIMER) {
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);
+ outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW_REG);
+ outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID_REG);
+ outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH_REG);
scanlist_start_on_every_entry = 1;
} else {
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);
+ outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW_REG);
+ outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID_REG);
+ outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH_REG);
scanlist_start_on_every_entry = 0;
}
/* Reset data FIFO (see page 28 of DAQP User's Manual) */
- outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+ outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_CMD_REG);
/* Set FIFO threshold. First two bytes are near-empty
* threshold, which is unused; next two bytes are near-full
* when the interrupt is to happen.
*/
- outb(0x00, dev->iobase + DAQP_FIFO);
- outb(0x00, dev->iobase + DAQP_FIFO);
+ outb(0x00, dev->iobase + DAQP_AI_FIFO_REG);
+ outb(0x00, dev->iobase + DAQP_AI_FIFO_REG);
- outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
- outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
+ outb((DAQP_FIFO_SIZE - threshold) & 0xff,
+ dev->iobase + DAQP_AI_FIFO_REG);
+ outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_AI_FIFO_REG);
/* Set trigger */
outb(DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL |
DAQP_CONTROL_PACER_CLK_5MHZ | DAQP_CONTROL_FIFO_INT_ENABLE,
- dev->iobase + DAQP_CONTROL);
+ dev->iobase + DAQP_CTRL_REG);
ret = daqp_clear_events(dev, 100);
if (ret)
/* Start conversion */
outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
- dev->iobase + DAQP_COMMAND);
+ dev->iobase + DAQP_CMD_REG);
return 0;
}
{
unsigned int status;
- status = inb(dev->iobase + DAQP_AUX);
+ status = inb(dev->iobase + DAQP_AUX_REG);
if ((status & DAQP_AUX_DA_BUFFER) == 0)
return 0;
return -EBUSY;
return -EIO;
/* Make sure D/A update mode is direct update */
- outb(0, dev->iobase + DAQP_AUX);
+ outb(0, dev->iobase + DAQP_AUX_REG);
for (i = 0; i > insn->n; i++) {
unsigned val = data[i];
/* write the two's complement value to the channel */
outw((chan << 12) | comedi_offset_munge(s, val),
- dev->iobase + DAQP_DA);
+ dev->iobase + DAQP_AO_REG);
s->readback[chan] = val;
}
if (devpriv->stop)
return -EIO;
- data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
+ data[0] = inb(dev->iobase + DAQP_DI_REG);
return insn->n;
}
return -EIO;
if (comedi_dio_update_state(s, data))
- outb(s->state, dev->iobase + DAQP_DIGITAL_IO);
+ outb(s->state, dev->iobase + DAQP_DO_REG);
data[1] = s->state;