#define PCL816_RANGE_REG 0x09
#define PCL816_MUX_REG 0x0b
#define PCL816_MUX_SCAN(_first, _last) (((_last) << 4) | (_first))
+#define PCL816_CTRL_REG 0x0c
+#define PCL816_CTRL_DISABLE_TRIG (0 << 0)
+#define PCL816_CTRL_SOFT_TRIG (1 << 0)
+#define PCL816_CTRL_PACER_TRIG (1 << 1)
+#define PCL816_CTRL_EXT_TRIG (1 << 2)
+#define PCL816_CTRL_POE (1 << 3)
+#define PCL816_CTRL_DMAEN (1 << 4)
+#define PCL816_CTRL_INTEN (1 << 5)
+#define PCL816_CTRL_DMASRC_SLOT0 (0 << 6)
+#define PCL816_CTRL_DMASRC_SLOT1 (1 << 6)
+#define PCL816_CTRL_DMASRC_SLOT2 (2 << 6)
#define PCL816_STATUS_REG 0x0d
#define PCL816_STATUS_NEXT_CHAN_MASK (0xf << 0)
#define PCL816_STATUS_INTSRC_MASK (3 << 4)
/* W: clear INT request */
#define PCL816_CLRINT 10
-/* R/W: operation control register */
-#define PCL816_CONTROL 12
-
#define MAGIC_DMA_WORD 0x5a5a
{
struct pcl816_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
- unsigned int dmairq;
+ unsigned int ctrl;
unsigned int seglen;
if (devpriv->ai_cmd_running)
devpriv->ai_poll_ptr = 0;
devpriv->ai_cmd_canceled = 0;
- if (devpriv->dma)
- pcl816_ai_setup_dma(dev, s);
+ pcl816_ai_setup_dma(dev, s);
pcl816_start_pacer(dev, true);
- dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
-
- switch (cmd->convert_src) {
- case TRIG_TIMER:
- /* Pacer+IRQ+DMA */
- outb(0x32, dev->iobase + PCL816_CONTROL);
- /* write irq and DMA to card */
- outb(dmairq, dev->iobase + PCL816_STATUS_REG);
- break;
-
- default:
- /* Ext trig+IRQ+DMA */
- outb(0x34, dev->iobase + PCL816_CONTROL);
+ ctrl = PCL816_CTRL_INTEN | PCL816_CTRL_DMAEN | PCL816_CTRL_DMASRC_SLOT0;
+ if (cmd->convert_src == TRIG_TIMER)
+ ctrl |= PCL816_CTRL_PACER_TRIG;
+ else /* TRIG_EXT */
+ ctrl |= PCL816_CTRL_EXT_TRIG;
- /* write irq to card */
- outb(dmairq, dev->iobase + PCL816_STATUS_REG);
- break;
- }
+ outb(ctrl, dev->iobase + PCL816_CTRL_REG);
+ outb((devpriv->dma << 4) | dev->irq, dev->iobase + PCL816_STATUS_REG);
return 0;
}
unsigned long flags;
unsigned int top1, top2, i;
- if (!devpriv->dma)
- return 0; /* poll is valid only for DMA transfer */
-
spin_lock_irqsave(&dev->spinlock, flags);
for (i = 0; i < 20; i++) {
if (!devpriv->ai_cmd_running)
return 0;
- disable_dma(devpriv->dma);
- outb(inb(dev->iobase + PCL816_CONTROL) & 0x73,
- dev->iobase + PCL816_CONTROL); /* Stop A/D */
- udelay(1);
- outb(0, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ outb(PCL816_CTRL_DISABLE_TRIG, dev->iobase + PCL816_CTRL_REG);
+ pcl816_ai_clear_eoc(dev);
/* Stop pacer */
i8254_set_mode(dev->iobase + PCL816_TIMER_BASE, 0,
i8254_set_mode(dev->iobase + PCL816_TIMER_BASE, 0,
1, I8254_MODE0 | I8254_BINARY);
- pcl816_ai_soft_trig(dev);
- pcl816_ai_get_sample(dev, s);
-
- pcl816_ai_clear_eoc(dev);
-
- /* Stop A/D */
- outb(0, dev->iobase + PCL816_CONTROL);
devpriv->ai_cmd_running = 0;
devpriv->ai_cmd_canceled = 1;
int ret = 0;
int i;
- /* software trigger, DMA and INT off */
- outb(0, dev->iobase + PCL816_CONTROL);
+ outb(PCL816_CTRL_SOFT_TRIG, dev->iobase + PCL816_CTRL_REG);
pcl816_ai_set_chan_range(dev, chan, range);
pcl816_ai_set_chan_scan(dev, chan, chan);
data[i] = pcl816_ai_get_sample(dev, s);
}
+ outb(PCL816_CTRL_DISABLE_TRIG, dev->iobase + PCL816_CTRL_REG);
pcl816_ai_clear_eoc(dev);
return ret ? ret : insn->n;
{
unsigned long timer_base = dev->iobase + PCL816_TIMER_BASE;
- outb(0, dev->iobase + PCL816_CONTROL);
+ outb(PCL816_CTRL_DISABLE_TRIG, dev->iobase + PCL816_CTRL_REG);
pcl816_ai_set_chan_range(dev, 0, 0);
pcl816_ai_clear_eoc(dev);