2 * comedi/drivers/rtd520.c
3 * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
21 * Description: Real Time Devices PCI4520/DM7520
22 * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8,
23 * PCI4520 (PCI4520), PCI4520-8
24 * Author: Dan Christian
25 * Status: Works. Only tested on DM7520-8. Not SMP safe.
27 * Configuration options: not applicable, uses PCI auto config
31 * Created by Dan Christian, NASA Ames Research Center.
33 * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
35 * 8/16 12 bit ADC with FIFO and channel gain table
36 * 8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
37 * 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
38 * 2 12 bit DACs with FIFOs
42 * timers: ADC sample, pacer, burst, about, delay, DA1, DA2
44 * 3 user timer/counters (8254)
47 * The DM7520 has slightly fewer features (fewer gain steps).
49 * These boards can support external multiplexors and multi-board
50 * synchronization, but this driver doesn't support that.
52 * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
53 * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
54 * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
55 * Call them and ask for the register level manual.
56 * PCI chip: http://www.plxtech.com/products/io/pci9080
59 * This board is memory mapped. There is some IO stuff, but it isn't needed.
61 * I use a pretty loose naming style within the driver (rtd_blah).
62 * All externally visible names should be rtd520_blah.
63 * I use camelCase for structures (and inside them).
64 * I may also use upper CamelCase for function names (old habit).
66 * This board is somewhat related to the RTD PCI4400 board.
68 * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
69 * das1800, since they have the best documented code. Driver cb_pcidas64.c
70 * uses the same DMA controller.
72 * As far as I can tell, the About interrupt doesn't work if Sample is
73 * also enabled. It turns out that About really isn't needed, since
74 * we always count down samples read.
76 * There was some timer/counter code, but it didn't follow the right API.
82 * Analog-In supports instruction and command mode.
84 * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
85 * (single channel, 64K read buffer). I get random system lockups when
86 * using DMA with ALI-15xx based systems. I haven't been able to test
87 * any other chipsets. The lockups happen soon after the start of an
88 * acquistion, not in the middle of a long run.
90 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
91 * (with a 256K read buffer).
93 * Digital-IO and Analog-Out only support instruction mode.
96 #include <linux/module.h>
97 #include <linux/delay.h>
98 #include <linux/interrupt.h>
100 #include "../comedi_pci.h"
105 * Local Address Space 0 Offsets
107 #define LAS0_USER_IO 0x0008 /* User I/O */
108 #define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
109 #define FS_DAC1_NOT_EMPTY BIT(0) /* DAC1 FIFO not empty */
110 #define FS_DAC1_HEMPTY BIT(1) /* DAC1 FIFO half empty */
111 #define FS_DAC1_NOT_FULL BIT(2) /* DAC1 FIFO not full */
112 #define FS_DAC2_NOT_EMPTY BIT(4) /* DAC2 FIFO not empty */
113 #define FS_DAC2_HEMPTY BIT(5) /* DAC2 FIFO half empty */
114 #define FS_DAC2_NOT_FULL BIT(6) /* DAC2 FIFO not full */
115 #define FS_ADC_NOT_EMPTY BIT(8) /* ADC FIFO not empty */
116 #define FS_ADC_HEMPTY BIT(9) /* ADC FIFO half empty */
117 #define FS_ADC_NOT_FULL BIT(10) /* ADC FIFO not full */
118 #define FS_DIN_NOT_EMPTY BIT(12) /* DIN FIFO not empty */
119 #define FS_DIN_HEMPTY BIT(13) /* DIN FIFO half empty */
120 #define FS_DIN_NOT_FULL BIT(14) /* DIN FIFO not full */
121 #define LAS0_UPDATE_DAC(x) (0x0014 + ((x) * 0x4)) /* D/Ax Update (w) */
122 #define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
123 #define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
124 #define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
125 #define LAS0_IT 0x0030 /* Interrupt Status/Enable */
126 #define IRQM_ADC_FIFO_WRITE BIT(0) /* ADC FIFO Write */
127 #define IRQM_CGT_RESET BIT(1) /* Reset CGT */
128 #define IRQM_CGT_PAUSE BIT(3) /* Pause CGT */
129 #define IRQM_ADC_ABOUT_CNT BIT(4) /* About Counter out */
130 #define IRQM_ADC_DELAY_CNT BIT(5) /* Delay Counter out */
131 #define IRQM_ADC_SAMPLE_CNT BIT(6) /* ADC Sample Counter */
132 #define IRQM_DAC1_UCNT BIT(7) /* DAC1 Update Counter */
133 #define IRQM_DAC2_UCNT BIT(8) /* DAC2 Update Counter */
134 #define IRQM_UTC1 BIT(9) /* User TC1 out */
135 #define IRQM_UTC1_INV BIT(10) /* User TC1 out, inverted */
136 #define IRQM_UTC2 BIT(11) /* User TC2 out */
137 #define IRQM_DIGITAL_IT BIT(12) /* Digital Interrupt */
138 #define IRQM_EXTERNAL_IT BIT(13) /* External Interrupt */
139 #define IRQM_ETRIG_RISING BIT(14) /* Ext Trigger rising-edge */
140 #define IRQM_ETRIG_FALLING BIT(15) /* Ext Trigger falling-edge */
141 #define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
142 #define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
143 #define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
144 #define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
145 #define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
146 #define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
147 #define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
148 #define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
149 #define LAS0_ACNT 0x0058 /* About counter (16 bit) */
150 #define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
151 #define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
152 #define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
153 #define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
154 #define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
155 #define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
156 #define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
157 #define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
158 #define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
159 #define LAS0_BOARD_RESET 0x0100 /* Board reset */
160 #define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
161 #define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
162 #define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
163 #define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
164 #define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
165 #define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
166 #define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
167 #define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
168 #define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
169 #define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
170 #define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
171 #define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
172 #define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
173 #define LAS0_CG_DATA 0x0138 /* Digital Table Write */
174 #define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
175 #define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
176 #define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
177 #define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
178 #define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
179 #define LAS0_DAC_CTRL(x) (0x0150 + ((x) * 0x14)) /* D/Ax type/range */
180 #define LAS0_DAC_SRC(x) (0x0154 + ((x) * 0x14)) /* D/Ax update source */
181 #define LAS0_DAC_CYCLE(x) (0x0158 + ((x) * 0x14)) /* D/Ax cycle mode */
182 #define LAS0_DAC_RESET(x) (0x015c + ((x) * 0x14)) /* D/Ax FIFO reset */
183 #define LAS0_DAC_FIFO_CLEAR(x) (0x0160 + ((x) * 0x14)) /* D/Ax FIFO clear */
184 #define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
185 #define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
186 #define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
187 #define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
188 #define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
189 #define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
190 #define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
191 #define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
192 #define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
193 #define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
194 #define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
195 #define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
196 #define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
197 #define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
198 #define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
199 #define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
200 #define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
201 #define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
202 #define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
203 #define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
206 * Local Address Space 1 Offsets
208 #define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
209 #define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
210 #define LAS1_DAC_FIFO(x) (0x0008 + ((x) * 0x4)) /* D/Ax FIFO (16bit) */
213 * Driver specific stuff (tunable)
217 * We really only need 2 buffers. More than that means being much
218 * smarter about knowing which ones are full.
220 #define DMA_CHAIN_COUNT 2 /* max DMA segments/buffers in a ring (min 2) */
222 /* Target period for periodic transfers. This sets the user read latency. */
223 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
224 /* If this is too low, efficiency is poor */
225 #define TRANS_TARGET_PERIOD 10000000 /* 10 ms (in nanoseconds) */
227 /* Set a practical limit on how long a list to support (affects memory use) */
228 /* The board support a channel list up to the FIFO length (1K or 8K) */
229 #define RTD_MAX_CHANLIST 128 /* max channel list that we allow */
232 * Board specific stuff
235 #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
236 #define RTD_CLOCK_BASE 125 /* clock period in ns */
238 /* Note: these speed are slower than the spec, but fit the counter resolution*/
239 #define RTD_MAX_SPEED 1625 /* when sampling, in nanoseconds */
240 /* max speed if we don't have to wait for settling */
241 #define RTD_MAX_SPEED_1 875 /* if single channel, in nanoseconds */
243 #define RTD_MIN_SPEED 2097151875 /* (24bit counter) in nanoseconds */
244 /* min speed when only 1 channel (no burst counter) */
245 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
247 /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */
248 #define DMA_MODE_BITS (\
249 PLX_LOCAL_BUS_16_WIDE_BITS \
250 | PLX_DMA_EN_READYIN_BIT \
251 | PLX_DMA_LOCAL_BURST_EN_BIT \
253 | PLX_DMA_INTR_PCI_BIT \
254 | PLX_LOCAL_ADDR_CONST_BIT \
255 | PLX_DEMAND_MODE_BIT)
257 #define DMA_TRANSFER_BITS (\
258 /* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \
259 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
260 /* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
263 * Comedi specific stuff
267 * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
269 static const struct comedi_lrange rtd_ai_7520_range = {
271 /* +-5V input range gain steps */
278 /* +-10V input range gain steps */
283 BIP_RANGE(10.0 / 16),
284 BIP_RANGE(10.0 / 32),
285 /* +10V input range gain steps */
290 UNI_RANGE(10.0 / 16),
291 UNI_RANGE(10.0 / 32),
295 /* PCI4520 has two more gains (6 more entries) */
296 static const struct comedi_lrange rtd_ai_4520_range = {
298 /* +-5V input range gain steps */
306 BIP_RANGE(5.0 / 128),
307 /* +-10V input range gain steps */
312 BIP_RANGE(10.0 / 16),
313 BIP_RANGE(10.0 / 32),
314 BIP_RANGE(10.0 / 64),
315 BIP_RANGE(10.0 / 128),
316 /* +10V input range gain steps */
321 UNI_RANGE(10.0 / 16),
322 UNI_RANGE(10.0 / 32),
323 UNI_RANGE(10.0 / 64),
324 UNI_RANGE(10.0 / 128),
328 /* Table order matches range values */
329 static const struct comedi_lrange rtd_ao_range = {
343 struct rtd_boardinfo {
345 int range_bip10; /* start of +-10V range */
346 int range_uni10; /* start of +10V range */
347 const struct comedi_lrange *ai_range;
350 static const struct rtd_boardinfo rtd520_boards[] = {
355 .ai_range = &rtd_ai_7520_range,
361 .ai_range = &rtd_ai_4520_range,
366 /* memory mapped board structures */
370 long ai_count; /* total transfer size (samples) */
371 int xfer_count; /* # to transfer data. 0->1/2FIFO */
372 int flags; /* flag event modes */
376 /* bit defines for "flags" */
377 #define SEND_EOS 0x01 /* send End Of Scan events */
378 #define DMA0_ACTIVE 0x02 /* DMA0 is active */
379 #define DMA1_ACTIVE 0x04 /* DMA1 is active */
382 * Given a desired period and the clock period (both in ns), return the
383 * proper counter value (divider-1). Sets the original period to be the
385 * Note: you have to check if the value is larger than the counter range!
387 static int rtd_ns_to_timer_base(unsigned int *nanosec,
388 unsigned int flags, int base)
392 switch (flags & CMDF_ROUND_MASK) {
393 case CMDF_ROUND_NEAREST:
395 divider = DIV_ROUND_CLOSEST(*nanosec, base);
397 case CMDF_ROUND_DOWN:
398 divider = (*nanosec) / base;
401 divider = DIV_ROUND_UP(*nanosec, base);
405 divider = 2; /* min is divide by 2 */
408 * Note: we don't check for max, because different timers
409 * have different ranges
412 *nanosec = base * divider;
413 return divider - 1; /* countdown is divisor+1 */
417 * Given a desired period (in ns), return the proper counter value
418 * (divider-1) for the internal clock. Sets the original period to
421 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
423 return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
426 /* Convert a single comedi channel-gain entry to a RTD520 table entry */
427 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
428 unsigned int chanspec, int index)
430 const struct rtd_boardinfo *board = dev->board_ptr;
431 unsigned int chan = CR_CHAN(chanspec);
432 unsigned int range = CR_RANGE(chanspec);
433 unsigned int aref = CR_AREF(chanspec);
434 unsigned short r = 0;
438 /* Note: we also setup the channel list bipolar flag array */
439 if (range < board->range_bip10) {
442 r |= (range & 0x7) << 4;
443 } else if (range < board->range_uni10) {
446 r |= ((range - board->range_bip10) & 0x7) << 4;
450 r |= ((range - board->range_uni10) & 0x7) << 4;
454 case AREF_GROUND: /* on-board ground */
458 r |= 0x80; /* ref external analog common */
462 r |= 0x400; /* differential inputs */
465 case AREF_OTHER: /* ??? */
471 /* Setup the channel-gain table from a comedi list */
472 static void rtd_load_channelgain_list(struct comedi_device *dev,
473 unsigned int n_chan, unsigned int *list)
475 if (n_chan > 1) { /* setup channel gain table */
478 writel(0, dev->mmio + LAS0_CGT_CLEAR);
479 writel(1, dev->mmio + LAS0_CGT_ENABLE);
480 for (ii = 0; ii < n_chan; ii++) {
481 writel(rtd_convert_chan_gain(dev, list[ii], ii),
482 dev->mmio + LAS0_CGT_WRITE);
484 } else { /* just use the channel gain latch */
485 writel(0, dev->mmio + LAS0_CGT_ENABLE);
486 writel(rtd_convert_chan_gain(dev, list[0], 0),
487 dev->mmio + LAS0_CGL_WRITE);
492 * Determine fifo size by doing adc conversions until the fifo half
493 * empty status flag clears.
495 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
497 unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
499 static const unsigned limit = 0x2000;
500 unsigned fifo_size = 0;
502 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
503 rtd_load_channelgain_list(dev, 1, &chanspec);
504 /* ADC conversion trigger source: SOFTWARE */
505 writel(0, dev->mmio + LAS0_ADC_CONVERSION);
506 /* convert samples */
507 for (i = 0; i < limit; ++i) {
508 unsigned fifo_status;
509 /* trigger conversion */
510 writew(0, dev->mmio + LAS0_ADC);
511 usleep_range(1, 1000);
512 fifo_status = readl(dev->mmio + LAS0_ADC);
513 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
519 dev_info(dev->class_dev, "failed to probe fifo size.\n");
522 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
523 if (fifo_size != 0x400 && fifo_size != 0x2000) {
524 dev_info(dev->class_dev,
525 "unexpected fifo size of %i, expected 1024 or 8192.\n",
532 static int rtd_ai_eoc(struct comedi_device *dev,
533 struct comedi_subdevice *s,
534 struct comedi_insn *insn,
535 unsigned long context)
539 status = readl(dev->mmio + LAS0_ADC);
540 if (status & FS_ADC_NOT_EMPTY)
545 static int rtd_ai_rinsn(struct comedi_device *dev,
546 struct comedi_subdevice *s, struct comedi_insn *insn,
549 struct rtd_private *devpriv = dev->private;
550 unsigned int range = CR_RANGE(insn->chanspec);
554 /* clear any old fifo data */
555 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
557 /* write channel to multiplexer and clear channel gain table */
558 rtd_load_channelgain_list(dev, 1, &insn->chanspec);
560 /* ADC conversion trigger source: SOFTWARE */
561 writel(0, dev->mmio + LAS0_ADC_CONVERSION);
563 /* convert n samples */
564 for (n = 0; n < insn->n; n++) {
566 /* trigger conversion */
567 writew(0, dev->mmio + LAS0_ADC);
569 ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
574 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
575 d >>= 3; /* low 3 bits are marker lines */
577 /* convert bipolar data to comedi unsigned data */
578 if (comedi_range_is_bipolar(s, range))
579 d = comedi_offset_munge(s, d);
581 data[n] = d & s->maxdata;
584 /* return the number of samples read/written */
588 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
591 struct rtd_private *devpriv = dev->private;
592 struct comedi_async *async = s->async;
593 struct comedi_cmd *cmd = &async->cmd;
596 for (ii = 0; ii < count; ii++) {
597 unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]);
600 if (devpriv->ai_count == 0) { /* done */
601 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
605 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
606 d >>= 3; /* low 3 bits are marker lines */
608 /* convert bipolar data to comedi unsigned data */
609 if (comedi_range_is_bipolar(s, range))
610 d = comedi_offset_munge(s, d);
613 if (!comedi_buf_write_samples(s, &d, 1))
616 if (devpriv->ai_count > 0) /* < 0, means read forever */
622 static irqreturn_t rtd_interrupt(int irq, void *d)
624 struct comedi_device *dev = d;
625 struct comedi_subdevice *s = dev->read_subdev;
626 struct rtd_private *devpriv = dev->private;
634 fifo_status = readl(dev->mmio + LAS0_ADC);
635 /* check for FIFO full, this automatically halts the ADC! */
636 if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */
639 status = readw(dev->mmio + LAS0_IT);
640 /* if interrupt was not caused by our board, or handled above */
644 if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */
646 * since the priority interrupt controller may have queued
647 * a sample counter interrupt, even though we have already
648 * finished, we must handle the possibility that there is
651 if (!(fifo_status & FS_ADC_HEMPTY)) {
653 if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
656 if (devpriv->ai_count == 0)
658 } else if (devpriv->xfer_count > 0) {
659 if (fifo_status & FS_ADC_NOT_EMPTY) {
661 if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
664 if (devpriv->ai_count == 0)
670 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
674 /* clear the interrupt */
675 writew(status, dev->mmio + LAS0_CLEAR);
676 readw(dev->mmio + LAS0_CLEAR);
678 comedi_handle_events(dev, s);
683 s->async->events |= COMEDI_CB_ERROR;
686 s->async->events |= COMEDI_CB_EOA;
688 /* clear the interrupt */
689 status = readw(dev->mmio + LAS0_IT);
690 writew(status, dev->mmio + LAS0_CLEAR);
691 readw(dev->mmio + LAS0_CLEAR);
693 fifo_status = readl(dev->mmio + LAS0_ADC);
694 overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
696 comedi_handle_events(dev, s);
701 static int rtd_ai_cmdtest(struct comedi_device *dev,
702 struct comedi_subdevice *s, struct comedi_cmd *cmd)
707 /* Step 1 : check if triggers are trivially valid */
709 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
710 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
711 TRIG_TIMER | TRIG_EXT);
712 err |= comedi_check_trigger_src(&cmd->convert_src,
713 TRIG_TIMER | TRIG_EXT);
714 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
715 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
720 /* Step 2a : make sure trigger sources are unique */
722 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
723 err |= comedi_check_trigger_is_unique(cmd->convert_src);
724 err |= comedi_check_trigger_is_unique(cmd->stop_src);
726 /* Step 2b : and mutually compatible */
731 /* Step 3: check if arguments are trivially valid */
733 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
735 if (cmd->scan_begin_src == TRIG_TIMER) {
736 /* Note: these are time periods, not actual rates */
737 if (cmd->chanlist_len == 1) { /* no scanning */
738 if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
740 rtd_ns_to_timer(&cmd->scan_begin_arg,
744 if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
746 rtd_ns_to_timer(&cmd->scan_begin_arg,
751 if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
753 rtd_ns_to_timer(&cmd->scan_begin_arg,
757 if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
759 rtd_ns_to_timer(&cmd->scan_begin_arg,
765 /* external trigger */
766 /* should be level/edge, hi/lo specification here */
767 /* should specify multiple external triggers */
768 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
771 if (cmd->convert_src == TRIG_TIMER) {
772 if (cmd->chanlist_len == 1) { /* no scanning */
773 if (comedi_check_trigger_arg_min(&cmd->convert_arg,
775 rtd_ns_to_timer(&cmd->convert_arg,
779 if (comedi_check_trigger_arg_max(&cmd->convert_arg,
781 rtd_ns_to_timer(&cmd->convert_arg,
786 if (comedi_check_trigger_arg_min(&cmd->convert_arg,
788 rtd_ns_to_timer(&cmd->convert_arg,
792 if (comedi_check_trigger_arg_max(&cmd->convert_arg,
794 rtd_ns_to_timer(&cmd->convert_arg,
800 /* external trigger */
802 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 9);
805 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
808 if (cmd->stop_src == TRIG_COUNT)
809 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
811 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
816 /* step 4: fix up any arguments */
818 if (cmd->scan_begin_src == TRIG_TIMER) {
819 arg = cmd->scan_begin_arg;
820 rtd_ns_to_timer(&arg, cmd->flags);
821 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
824 if (cmd->convert_src == TRIG_TIMER) {
825 arg = cmd->convert_arg;
826 rtd_ns_to_timer(&arg, cmd->flags);
827 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
829 if (cmd->scan_begin_src == TRIG_TIMER) {
830 arg = cmd->convert_arg * cmd->scan_end_arg;
831 err |= comedi_check_trigger_arg_min(&cmd->
843 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
845 struct rtd_private *devpriv = dev->private;
846 struct comedi_cmd *cmd = &s->async->cmd;
849 /* stop anything currently running */
850 /* pacer stop source: SOFTWARE */
851 writel(0, dev->mmio + LAS0_PACER_STOP);
852 writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
853 writel(0, dev->mmio + LAS0_ADC_CONVERSION);
854 writew(0, dev->mmio + LAS0_IT);
855 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
856 writel(0, dev->mmio + LAS0_OVERRUN);
858 /* start configuration */
859 /* load channel list and reset CGT */
860 rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
862 /* setup the common case and override if needed */
863 if (cmd->chanlist_len > 1) {
864 /* pacer start source: SOFTWARE */
865 writel(0, dev->mmio + LAS0_PACER_START);
866 /* burst trigger source: PACER */
867 writel(1, dev->mmio + LAS0_BURST_START);
868 /* ADC conversion trigger source: BURST */
869 writel(2, dev->mmio + LAS0_ADC_CONVERSION);
870 } else { /* single channel */
871 /* pacer start source: SOFTWARE */
872 writel(0, dev->mmio + LAS0_PACER_START);
873 /* ADC conversion trigger source: PACER */
874 writel(1, dev->mmio + LAS0_ADC_CONVERSION);
876 writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
878 if (cmd->scan_begin_src == TRIG_TIMER) {
879 /* scan_begin_arg is in nanoseconds */
880 /* find out how many samples to wait before transferring */
881 if (cmd->flags & CMDF_WAKE_EOS) {
883 * this may generate un-sustainable interrupt rates
884 * the application is responsible for doing the
887 devpriv->xfer_count = cmd->chanlist_len;
888 devpriv->flags |= SEND_EOS;
890 /* arrange to transfer data periodically */
891 devpriv->xfer_count =
892 (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
894 if (devpriv->xfer_count < cmd->chanlist_len) {
895 /* transfer after each scan (and avoid 0) */
896 devpriv->xfer_count = cmd->chanlist_len;
897 } else { /* make a multiple of scan length */
898 devpriv->xfer_count =
899 (devpriv->xfer_count +
900 cmd->chanlist_len - 1)
902 devpriv->xfer_count *= cmd->chanlist_len;
904 devpriv->flags |= SEND_EOS;
906 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
907 /* out of counter range, use 1/2 fifo instead */
908 devpriv->xfer_count = 0;
909 devpriv->flags &= ~SEND_EOS;
911 /* interrupt for each transfer */
912 writel((devpriv->xfer_count - 1) & 0xffff,
913 dev->mmio + LAS0_ACNT);
915 } else { /* unknown timing, just use 1/2 FIFO */
916 devpriv->xfer_count = 0;
917 devpriv->flags &= ~SEND_EOS;
919 /* pacer clock source: INTERNAL 8MHz */
920 writel(1, dev->mmio + LAS0_PACER_SELECT);
921 /* just interrupt, don't stop */
922 writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
924 /* BUG??? these look like enumerated values, but they are bit fields */
926 /* First, setup when to stop */
927 switch (cmd->stop_src) {
928 case TRIG_COUNT: /* stop after N scans */
929 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
930 if ((devpriv->xfer_count > 0) &&
931 (devpriv->xfer_count > devpriv->ai_count)) {
932 devpriv->xfer_count = devpriv->ai_count;
936 case TRIG_NONE: /* stop when cancel is called */
937 devpriv->ai_count = -1; /* read forever */
942 switch (cmd->scan_begin_src) {
943 case TRIG_TIMER: /* periodic scanning */
944 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
946 /* set PACER clock */
947 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
952 /* pacer start source: EXTERNAL */
953 writel(1, dev->mmio + LAS0_PACER_START);
957 /* Sample timing within a scan */
958 switch (cmd->convert_src) {
959 case TRIG_TIMER: /* periodic */
960 if (cmd->chanlist_len > 1) {
961 /* only needed for multi-channel */
962 timer = rtd_ns_to_timer(&cmd->convert_arg,
964 /* setup BURST clock */
965 writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
970 case TRIG_EXT: /* external */
971 /* burst trigger source: EXTERNAL */
972 writel(2, dev->mmio + LAS0_BURST_START);
975 /* end configuration */
978 * This doesn't seem to work. There is no way to clear an interrupt
979 * that the priority controller has queued!
981 writew(~0, dev->mmio + LAS0_CLEAR);
982 readw(dev->mmio + LAS0_CLEAR);
984 /* TODO: allow multiple interrupt sources */
985 /* transfer every N samples */
986 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
988 /* BUG: start_src is ASSUMED to be TRIG_NOW */
989 /* BUG? it seems like things are running before the "start" */
990 readl(dev->mmio + LAS0_PACER); /* start pacer */
994 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
996 struct rtd_private *devpriv = dev->private;
998 /* pacer stop source: SOFTWARE */
999 writel(0, dev->mmio + LAS0_PACER_STOP);
1000 writel(0, dev->mmio + LAS0_PACER); /* stop pacer */
1001 writel(0, dev->mmio + LAS0_ADC_CONVERSION);
1002 writew(0, dev->mmio + LAS0_IT);
1003 devpriv->ai_count = 0; /* stop and don't transfer any more */
1004 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1008 static int rtd_ao_eoc(struct comedi_device *dev,
1009 struct comedi_subdevice *s,
1010 struct comedi_insn *insn,
1011 unsigned long context)
1013 unsigned int chan = CR_CHAN(insn->chanspec);
1014 unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
1015 unsigned int status;
1017 status = readl(dev->mmio + LAS0_ADC);
1023 static int rtd_ao_insn_write(struct comedi_device *dev,
1024 struct comedi_subdevice *s,
1025 struct comedi_insn *insn,
1028 struct rtd_private *devpriv = dev->private;
1029 unsigned int chan = CR_CHAN(insn->chanspec);
1030 unsigned int range = CR_RANGE(insn->chanspec);
1034 /* Configure the output range (table index matches the range values) */
1035 writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan));
1037 for (i = 0; i < insn->n; ++i) {
1038 unsigned int val = data[i];
1040 /* bipolar uses 2's complement values with an extended sign */
1041 if (comedi_range_is_bipolar(s, range)) {
1042 val = comedi_offset_munge(s, val);
1043 val |= (val & ((s->maxdata + 1) >> 1)) << 1;
1046 /* shift the 12-bit data (+ sign) to match the register */
1049 writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan));
1050 writew(0, dev->mmio + LAS0_UPDATE_DAC(chan));
1052 ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
1056 s->readback[chan] = data[i];
1062 static int rtd_dio_insn_bits(struct comedi_device *dev,
1063 struct comedi_subdevice *s,
1064 struct comedi_insn *insn,
1067 if (comedi_dio_update_state(s, data))
1068 writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
1070 data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
1075 static int rtd_dio_insn_config(struct comedi_device *dev,
1076 struct comedi_subdevice *s,
1077 struct comedi_insn *insn,
1082 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1086 /* TODO support digital match interrupts and strobes */
1089 writew(0x01, dev->mmio + LAS0_DIO_STATUS);
1090 writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
1092 /* clear interrupts */
1093 writew(0x00, dev->mmio + LAS0_DIO_STATUS);
1095 /* port1 can only be all input or all output */
1097 /* there are also 2 user input lines and 2 user output lines */
1102 static void rtd_reset(struct comedi_device *dev)
1104 struct rtd_private *devpriv = dev->private;
1106 writel(0, dev->mmio + LAS0_BOARD_RESET);
1107 usleep_range(100, 1000); /* needed? */
1108 writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1109 writew(0, dev->mmio + LAS0_IT);
1110 writew(~0, dev->mmio + LAS0_CLEAR);
1111 readw(dev->mmio + LAS0_CLEAR);
1115 * initialize board, per RTD spec
1116 * also, initialize shadow registers
1118 static void rtd_init_board(struct comedi_device *dev)
1122 writel(0, dev->mmio + LAS0_OVERRUN);
1123 writel(0, dev->mmio + LAS0_CGT_CLEAR);
1124 writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1125 writel(0, dev->mmio + LAS0_DAC_RESET(0));
1126 writel(0, dev->mmio + LAS0_DAC_RESET(1));
1127 /* clear digital IO fifo */
1128 writew(0, dev->mmio + LAS0_DIO_STATUS);
1129 writeb((0 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1130 writeb((1 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1131 writeb((2 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1132 writeb((3 << 6) | 0x00, dev->mmio + LAS0_UTC_CTRL);
1133 /* TODO: set user out source ??? */
1136 /* The RTD driver does this */
1137 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1138 struct pci_dev *pcidev)
1140 unsigned char pci_latency;
1142 pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1143 if (pci_latency < 32) {
1144 dev_info(dev->class_dev,
1145 "PCI latency changed from %d to %d\n",
1147 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1151 static int rtd_auto_attach(struct comedi_device *dev,
1152 unsigned long context)
1154 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1155 const struct rtd_boardinfo *board = NULL;
1156 struct rtd_private *devpriv;
1157 struct comedi_subdevice *s;
1160 if (context < ARRAY_SIZE(rtd520_boards))
1161 board = &rtd520_boards[context];
1164 dev->board_ptr = board;
1165 dev->board_name = board->name;
1167 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1171 ret = comedi_pci_enable(dev);
1175 dev->mmio = pci_ioremap_bar(pcidev, 2);
1176 devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1177 devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1178 if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
1181 rtd_pci_latency_quirk(dev, pcidev);
1184 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1185 dev->board_name, dev);
1187 dev->irq = pcidev->irq;
1190 ret = comedi_alloc_subdevices(dev, 4);
1194 s = &dev->subdevices[0];
1195 /* analog input subdevice */
1196 s->type = COMEDI_SUBD_AI;
1197 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1199 s->maxdata = 0x0fff;
1200 s->range_table = board->ai_range;
1201 s->len_chanlist = RTD_MAX_CHANLIST;
1202 s->insn_read = rtd_ai_rinsn;
1204 dev->read_subdev = s;
1205 s->subdev_flags |= SDF_CMD_READ;
1206 s->do_cmd = rtd_ai_cmd;
1207 s->do_cmdtest = rtd_ai_cmdtest;
1208 s->cancel = rtd_ai_cancel;
1211 s = &dev->subdevices[1];
1212 /* analog output subdevice */
1213 s->type = COMEDI_SUBD_AO;
1214 s->subdev_flags = SDF_WRITABLE;
1216 s->maxdata = 0x0fff;
1217 s->range_table = &rtd_ao_range;
1218 s->insn_write = rtd_ao_insn_write;
1220 ret = comedi_alloc_subdev_readback(s);
1224 s = &dev->subdevices[2];
1225 /* digital i/o subdevice */
1226 s->type = COMEDI_SUBD_DIO;
1227 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1228 /* we only support port 0 right now. Ignoring port 1 and user IO */
1231 s->range_table = &range_digital;
1232 s->insn_bits = rtd_dio_insn_bits;
1233 s->insn_config = rtd_dio_insn_config;
1235 /* timer/counter subdevices (not currently supported) */
1236 s = &dev->subdevices[3];
1237 s->type = COMEDI_SUBD_COUNTER;
1238 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1240 s->maxdata = 0xffff;
1242 rtd_init_board(dev);
1244 ret = rtd520_probe_fifo_depth(dev);
1247 devpriv->fifosz = ret;
1250 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1255 static void rtd_detach(struct comedi_device *dev)
1257 struct rtd_private *devpriv = dev->private;
1260 /* Shut down any board ops by resetting it */
1261 if (dev->mmio && devpriv->lcfg)
1264 free_irq(dev->irq, dev);
1268 iounmap(devpriv->las1);
1270 iounmap(devpriv->lcfg);
1272 comedi_pci_disable(dev);
1275 static struct comedi_driver rtd520_driver = {
1276 .driver_name = "rtd520",
1277 .module = THIS_MODULE,
1278 .auto_attach = rtd_auto_attach,
1279 .detach = rtd_detach,
1282 static int rtd520_pci_probe(struct pci_dev *dev,
1283 const struct pci_device_id *id)
1285 return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1288 static const struct pci_device_id rtd520_pci_table[] = {
1289 { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1290 { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1293 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1295 static struct pci_driver rtd520_pci_driver = {
1297 .id_table = rtd520_pci_table,
1298 .probe = rtd520_pci_probe,
1299 .remove = comedi_pci_auto_unconfig,
1301 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1303 MODULE_AUTHOR("Comedi http://www.comedi.org");
1304 MODULE_DESCRIPTION("Comedi low-level driver");
1305 MODULE_LICENSE("GPL");