in drivers/ni_pcidio.c [617:729]
static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct nidio96_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
/* XXX configure ports for input */
writel(0x0000, dev->mmio + PORT_PIN_DIRECTIONS(0));
if (1) {
/* enable fifos A B C D */
writeb(0x0f, dev->mmio + DATA_PATH);
/* set transfer width a 32 bits */
writeb(TRANSFER_WIDTH(0) | TRANSFER_LENGTH(0),
dev->mmio + TRANSFER_SIZE_CONTROL);
} else {
writeb(0x03, dev->mmio + DATA_PATH);
writeb(TRANSFER_WIDTH(3) | TRANSFER_LENGTH(0),
dev->mmio + TRANSFER_SIZE_CONTROL);
}
/* protocol configuration */
if (cmd->scan_begin_src == TRIG_TIMER) {
/* page 4-5, "input with internal REQs" */
writeb(0, dev->mmio + OP_MODE);
writeb(0x00, dev->mmio + CLOCK_REG);
writeb(1, dev->mmio + SEQUENCE);
writeb(0x04, dev->mmio + REQ_REG);
writeb(4, dev->mmio + BLOCK_MODE);
writeb(3, dev->mmio + LINE_POLARITIES);
writeb(0xc0, dev->mmio + ACK_SER);
writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
CMDF_ROUND_NEAREST),
dev->mmio + START_DELAY);
writeb(1, dev->mmio + REQ_DELAY);
writeb(1, dev->mmio + REQ_NOT_DELAY);
writeb(1, dev->mmio + ACK_DELAY);
writeb(0x0b, dev->mmio + ACK_NOT_DELAY);
writeb(0x01, dev->mmio + DATA_1_DELAY);
/*
* manual, page 4-5:
* CLOCK_SPEED comment is incorrectly listed on DAQ_OPTIONS
*/
writew(0, dev->mmio + CLOCK_SPEED);
writeb(0, dev->mmio + DAQ_OPTIONS);
} else {
/* TRIG_EXT */
/* page 4-5, "input with external REQs" */
writeb(0, dev->mmio + OP_MODE);
writeb(0x00, dev->mmio + CLOCK_REG);
writeb(0, dev->mmio + SEQUENCE);
writeb(0x00, dev->mmio + REQ_REG);
writeb(4, dev->mmio + BLOCK_MODE);
if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */
writeb(0, dev->mmio + LINE_POLARITIES);
else /* Trailing Edge */
writeb(2, dev->mmio + LINE_POLARITIES);
writeb(0x00, dev->mmio + ACK_SER);
writel(1, dev->mmio + START_DELAY);
writeb(1, dev->mmio + REQ_DELAY);
writeb(1, dev->mmio + REQ_NOT_DELAY);
writeb(1, dev->mmio + ACK_DELAY);
writeb(0x0C, dev->mmio + ACK_NOT_DELAY);
writeb(0x10, dev->mmio + DATA_1_DELAY);
writew(0, dev->mmio + CLOCK_SPEED);
writeb(0x60, dev->mmio + DAQ_OPTIONS);
}
if (cmd->stop_src == TRIG_COUNT) {
writel(cmd->stop_arg,
dev->mmio + TRANSFER_COUNT);
} else {
/* XXX */
}
#ifdef USE_DMA
writeb(CLEAR_PRIMARY_TC | CLEAR_SECONDARY_TC,
dev->mmio + GROUP_1_FIRST_CLEAR);
{
int retval = setup_mite_dma(dev, s);
if (retval)
return retval;
}
#else
writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP1);
#endif
writeb(0x00, dev->mmio + DMA_LINE_CONTROL_GROUP2);
/* clear and enable interrupts */
writeb(0xff, dev->mmio + GROUP_1_FIRST_CLEAR);
/* writeb(CLEAR_EXPIRED, dev->mmio+GROUP_1_SECOND_CLEAR); */
writeb(INT_EN, dev->mmio + INTERRUPT_CONTROL);
writeb(0x03, dev->mmio + MASTER_DMA_AND_INTERRUPT_CONTROL);
if (cmd->stop_src == TRIG_NONE) {
devpriv->OP_MODEBits = DATA_LATCHING(0) | RUN_MODE(7);
} else { /* TRIG_TIMER */
devpriv->OP_MODEBits = NUMBERED | RUN_MODE(7);
}
if (cmd->start_src == TRIG_NOW) {
/* start */
writeb(devpriv->OP_MODEBits, dev->mmio + OP_MODE);
s->async->inttrig = NULL;
} else {
/* TRIG_INT */
s->async->inttrig = ni_pcidio_inttrig;
}
return 0;
}