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.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Description: Real Time Devices PCI4520/DM7520
26 * Devices: (Real Time Devices) DM7520HR-1 [DM7520]
27 * (Real Time Devices) DM7520HR-8 [DM7520]
28 * (Real Time Devices) PCI4520 [PCI4520]
29 * (Real Time Devices) PCI4520-8 [PCI4520]
30 * Author: Dan Christian
31 * Status: Works. Only tested on DM7520-8. Not SMP safe.
33 * Configuration options: not applicable, uses PCI auto config
37 * Created by Dan Christian, NASA Ames Research Center.
39 * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
41 * 8/16 12 bit ADC with FIFO and channel gain table
42 * 8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
43 * 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
44 * 2 12 bit DACs with FIFOs
48 * timers: ADC sample, pacer, burst, about, delay, DA1, DA2
50 * 3 user timer/counters (8254)
53 * The DM7520 has slightly fewer features (fewer gain steps).
55 * These boards can support external multiplexors and multi-board
56 * synchronization, but this driver doesn't support that.
58 * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
59 * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
60 * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
61 * Call them and ask for the register level manual.
62 * PCI chip: http://www.plxtech.com/products/io/pci9080
65 * This board is memory mapped. There is some IO stuff, but it isn't needed.
67 * I use a pretty loose naming style within the driver (rtd_blah).
68 * All externally visible names should be rtd520_blah.
69 * I use camelCase for structures (and inside them).
70 * I may also use upper CamelCase for function names (old habit).
72 * This board is somewhat related to the RTD PCI4400 board.
74 * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
75 * das1800, since they have the best documented code. Driver cb_pcidas64.c
76 * uses the same DMA controller.
78 * As far as I can tell, the About interrupt doesn't work if Sample is
79 * also enabled. It turns out that About really isn't needed, since
80 * we always count down samples read.
82 * There was some timer/counter code, but it didn't follow the right API.
88 * Analog-In supports instruction and command mode.
90 * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
91 * (single channel, 64K read buffer). I get random system lockups when
92 * using DMA with ALI-15xx based systems. I haven't been able to test
93 * any other chipsets. The lockups happen soon after the start of an
94 * acquistion, not in the middle of a long run.
96 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
97 * (with a 256K read buffer).
99 * Digital-IO and Analog-Out only support instruction mode.
102 #include <linux/pci.h>
103 #include <linux/delay.h>
104 #include <linux/interrupt.h>
106 #include "../comedidev.h"
108 #include "comedi_fc.h"
112 * Local Address Space 0 Offsets
114 #define LAS0_USER_IO 0x0008 /* User I/O */
115 #define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
116 #define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */
117 #define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */
118 #define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */
119 #define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */
120 #define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */
121 #define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */
122 #define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */
123 #define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */
124 #define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */
125 #define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */
126 #define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */
127 #define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */
128 #define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */
129 #define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */
130 #define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
131 #define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
132 #define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
133 #define LAS0_IT 0x0030 /* Interrupt Status/Enable */
134 #define IRQM_ADC_FIFO_WRITE (1 << 0) /* ADC FIFO Write */
135 #define IRQM_CGT_RESET (1 << 1) /* Reset CGT */
136 #define IRQM_CGT_PAUSE (1 << 3) /* Pause CGT */
137 #define IRQM_ADC_ABOUT_CNT (1 << 4) /* About Counter out */
138 #define IRQM_ADC_DELAY_CNT (1 << 5) /* Delay Counter out */
139 #define IRQM_ADC_SAMPLE_CNT (1 << 6) /* ADC Sample Counter */
140 #define IRQM_DAC1_UCNT (1 << 7) /* DAC1 Update Counter */
141 #define IRQM_DAC2_UCNT (1 << 8) /* DAC2 Update Counter */
142 #define IRQM_UTC1 (1 << 9) /* User TC1 out */
143 #define IRQM_UTC1_INV (1 << 10) /* User TC1 out, inverted */
144 #define IRQM_UTC2 (1 << 11) /* User TC2 out */
145 #define IRQM_DIGITAL_IT (1 << 12) /* Digital Interrupt */
146 #define IRQM_EXTERNAL_IT (1 << 13) /* External Interrupt */
147 #define IRQM_ETRIG_RISING (1 << 14) /* Ext Trigger rising-edge */
148 #define IRQM_ETRIG_FALLING (1 << 15) /* Ext Trigger falling-edge */
149 #define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
150 #define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
151 #define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
152 #define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
153 #define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
154 #define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
155 #define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
156 #define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
157 #define LAS0_ACNT 0x0058 /* About counter (16 bit) */
158 #define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
159 #define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
160 #define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
161 #define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
162 #define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
163 #define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
164 #define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
165 #define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
166 #define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
167 #define LAS0_BOARD_RESET 0x0100 /* Board reset */
168 #define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
169 #define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
170 #define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
171 #define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
172 #define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
173 #define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
174 #define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
175 #define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
176 #define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
177 #define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
178 #define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
179 #define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
180 #define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
181 #define LAS0_CG_DATA 0x0138 /* Digital Table Write */
182 #define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
183 #define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
184 #define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
185 #define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
186 #define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
187 #define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
188 #define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
189 #define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
190 #define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */
191 #define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
192 #define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
193 #define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
194 #define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */
195 #define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
196 #define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
197 #define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
198 #define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
199 #define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
200 #define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
201 #define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
202 #define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
203 #define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
204 #define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
205 #define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
206 #define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
207 #define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
208 #define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
209 #define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
210 #define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
211 #define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
212 #define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
213 #define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
214 #define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
215 #define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
216 #define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
219 * Local Address Space 1 Offsets
221 #define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
222 #define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
223 #define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */
224 #define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */
226 /*======================================================================
227 Driver specific stuff (tunable)
228 ======================================================================*/
230 /* We really only need 2 buffers. More than that means being much
231 smarter about knowing which ones are full. */
232 #define DMA_CHAIN_COUNT 2 /* max DMA segments/buffers in a ring (min 2) */
234 /* Target period for periodic transfers. This sets the user read latency. */
235 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
236 /* If this is too low, efficiency is poor */
237 #define TRANS_TARGET_PERIOD 10000000 /* 10 ms (in nanoseconds) */
239 /* Set a practical limit on how long a list to support (affects memory use) */
240 /* The board support a channel list up to the FIFO length (1K or 8K) */
241 #define RTD_MAX_CHANLIST 128 /* max channel list that we allow */
243 /* tuning for ai/ao instruction done polling */
245 #define WAIT_QUIETLY /* as nothing, spin on done bit */
246 #define RTD_ADC_TIMEOUT 66000 /* 2 msec at 33mhz bus rate */
247 #define RTD_DAC_TIMEOUT 66000
248 #define RTD_DMA_TIMEOUT 33000 /* 1 msec */
250 /* by delaying, power and electrical noise are reduced somewhat */
251 #define WAIT_QUIETLY udelay(1)
252 #define RTD_ADC_TIMEOUT 2000 /* in usec */
253 #define RTD_DAC_TIMEOUT 2000 /* in usec */
254 #define RTD_DMA_TIMEOUT 1000 /* in usec */
257 /*======================================================================
259 ======================================================================*/
261 #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
262 #define RTD_CLOCK_BASE 125 /* clock period in ns */
264 /* Note: these speed are slower than the spec, but fit the counter resolution*/
265 #define RTD_MAX_SPEED 1625 /* when sampling, in nanoseconds */
266 /* max speed if we don't have to wait for settling */
267 #define RTD_MAX_SPEED_1 875 /* if single channel, in nanoseconds */
269 #define RTD_MIN_SPEED 2097151875 /* (24bit counter) in nanoseconds */
270 /* min speed when only 1 channel (no burst counter) */
271 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
273 /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */
274 #define DMA_MODE_BITS (\
275 PLX_LOCAL_BUS_16_WIDE_BITS \
276 | PLX_DMA_EN_READYIN_BIT \
277 | PLX_DMA_LOCAL_BURST_EN_BIT \
279 | PLX_DMA_INTR_PCI_BIT \
280 | PLX_LOCAL_ADDR_CONST_BIT \
281 | PLX_DEMAND_MODE_BIT)
283 #define DMA_TRANSFER_BITS (\
284 /* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \
285 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
286 /* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
288 /*======================================================================
289 Comedi specific stuff
290 ======================================================================*/
293 * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
295 static const struct comedi_lrange rtd_ai_7520_range = {
297 /* +-5V input range gain steps */
304 /* +-10V input range gain steps */
309 BIP_RANGE(10.0 / 16),
310 BIP_RANGE(10.0 / 32),
311 /* +10V input range gain steps */
316 UNI_RANGE(10.0 / 16),
317 UNI_RANGE(10.0 / 32),
321 /* PCI4520 has two more gains (6 more entries) */
322 static const struct comedi_lrange rtd_ai_4520_range = {
324 /* +-5V input range gain steps */
332 BIP_RANGE(5.0 / 128),
333 /* +-10V input range gain steps */
338 BIP_RANGE(10.0 / 16),
339 BIP_RANGE(10.0 / 32),
340 BIP_RANGE(10.0 / 64),
341 BIP_RANGE(10.0 / 128),
342 /* +10V input range gain steps */
347 UNI_RANGE(10.0 / 16),
348 UNI_RANGE(10.0 / 32),
349 UNI_RANGE(10.0 / 64),
350 UNI_RANGE(10.0 / 128),
354 /* Table order matches range values */
355 static const struct comedi_lrange rtd_ao_range = {
371 int range10Start; /* start of +-10V range */
372 int rangeUniStart; /* start of +10V range */
373 const struct comedi_lrange *ai_range;
376 static const struct rtdBoard rtd520Boards[] = {
381 .ai_range = &rtd_ai_7520_range,
387 .ai_range = &rtd_ai_4520_range,
392 This structure is for data unique to this hardware driver.
393 This is also unique for each board in the system.
396 /* memory mapped board structures */
401 long aiCount; /* total transfer size (samples) */
402 int transCount; /* # to transfer data. 0->1/2FIFO */
403 int flags; /* flag event modes */
405 /* channel list info */
406 /* chanBipolar tracks whether a channel is bipolar (and needs +2048) */
407 unsigned char chanBipolar[RTD_MAX_CHANLIST / 8]; /* bit array */
410 unsigned int aoValue[2]; /* Used for AO read back */
415 /* bit defines for "flags" */
416 #define SEND_EOS 0x01 /* send End Of Scan events */
417 #define DMA0_ACTIVE 0x02 /* DMA0 is active */
418 #define DMA1_ACTIVE 0x04 /* DMA1 is active */
420 /* Macros for accessing channel list bit array */
421 #define CHAN_ARRAY_TEST(array, index) \
422 (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
423 #define CHAN_ARRAY_SET(array, index) \
424 (((array)[(index)/8] |= 1 << ((index) & 0x7)))
425 #define CHAN_ARRAY_CLEAR(array, index) \
426 (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
429 Given a desired period and the clock period (both in ns),
430 return the proper counter value (divider-1).
431 Sets the original period to be the true value.
432 Note: you have to check if the value is larger than the counter range!
434 static int rtd_ns_to_timer_base(unsigned int *nanosec,
435 int round_mode, int base)
439 switch (round_mode) {
440 case TRIG_ROUND_NEAREST:
442 divider = (*nanosec + base / 2) / base;
444 case TRIG_ROUND_DOWN:
445 divider = (*nanosec) / base;
448 divider = (*nanosec + base - 1) / base;
452 divider = 2; /* min is divide by 2 */
454 /* Note: we don't check for max, because different timers
455 have different ranges */
457 *nanosec = base * divider;
458 return divider - 1; /* countdown is divisor+1 */
462 Given a desired period (in ns),
463 return the proper counter value (divider-1) for the internal clock.
464 Sets the original period to be the true value.
466 static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
468 return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
472 Convert a single comedi channel-gain entry to a RTD520 table entry
474 static unsigned short rtdConvertChanGain(struct comedi_device *dev,
475 unsigned int comediChan, int chanIndex)
476 { /* index in channel list */
477 const struct rtdBoard *thisboard = comedi_board(dev);
478 struct rtdPrivate *devpriv = dev->private;
479 unsigned int chan, range, aref;
480 unsigned short r = 0;
482 chan = CR_CHAN(comediChan);
483 range = CR_RANGE(comediChan);
484 aref = CR_AREF(comediChan);
488 /* Note: we also setup the channel list bipolar flag array */
489 if (range < thisboard->range10Start) {
492 r |= (range & 0x7) << 4;
493 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
494 } else if (range < thisboard->rangeUniStart) {
497 r |= ((range - thisboard->range10Start) & 0x7) << 4;
498 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
502 r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;
503 CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
507 case AREF_GROUND: /* on-board ground */
511 r |= 0x80; /* ref external analog common */
515 r |= 0x400; /* differential inputs */
518 case AREF_OTHER: /* ??? */
521 /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
522 chan, range, aref, r); */
527 Setup the channel-gain table from a comedi list
529 static void rtd_load_channelgain_list(struct comedi_device *dev,
530 unsigned int n_chan, unsigned int *list)
532 struct rtdPrivate *devpriv = dev->private;
534 if (n_chan > 1) { /* setup channel gain table */
537 writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
538 writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
539 for (ii = 0; ii < n_chan; ii++) {
540 writel(rtdConvertChanGain(dev, list[ii], ii),
541 devpriv->las0 + LAS0_CGT_WRITE);
543 } else { /* just use the channel gain latch */
544 writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
545 writel(rtdConvertChanGain(dev, list[0], 0),
546 devpriv->las0 + LAS0_CGL_WRITE);
550 /* determine fifo size by doing adc conversions until the fifo half
551 empty status flag clears */
552 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
554 struct rtdPrivate *devpriv = dev->private;
555 unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
557 static const unsigned limit = 0x2000;
558 unsigned fifo_size = 0;
560 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
561 rtd_load_channelgain_list(dev, 1, &chanspec);
562 /* ADC conversion trigger source: SOFTWARE */
563 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
564 /* convert samples */
565 for (i = 0; i < limit; ++i) {
566 unsigned fifo_status;
567 /* trigger conversion */
568 writew(0, devpriv->las0 + LAS0_ADC);
570 fifo_status = readl(devpriv->las0 + LAS0_ADC);
571 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
577 dev_info(dev->class_dev, "failed to probe fifo size.\n");
580 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
581 if (fifo_size != 0x400 && fifo_size != 0x2000) {
582 dev_info(dev->class_dev,
583 "unexpected fifo size of %i, expected 1024 or 8192.\n",
591 "instructions" read/write data in "one-shot" or "software-triggered"
592 mode (simplest case).
593 This doesn't use interrupts.
595 Note, we don't do any settling delays. Use a instruction list to
596 select, delay, then read.
598 static int rtd_ai_rinsn(struct comedi_device *dev,
599 struct comedi_subdevice *s, struct comedi_insn *insn,
602 struct rtdPrivate *devpriv = dev->private;
606 /* clear any old fifo data */
607 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
609 /* write channel to multiplexer and clear channel gain table */
610 rtd_load_channelgain_list(dev, 1, &insn->chanspec);
612 /* ADC conversion trigger source: SOFTWARE */
613 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
615 /* convert n samples */
616 for (n = 0; n < insn->n; n++) {
618 /* trigger conversion */
619 writew(0, devpriv->las0 + LAS0_ADC);
621 for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
622 stat = readl(devpriv->las0 + LAS0_ADC);
623 if (stat & FS_ADC_NOT_EMPTY) /* 1 -> not empty */
627 if (ii >= RTD_ADC_TIMEOUT)
631 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
632 /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
633 d = d >> 3; /* low 3 bits are marker lines */
634 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0))
635 /* convert to comedi unsigned data */
641 /* return the number of samples read/written */
646 Get what we know is there.... Fast!
647 This uses 1/2 the bus cycles of read_dregs (below).
649 The manual claims that we can do a lword read, but it doesn't work here.
651 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
654 struct rtdPrivate *devpriv = dev->private;
657 for (ii = 0; ii < count; ii++) {
661 if (0 == devpriv->aiCount) { /* done */
662 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
666 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
667 d = d >> 3; /* low 3 bits are marker lines */
668 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
669 /* convert to comedi unsigned data */
674 if (!comedi_buf_put(s->async, sample))
677 if (devpriv->aiCount > 0) /* < 0, means read forever */
684 unknown amout of data is waiting in fifo.
686 static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
688 struct rtdPrivate *devpriv = dev->private;
690 while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
692 s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
694 if (0 == devpriv->aiCount) { /* done */
695 continue; /* read rest */
698 d = d >> 3; /* low 3 bits are marker lines */
699 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
700 /* convert to comedi unsigned data */
705 if (!comedi_buf_put(s->async, sample))
708 if (devpriv->aiCount > 0) /* < 0, means read forever */
715 Handle all rtd520 interrupts.
716 Runs atomically and is never re-entered.
717 This is a "slow handler"; other interrupts may be active.
718 The data conversion may someday happen in a "bottom half".
720 static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
722 { /* our data *//* cpu context (ignored) */
723 struct comedi_device *dev = d;
724 struct comedi_subdevice *s = &dev->subdevices[0];
725 struct rtdPrivate *devpriv = dev->private;
733 fifoStatus = readl(devpriv->las0 + LAS0_ADC);
734 /* check for FIFO full, this automatically halts the ADC! */
735 if (!(fifoStatus & FS_ADC_NOT_FULL)) /* 0 -> full */
738 status = readw(devpriv->las0 + LAS0_IT);
739 /* if interrupt was not caused by our board, or handled above */
743 if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */
745 * since the priority interrupt controller may have queued
746 * a sample counter interrupt, even though we have already
747 * finished, we must handle the possibility that there is
750 if (!(fifoStatus & FS_ADC_HEMPTY)) {
752 if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0)
755 if (0 == devpriv->aiCount)
758 comedi_event(dev, s);
759 } else if (devpriv->transCount > 0) {
760 if (fifoStatus & FS_ADC_NOT_EMPTY) {
762 if (ai_read_n(dev, s, devpriv->transCount) < 0)
765 if (0 == devpriv->aiCount)
768 comedi_event(dev, s);
773 overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
777 /* clear the interrupt */
778 writew(status, devpriv->las0 + LAS0_CLEAR);
779 readw(devpriv->las0 + LAS0_CLEAR);
783 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
784 s->async->events |= COMEDI_CB_ERROR;
785 devpriv->aiCount = 0; /* stop and don't transfer any more */
786 /* fall into transferDone */
789 /* pacer stop source: SOFTWARE */
790 writel(0, devpriv->las0 + LAS0_PACER_STOP);
791 writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
792 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
793 writew(0, devpriv->las0 + LAS0_IT);
795 if (devpriv->aiCount > 0) { /* there shouldn't be anything left */
796 fifoStatus = readl(devpriv->las0 + LAS0_ADC);
797 ai_read_dregs(dev, s); /* read anything left in FIFO */
800 s->async->events |= COMEDI_CB_EOA; /* signal end to comedi */
801 comedi_event(dev, s);
803 /* clear the interrupt */
804 status = readw(devpriv->las0 + LAS0_IT);
805 writew(status, devpriv->las0 + LAS0_CLEAR);
806 readw(devpriv->las0 + LAS0_CLEAR);
808 fifoStatus = readl(devpriv->las0 + LAS0_ADC);
809 overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
815 cmdtest tests a particular command to see if it is valid.
816 Using the cmdtest ioctl, a user can create a valid cmd
817 and then have it executed by the cmd ioctl (asynchronously).
819 cmdtest returns 1,2,3,4 or 0, depending on which tests
823 static int rtd_ai_cmdtest(struct comedi_device *dev,
824 struct comedi_subdevice *s, struct comedi_cmd *cmd)
829 /* Step 1 : check if triggers are trivially valid */
831 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
832 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
833 TRIG_TIMER | TRIG_EXT);
834 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
835 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
836 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
841 /* Step 2a : make sure trigger sources are unique */
843 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
844 err |= cfc_check_trigger_is_unique(cmd->convert_src);
845 err |= cfc_check_trigger_is_unique(cmd->stop_src);
847 /* Step 2b : and mutually compatible */
852 /* Step 3: check if arguments are trivially valid */
854 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
856 if (cmd->scan_begin_src == TRIG_TIMER) {
857 /* Note: these are time periods, not actual rates */
858 if (1 == cmd->chanlist_len) { /* no scanning */
859 if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
861 rtd_ns_to_timer(&cmd->scan_begin_arg,
865 if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
867 rtd_ns_to_timer(&cmd->scan_begin_arg,
872 if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
874 rtd_ns_to_timer(&cmd->scan_begin_arg,
878 if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
880 rtd_ns_to_timer(&cmd->scan_begin_arg,
886 /* external trigger */
887 /* should be level/edge, hi/lo specification here */
888 /* should specify multiple external triggers */
889 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
892 if (cmd->convert_src == TRIG_TIMER) {
893 if (1 == cmd->chanlist_len) { /* no scanning */
894 if (cfc_check_trigger_arg_min(&cmd->convert_arg,
896 rtd_ns_to_timer(&cmd->convert_arg,
900 if (cfc_check_trigger_arg_max(&cmd->convert_arg,
902 rtd_ns_to_timer(&cmd->convert_arg,
907 if (cfc_check_trigger_arg_min(&cmd->convert_arg,
909 rtd_ns_to_timer(&cmd->convert_arg,
913 if (cfc_check_trigger_arg_max(&cmd->convert_arg,
915 rtd_ns_to_timer(&cmd->convert_arg,
921 /* external trigger */
923 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
926 if (cmd->stop_src == TRIG_COUNT) {
927 /* TODO check for rounding error due to counter wrap */
930 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
937 /* step 4: fix up any arguments */
939 if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
940 cmd->chanlist_len = RTD_MAX_CHANLIST;
943 if (cmd->scan_begin_src == TRIG_TIMER) {
944 tmp = cmd->scan_begin_arg;
945 rtd_ns_to_timer(&cmd->scan_begin_arg,
946 cmd->flags & TRIG_ROUND_MASK);
947 if (tmp != cmd->scan_begin_arg)
951 if (cmd->convert_src == TRIG_TIMER) {
952 tmp = cmd->convert_arg;
953 rtd_ns_to_timer(&cmd->convert_arg,
954 cmd->flags & TRIG_ROUND_MASK);
955 if (tmp != cmd->convert_arg)
958 if (cmd->scan_begin_src == TRIG_TIMER
959 && (cmd->scan_begin_arg
960 < (cmd->convert_arg * cmd->scan_end_arg))) {
961 cmd->scan_begin_arg =
962 cmd->convert_arg * cmd->scan_end_arg;
974 Execute a analog in command with many possible triggering options.
975 The data get stored in the async structure of the subdevice.
976 This is usually done by an interrupt handler.
977 Userland gets to the data using read calls.
979 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
981 struct rtdPrivate *devpriv = dev->private;
982 struct comedi_cmd *cmd = &s->async->cmd;
985 /* stop anything currently running */
986 /* pacer stop source: SOFTWARE */
987 writel(0, devpriv->las0 + LAS0_PACER_STOP);
988 writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
989 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
990 writew(0, devpriv->las0 + LAS0_IT);
991 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
992 writel(0, devpriv->las0 + LAS0_OVERRUN);
994 /* start configuration */
995 /* load channel list and reset CGT */
996 rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
998 /* setup the common case and override if needed */
999 if (cmd->chanlist_len > 1) {
1000 /* pacer start source: SOFTWARE */
1001 writel(0, devpriv->las0 + LAS0_PACER_START);
1002 /* burst trigger source: PACER */
1003 writel(1, devpriv->las0 + LAS0_BURST_START);
1004 /* ADC conversion trigger source: BURST */
1005 writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
1006 } else { /* single channel */
1007 /* pacer start source: SOFTWARE */
1008 writel(0, devpriv->las0 + LAS0_PACER_START);
1009 /* ADC conversion trigger source: PACER */
1010 writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
1012 writel((devpriv->fifoLen / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
1014 if (TRIG_TIMER == cmd->scan_begin_src) {
1015 /* scan_begin_arg is in nanoseconds */
1016 /* find out how many samples to wait before transferring */
1017 if (cmd->flags & TRIG_WAKE_EOS) {
1019 * this may generate un-sustainable interrupt rates
1020 * the application is responsible for doing the
1023 devpriv->transCount = cmd->chanlist_len;
1024 devpriv->flags |= SEND_EOS;
1026 /* arrange to transfer data periodically */
1029 (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
1030 cmd->scan_begin_arg;
1031 if (devpriv->transCount < cmd->chanlist_len) {
1032 /* transfer after each scan (and avoid 0) */
1033 devpriv->transCount = cmd->chanlist_len;
1034 } else { /* make a multiple of scan length */
1035 devpriv->transCount =
1036 (devpriv->transCount +
1037 cmd->chanlist_len - 1)
1038 / cmd->chanlist_len;
1039 devpriv->transCount *= cmd->chanlist_len;
1041 devpriv->flags |= SEND_EOS;
1043 if (devpriv->transCount >= (devpriv->fifoLen / 2)) {
1044 /* out of counter range, use 1/2 fifo instead */
1045 devpriv->transCount = 0;
1046 devpriv->flags &= ~SEND_EOS;
1048 /* interrupt for each transfer */
1049 writel((devpriv->transCount - 1) & 0xffff,
1050 devpriv->las0 + LAS0_ACNT);
1052 } else { /* unknown timing, just use 1/2 FIFO */
1053 devpriv->transCount = 0;
1054 devpriv->flags &= ~SEND_EOS;
1056 /* pacer clock source: INTERNAL 8MHz */
1057 writel(1, devpriv->las0 + LAS0_PACER_SELECT);
1058 /* just interrupt, don't stop */
1059 writel(1, devpriv->las0 + LAS0_ACNT_STOP_ENABLE);
1061 /* BUG??? these look like enumerated values, but they are bit fields */
1063 /* First, setup when to stop */
1064 switch (cmd->stop_src) {
1065 case TRIG_COUNT: /* stop after N scans */
1066 devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len;
1067 if ((devpriv->transCount > 0)
1068 && (devpriv->transCount > devpriv->aiCount)) {
1069 devpriv->transCount = devpriv->aiCount;
1073 case TRIG_NONE: /* stop when cancel is called */
1074 devpriv->aiCount = -1; /* read forever */
1079 switch (cmd->scan_begin_src) {
1080 case TRIG_TIMER: /* periodic scanning */
1081 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
1082 TRIG_ROUND_NEAREST);
1083 /* set PACER clock */
1084 writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
1089 /* pacer start source: EXTERNAL */
1090 writel(1, devpriv->las0 + LAS0_PACER_START);
1094 /* Sample timing within a scan */
1095 switch (cmd->convert_src) {
1096 case TRIG_TIMER: /* periodic */
1097 if (cmd->chanlist_len > 1) {
1098 /* only needed for multi-channel */
1099 timer = rtd_ns_to_timer(&cmd->convert_arg,
1100 TRIG_ROUND_NEAREST);
1101 /* setup BURST clock */
1102 writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
1107 case TRIG_EXT: /* external */
1108 /* burst trigger source: EXTERNAL */
1109 writel(2, devpriv->las0 + LAS0_BURST_START);
1112 /* end configuration */
1114 /* This doesn't seem to work. There is no way to clear an interrupt
1115 that the priority controller has queued! */
1116 writew(~0, devpriv->las0 + LAS0_CLEAR);
1117 readw(devpriv->las0 + LAS0_CLEAR);
1119 /* TODO: allow multiple interrupt sources */
1120 if (devpriv->transCount > 0) { /* transfer every N samples */
1121 writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
1122 } else { /* 1/2 FIFO transfers */
1123 writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
1126 /* BUG: start_src is ASSUMED to be TRIG_NOW */
1127 /* BUG? it seems like things are running before the "start" */
1128 readl(devpriv->las0 + LAS0_PACER); /* start pacer */
1133 Stop a running data acquisition.
1135 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1137 struct rtdPrivate *devpriv = dev->private;
1141 /* pacer stop source: SOFTWARE */
1142 writel(0, devpriv->las0 + LAS0_PACER_STOP);
1143 writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
1144 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
1145 writew(0, devpriv->las0 + LAS0_IT);
1146 devpriv->aiCount = 0; /* stop and don't transfer any more */
1147 status = readw(devpriv->las0 + LAS0_IT);
1148 overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
1153 Output one (or more) analog values to a single port as fast as possible.
1155 static int rtd_ao_winsn(struct comedi_device *dev,
1156 struct comedi_subdevice *s, struct comedi_insn *insn,
1159 struct rtdPrivate *devpriv = dev->private;
1161 int chan = CR_CHAN(insn->chanspec);
1162 int range = CR_RANGE(insn->chanspec);
1164 /* Configure the output range (table index matches the range values) */
1165 writew(range & 7, devpriv->las0 +
1166 ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
1168 /* Writing a list of values to an AO channel is probably not
1169 * very useful, but that's how the interface is defined. */
1170 for (i = 0; i < insn->n; ++i) {
1171 int val = data[i] << 3;
1172 int stat = 0; /* initialize to avoid bogus warning */
1175 /* VERIFY: comedi range and offset conversions */
1177 if ((range > 1) /* bipolar */
1178 && (data[i] < 2048)) {
1179 /* offset and sign extend */
1180 val = (((int)data[i]) - 2048) << 3;
1181 } else { /* unipolor */
1185 /* a typical programming sequence */
1186 writew(val, devpriv->las1 +
1187 ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
1188 writew(0, devpriv->las0 +
1189 ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
1191 devpriv->aoValue[chan] = data[i]; /* save for read back */
1193 for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
1194 stat = readl(devpriv->las0 + LAS0_ADC);
1195 /* 1 -> not empty */
1196 if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
1201 if (ii >= RTD_DAC_TIMEOUT)
1205 /* return the number of samples read/written */
1209 /* AO subdevices should have a read insn as well as a write insn.
1210 * Usually this means copying a value stored in devpriv. */
1211 static int rtd_ao_rinsn(struct comedi_device *dev,
1212 struct comedi_subdevice *s, struct comedi_insn *insn,
1215 struct rtdPrivate *devpriv = dev->private;
1217 int chan = CR_CHAN(insn->chanspec);
1219 for (i = 0; i < insn->n; i++)
1220 data[i] = devpriv->aoValue[chan];
1226 static int rtd_dio_insn_bits(struct comedi_device *dev,
1227 struct comedi_subdevice *s,
1228 struct comedi_insn *insn,
1231 struct rtdPrivate *devpriv = dev->private;
1232 unsigned int mask = data[0];
1233 unsigned int bits = data[1];
1237 s->state |= (bits & mask);
1239 writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
1242 data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
1248 Configure one bit on a IO port as Input or Output (hence the name :-).
1250 static int rtd_dio_insn_config(struct comedi_device *dev,
1251 struct comedi_subdevice *s,
1252 struct comedi_insn *insn, unsigned int *data)
1254 struct rtdPrivate *devpriv = dev->private;
1255 int chan = CR_CHAN(insn->chanspec);
1257 /* The input or output configuration of each digital line is
1258 * configured by a special insn_config instruction. chanspec
1259 * contains the channel to be changed, and data[0] contains the
1260 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1262 case INSN_CONFIG_DIO_OUTPUT:
1263 s->io_bits |= 1 << chan; /* 1 means Out */
1265 case INSN_CONFIG_DIO_INPUT:
1266 s->io_bits &= ~(1 << chan);
1268 case INSN_CONFIG_DIO_QUERY:
1270 (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1277 /* TODO support digital match interrupts and strobes */
1280 writew(0x01, devpriv->las0 + LAS0_DIO_STATUS);
1281 writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
1283 /* clear interrupts */
1284 writew(0x00, devpriv->las0 + LAS0_DIO_STATUS);
1286 /* port1 can only be all input or all output */
1288 /* there are also 2 user input lines and 2 user output lines */
1293 static void rtd_reset(struct comedi_device *dev)
1295 struct rtdPrivate *devpriv = dev->private;
1297 writel(0, devpriv->las0 + LAS0_BOARD_RESET);
1298 udelay(100); /* needed? */
1299 writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1300 writew(0, devpriv->las0 + LAS0_IT);
1301 writew(~0, devpriv->las0 + LAS0_CLEAR);
1302 readw(devpriv->las0 + LAS0_CLEAR);
1306 * initialize board, per RTD spec
1307 * also, initialize shadow registers
1309 static void rtd_init_board(struct comedi_device *dev)
1311 struct rtdPrivate *devpriv = dev->private;
1315 writel(0, devpriv->las0 + LAS0_OVERRUN);
1316 writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
1317 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
1318 writel(0, devpriv->las0 + LAS0_DAC1_RESET);
1319 writel(0, devpriv->las0 + LAS0_DAC2_RESET);
1320 /* clear digital IO fifo */
1321 writew(0, devpriv->las0 + LAS0_DIO_STATUS);
1322 writeb((0 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1323 writeb((1 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1324 writeb((2 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1325 writeb((3 << 6) | 0x00, devpriv->las0 + LAS0_UTC_CTRL);
1326 /* TODO: set user out source ??? */
1329 /* The RTD driver does this */
1330 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1331 struct pci_dev *pcidev)
1333 unsigned char pci_latency;
1335 pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1336 if (pci_latency < 32) {
1337 dev_info(dev->class_dev,
1338 "PCI latency changed from %d to %d\n",
1340 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1344 static int rtd_auto_attach(struct comedi_device *dev,
1345 unsigned long context)
1347 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1348 const struct rtdBoard *thisboard = NULL;
1349 struct rtdPrivate *devpriv;
1350 struct comedi_subdevice *s;
1353 if (context < ARRAY_SIZE(rtd520Boards))
1354 thisboard = &rtd520Boards[context];
1357 dev->board_ptr = thisboard;
1358 dev->board_name = thisboard->name;
1360 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1363 dev->private = devpriv;
1365 ret = comedi_pci_enable(dev);
1369 devpriv->las0 = pci_ioremap_bar(pcidev, 2);
1370 devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1371 devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1372 if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
1375 rtd_pci_latency_quirk(dev, pcidev);
1378 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1379 dev->board_name, dev);
1381 dev->irq = pcidev->irq;
1384 ret = comedi_alloc_subdevices(dev, 4);
1388 s = &dev->subdevices[0];
1389 /* analog input subdevice */
1390 s->type = COMEDI_SUBD_AI;
1391 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1393 s->maxdata = 0x0fff;
1394 s->range_table = thisboard->ai_range;
1395 s->len_chanlist = RTD_MAX_CHANLIST;
1396 s->insn_read = rtd_ai_rinsn;
1398 dev->read_subdev = s;
1399 s->subdev_flags |= SDF_CMD_READ;
1400 s->do_cmd = rtd_ai_cmd;
1401 s->do_cmdtest = rtd_ai_cmdtest;
1402 s->cancel = rtd_ai_cancel;
1405 s = &dev->subdevices[1];
1406 /* analog output subdevice */
1407 s->type = COMEDI_SUBD_AO;
1408 s->subdev_flags = SDF_WRITABLE;
1410 s->maxdata = 0x0fff;
1411 s->range_table = &rtd_ao_range;
1412 s->insn_write = rtd_ao_winsn;
1413 s->insn_read = rtd_ao_rinsn;
1415 s = &dev->subdevices[2];
1416 /* digital i/o subdevice */
1417 s->type = COMEDI_SUBD_DIO;
1418 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1419 /* we only support port 0 right now. Ignoring port 1 and user IO */
1422 s->range_table = &range_digital;
1423 s->insn_bits = rtd_dio_insn_bits;
1424 s->insn_config = rtd_dio_insn_config;
1426 /* timer/counter subdevices (not currently supported) */
1427 s = &dev->subdevices[3];
1428 s->type = COMEDI_SUBD_COUNTER;
1429 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1431 s->maxdata = 0xffff;
1433 rtd_init_board(dev);
1435 ret = rtd520_probe_fifo_depth(dev);
1438 devpriv->fifoLen = ret;
1441 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1443 dev_info(dev->class_dev, "%s attached\n", dev->board_name);
1448 static void rtd_detach(struct comedi_device *dev)
1450 struct rtdPrivate *devpriv = dev->private;
1453 /* Shut down any board ops by resetting it */
1454 if (devpriv->las0 && devpriv->lcfg)
1457 writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
1458 ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
1459 devpriv->lcfg + PLX_INTRCS_REG);
1460 free_irq(dev->irq, dev);
1463 iounmap(devpriv->las0);
1465 iounmap(devpriv->las1);
1467 iounmap(devpriv->lcfg);
1469 comedi_pci_disable(dev);
1472 static struct comedi_driver rtd520_driver = {
1473 .driver_name = "rtd520",
1474 .module = THIS_MODULE,
1475 .auto_attach = rtd_auto_attach,
1476 .detach = rtd_detach,
1479 static int rtd520_pci_probe(struct pci_dev *dev,
1480 const struct pci_device_id *id)
1482 return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1485 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
1486 { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1487 { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1490 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1492 static struct pci_driver rtd520_pci_driver = {
1494 .id_table = rtd520_pci_table,
1495 .probe = rtd520_pci_probe,
1496 .remove = comedi_pci_auto_unconfig,
1498 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1500 MODULE_AUTHOR("Comedi http://www.comedi.org");
1501 MODULE_DESCRIPTION("Comedi low-level driver");
1502 MODULE_LICENSE("GPL");