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]
23 * (Real Time Devices) DM7520HR-8 [DM7520]
24 * (Real Time Devices) PCI4520 [PCI4520]
25 * (Real Time Devices) PCI4520-8 [PCI4520]
26 * Author: Dan Christian
27 * Status: Works. Only tested on DM7520-8. Not SMP safe.
29 * Configuration options: not applicable, uses PCI auto config
33 * Created by Dan Christian, NASA Ames Research Center.
35 * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
37 * 8/16 12 bit ADC with FIFO and channel gain table
38 * 8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
39 * 8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
40 * 2 12 bit DACs with FIFOs
44 * timers: ADC sample, pacer, burst, about, delay, DA1, DA2
46 * 3 user timer/counters (8254)
49 * The DM7520 has slightly fewer features (fewer gain steps).
51 * These boards can support external multiplexors and multi-board
52 * synchronization, but this driver doesn't support that.
54 * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
55 * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
56 * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
57 * Call them and ask for the register level manual.
58 * PCI chip: http://www.plxtech.com/products/io/pci9080
61 * This board is memory mapped. There is some IO stuff, but it isn't needed.
63 * I use a pretty loose naming style within the driver (rtd_blah).
64 * All externally visible names should be rtd520_blah.
65 * I use camelCase for structures (and inside them).
66 * I may also use upper CamelCase for function names (old habit).
68 * This board is somewhat related to the RTD PCI4400 board.
70 * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
71 * das1800, since they have the best documented code. Driver cb_pcidas64.c
72 * uses the same DMA controller.
74 * As far as I can tell, the About interrupt doesn't work if Sample is
75 * also enabled. It turns out that About really isn't needed, since
76 * we always count down samples read.
78 * There was some timer/counter code, but it didn't follow the right API.
84 * Analog-In supports instruction and command mode.
86 * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
87 * (single channel, 64K read buffer). I get random system lockups when
88 * using DMA with ALI-15xx based systems. I haven't been able to test
89 * any other chipsets. The lockups happen soon after the start of an
90 * acquistion, not in the middle of a long run.
92 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
93 * (with a 256K read buffer).
95 * Digital-IO and Analog-Out only support instruction mode.
98 #include <linux/pci.h>
99 #include <linux/delay.h>
100 #include <linux/interrupt.h>
102 #include "../comedidev.h"
104 #include "comedi_fc.h"
108 * Local Address Space 0 Offsets
110 #define LAS0_USER_IO 0x0008 /* User I/O */
111 #define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
112 #define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */
113 #define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */
114 #define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */
115 #define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */
116 #define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */
117 #define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */
118 #define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */
119 #define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */
120 #define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */
121 #define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */
122 #define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */
123 #define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */
124 #define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */
125 #define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */
126 #define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
127 #define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
128 #define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
129 #define LAS0_IT 0x0030 /* Interrupt Status/Enable */
130 #define IRQM_ADC_FIFO_WRITE (1 << 0) /* ADC FIFO Write */
131 #define IRQM_CGT_RESET (1 << 1) /* Reset CGT */
132 #define IRQM_CGT_PAUSE (1 << 3) /* Pause CGT */
133 #define IRQM_ADC_ABOUT_CNT (1 << 4) /* About Counter out */
134 #define IRQM_ADC_DELAY_CNT (1 << 5) /* Delay Counter out */
135 #define IRQM_ADC_SAMPLE_CNT (1 << 6) /* ADC Sample Counter */
136 #define IRQM_DAC1_UCNT (1 << 7) /* DAC1 Update Counter */
137 #define IRQM_DAC2_UCNT (1 << 8) /* DAC2 Update Counter */
138 #define IRQM_UTC1 (1 << 9) /* User TC1 out */
139 #define IRQM_UTC1_INV (1 << 10) /* User TC1 out, inverted */
140 #define IRQM_UTC2 (1 << 11) /* User TC2 out */
141 #define IRQM_DIGITAL_IT (1 << 12) /* Digital Interrupt */
142 #define IRQM_EXTERNAL_IT (1 << 13) /* External Interrupt */
143 #define IRQM_ETRIG_RISING (1 << 14) /* Ext Trigger rising-edge */
144 #define IRQM_ETRIG_FALLING (1 << 15) /* Ext Trigger falling-edge */
145 #define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
146 #define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
147 #define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
148 #define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
149 #define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
150 #define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
151 #define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
152 #define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
153 #define LAS0_ACNT 0x0058 /* About counter (16 bit) */
154 #define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
155 #define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
156 #define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
157 #define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
158 #define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
159 #define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
160 #define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
161 #define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
162 #define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
163 #define LAS0_BOARD_RESET 0x0100 /* Board reset */
164 #define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
165 #define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
166 #define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
167 #define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
168 #define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
169 #define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
170 #define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
171 #define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
172 #define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
173 #define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
174 #define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
175 #define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
176 #define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
177 #define LAS0_CG_DATA 0x0138 /* Digital Table Write */
178 #define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
179 #define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
180 #define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
181 #define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
182 #define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
183 #define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
184 #define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
185 #define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
186 #define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */
187 #define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
188 #define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
189 #define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
190 #define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */
191 #define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
192 #define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
193 #define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
194 #define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
195 #define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
196 #define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
197 #define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
198 #define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
199 #define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
200 #define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
201 #define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
202 #define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
203 #define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
204 #define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
205 #define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
206 #define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
207 #define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
208 #define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
209 #define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
210 #define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
211 #define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
212 #define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
215 * Local Address Space 1 Offsets
217 #define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
218 #define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
219 #define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */
220 #define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */
222 /*======================================================================
223 Driver specific stuff (tunable)
224 ======================================================================*/
226 /* We really only need 2 buffers. More than that means being much
227 smarter about knowing which ones are full. */
228 #define DMA_CHAIN_COUNT 2 /* max DMA segments/buffers in a ring (min 2) */
230 /* Target period for periodic transfers. This sets the user read latency. */
231 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
232 /* If this is too low, efficiency is poor */
233 #define TRANS_TARGET_PERIOD 10000000 /* 10 ms (in nanoseconds) */
235 /* Set a practical limit on how long a list to support (affects memory use) */
236 /* The board support a channel list up to the FIFO length (1K or 8K) */
237 #define RTD_MAX_CHANLIST 128 /* max channel list that we allow */
239 /* tuning for ai/ao instruction done polling */
241 #define WAIT_QUIETLY /* as nothing, spin on done bit */
242 #define RTD_ADC_TIMEOUT 66000 /* 2 msec at 33mhz bus rate */
243 #define RTD_DAC_TIMEOUT 66000
244 #define RTD_DMA_TIMEOUT 33000 /* 1 msec */
246 /* by delaying, power and electrical noise are reduced somewhat */
247 #define WAIT_QUIETLY udelay(1)
248 #define RTD_ADC_TIMEOUT 2000 /* in usec */
249 #define RTD_DAC_TIMEOUT 2000 /* in usec */
250 #define RTD_DMA_TIMEOUT 1000 /* in usec */
253 /*======================================================================
255 ======================================================================*/
257 #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
258 #define RTD_CLOCK_BASE 125 /* clock period in ns */
260 /* Note: these speed are slower than the spec, but fit the counter resolution*/
261 #define RTD_MAX_SPEED 1625 /* when sampling, in nanoseconds */
262 /* max speed if we don't have to wait for settling */
263 #define RTD_MAX_SPEED_1 875 /* if single channel, in nanoseconds */
265 #define RTD_MIN_SPEED 2097151875 /* (24bit counter) in nanoseconds */
266 /* min speed when only 1 channel (no burst counter) */
267 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
269 /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */
270 #define DMA_MODE_BITS (\
271 PLX_LOCAL_BUS_16_WIDE_BITS \
272 | PLX_DMA_EN_READYIN_BIT \
273 | PLX_DMA_LOCAL_BURST_EN_BIT \
275 | PLX_DMA_INTR_PCI_BIT \
276 | PLX_LOCAL_ADDR_CONST_BIT \
277 | PLX_DEMAND_MODE_BIT)
279 #define DMA_TRANSFER_BITS (\
280 /* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \
281 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
282 /* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
284 /*======================================================================
285 Comedi specific stuff
286 ======================================================================*/
289 * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
291 static const struct comedi_lrange rtd_ai_7520_range
= {
293 /* +-5V input range gain steps */
300 /* +-10V input range gain steps */
305 BIP_RANGE(10.0 / 16),
306 BIP_RANGE(10.0 / 32),
307 /* +10V input range gain steps */
312 UNI_RANGE(10.0 / 16),
313 UNI_RANGE(10.0 / 32),
317 /* PCI4520 has two more gains (6 more entries) */
318 static const struct comedi_lrange rtd_ai_4520_range
= {
320 /* +-5V input range gain steps */
328 BIP_RANGE(5.0 / 128),
329 /* +-10V input range gain steps */
334 BIP_RANGE(10.0 / 16),
335 BIP_RANGE(10.0 / 32),
336 BIP_RANGE(10.0 / 64),
337 BIP_RANGE(10.0 / 128),
338 /* +10V input range gain steps */
343 UNI_RANGE(10.0 / 16),
344 UNI_RANGE(10.0 / 32),
345 UNI_RANGE(10.0 / 64),
346 UNI_RANGE(10.0 / 128),
350 /* Table order matches range values */
351 static const struct comedi_lrange rtd_ao_range
= {
365 struct rtd_boardinfo
{
367 int range_bip10
; /* start of +-10V range */
368 int range_uni10
; /* start of +10V range */
369 const struct comedi_lrange
*ai_range
;
372 static const struct rtd_boardinfo rtd520Boards
[] = {
377 .ai_range
= &rtd_ai_7520_range
,
383 .ai_range
= &rtd_ai_4520_range
,
388 /* memory mapped board structures */
393 long ai_count
; /* total transfer size (samples) */
394 int xfer_count
; /* # to transfer data. 0->1/2FIFO */
395 int flags
; /* flag event modes */
397 unsigned char chan_is_bipolar
[RTD_MAX_CHANLIST
/ 8]; /* bit array */
399 unsigned int ao_readback
[2];
404 /* bit defines for "flags" */
405 #define SEND_EOS 0x01 /* send End Of Scan events */
406 #define DMA0_ACTIVE 0x02 /* DMA0 is active */
407 #define DMA1_ACTIVE 0x04 /* DMA1 is active */
409 /* Macros for accessing channel list bit array */
410 #define CHAN_ARRAY_TEST(array, index) \
411 (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
412 #define CHAN_ARRAY_SET(array, index) \
413 (((array)[(index)/8] |= 1 << ((index) & 0x7)))
414 #define CHAN_ARRAY_CLEAR(array, index) \
415 (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
418 Given a desired period and the clock period (both in ns),
419 return the proper counter value (divider-1).
420 Sets the original period to be the true value.
421 Note: you have to check if the value is larger than the counter range!
423 static int rtd_ns_to_timer_base(unsigned int *nanosec
,
424 int round_mode
, int base
)
428 switch (round_mode
) {
429 case TRIG_ROUND_NEAREST
:
431 divider
= (*nanosec
+ base
/ 2) / base
;
433 case TRIG_ROUND_DOWN
:
434 divider
= (*nanosec
) / base
;
437 divider
= (*nanosec
+ base
- 1) / base
;
441 divider
= 2; /* min is divide by 2 */
443 /* Note: we don't check for max, because different timers
444 have different ranges */
446 *nanosec
= base
* divider
;
447 return divider
- 1; /* countdown is divisor+1 */
451 Given a desired period (in ns),
452 return the proper counter value (divider-1) for the internal clock.
453 Sets the original period to be the true value.
455 static int rtd_ns_to_timer(unsigned int *ns
, int round_mode
)
457 return rtd_ns_to_timer_base(ns
, round_mode
, RTD_CLOCK_BASE
);
461 Convert a single comedi channel-gain entry to a RTD520 table entry
463 static unsigned short rtd_convert_chan_gain(struct comedi_device
*dev
,
464 unsigned int chanspec
, int index
)
466 const struct rtd_boardinfo
*board
= comedi_board(dev
);
467 struct rtd_private
*devpriv
= dev
->private;
468 unsigned int chan
= CR_CHAN(chanspec
);
469 unsigned int range
= CR_RANGE(chanspec
);
470 unsigned int aref
= CR_AREF(chanspec
);
471 unsigned short r
= 0;
475 /* Note: we also setup the channel list bipolar flag array */
476 if (range
< board
->range_bip10
) {
479 r
|= (range
& 0x7) << 4;
480 CHAN_ARRAY_SET(devpriv
->chan_is_bipolar
, index
);
481 } else if (range
< board
->range_uni10
) {
484 r
|= ((range
- board
->range_bip10
) & 0x7) << 4;
485 CHAN_ARRAY_SET(devpriv
->chan_is_bipolar
, index
);
489 r
|= ((range
- board
->range_uni10
) & 0x7) << 4;
490 CHAN_ARRAY_CLEAR(devpriv
->chan_is_bipolar
, index
);
494 case AREF_GROUND
: /* on-board ground */
498 r
|= 0x80; /* ref external analog common */
502 r
|= 0x400; /* differential inputs */
505 case AREF_OTHER
: /* ??? */
508 /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
509 chan, range, aref, r); */
514 Setup the channel-gain table from a comedi list
516 static void rtd_load_channelgain_list(struct comedi_device
*dev
,
517 unsigned int n_chan
, unsigned int *list
)
519 struct rtd_private
*devpriv
= dev
->private;
521 if (n_chan
> 1) { /* setup channel gain table */
524 writel(0, devpriv
->las0
+ LAS0_CGT_CLEAR
);
525 writel(1, devpriv
->las0
+ LAS0_CGT_ENABLE
);
526 for (ii
= 0; ii
< n_chan
; ii
++) {
527 writel(rtd_convert_chan_gain(dev
, list
[ii
], ii
),
528 devpriv
->las0
+ LAS0_CGT_WRITE
);
530 } else { /* just use the channel gain latch */
531 writel(0, devpriv
->las0
+ LAS0_CGT_ENABLE
);
532 writel(rtd_convert_chan_gain(dev
, list
[0], 0),
533 devpriv
->las0
+ LAS0_CGL_WRITE
);
537 /* determine fifo size by doing adc conversions until the fifo half
538 empty status flag clears */
539 static int rtd520_probe_fifo_depth(struct comedi_device
*dev
)
541 struct rtd_private
*devpriv
= dev
->private;
542 unsigned int chanspec
= CR_PACK(0, 0, AREF_GROUND
);
544 static const unsigned limit
= 0x2000;
545 unsigned fifo_size
= 0;
547 writel(0, devpriv
->las0
+ LAS0_ADC_FIFO_CLEAR
);
548 rtd_load_channelgain_list(dev
, 1, &chanspec
);
549 /* ADC conversion trigger source: SOFTWARE */
550 writel(0, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
551 /* convert samples */
552 for (i
= 0; i
< limit
; ++i
) {
553 unsigned fifo_status
;
554 /* trigger conversion */
555 writew(0, devpriv
->las0
+ LAS0_ADC
);
557 fifo_status
= readl(devpriv
->las0
+ LAS0_ADC
);
558 if ((fifo_status
& FS_ADC_HEMPTY
) == 0) {
564 dev_info(dev
->class_dev
, "failed to probe fifo size.\n");
567 writel(0, devpriv
->las0
+ LAS0_ADC_FIFO_CLEAR
);
568 if (fifo_size
!= 0x400 && fifo_size
!= 0x2000) {
569 dev_info(dev
->class_dev
,
570 "unexpected fifo size of %i, expected 1024 or 8192.\n",
578 "instructions" read/write data in "one-shot" or "software-triggered"
579 mode (simplest case).
580 This doesn't use interrupts.
582 Note, we don't do any settling delays. Use a instruction list to
583 select, delay, then read.
585 static int rtd_ai_rinsn(struct comedi_device
*dev
,
586 struct comedi_subdevice
*s
, struct comedi_insn
*insn
,
589 struct rtd_private
*devpriv
= dev
->private;
593 /* clear any old fifo data */
594 writel(0, devpriv
->las0
+ LAS0_ADC_FIFO_CLEAR
);
596 /* write channel to multiplexer and clear channel gain table */
597 rtd_load_channelgain_list(dev
, 1, &insn
->chanspec
);
599 /* ADC conversion trigger source: SOFTWARE */
600 writel(0, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
602 /* convert n samples */
603 for (n
= 0; n
< insn
->n
; n
++) {
605 /* trigger conversion */
606 writew(0, devpriv
->las0
+ LAS0_ADC
);
608 for (ii
= 0; ii
< RTD_ADC_TIMEOUT
; ++ii
) {
609 stat
= readl(devpriv
->las0
+ LAS0_ADC
);
610 if (stat
& FS_ADC_NOT_EMPTY
) /* 1 -> not empty */
614 if (ii
>= RTD_ADC_TIMEOUT
)
618 d
= readw(devpriv
->las1
+ LAS1_ADC_FIFO
);
619 /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
620 d
= d
>> 3; /* low 3 bits are marker lines */
621 if (CHAN_ARRAY_TEST(devpriv
->chan_is_bipolar
, 0))
622 /* convert to comedi unsigned data */
628 /* return the number of samples read/written */
633 Get what we know is there.... Fast!
634 This uses 1/2 the bus cycles of read_dregs (below).
636 The manual claims that we can do a lword read, but it doesn't work here.
638 static int ai_read_n(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
641 struct rtd_private
*devpriv
= dev
->private;
644 for (ii
= 0; ii
< count
; ii
++) {
648 if (0 == devpriv
->ai_count
) { /* done */
649 d
= readw(devpriv
->las1
+ LAS1_ADC_FIFO
);
653 d
= readw(devpriv
->las1
+ LAS1_ADC_FIFO
);
654 d
= d
>> 3; /* low 3 bits are marker lines */
655 if (CHAN_ARRAY_TEST(devpriv
->chan_is_bipolar
,
656 s
->async
->cur_chan
)) {
657 /* convert to comedi unsigned data */
662 if (!comedi_buf_put(s
->async
, sample
))
665 if (devpriv
->ai_count
> 0) /* < 0, means read forever */
672 unknown amout of data is waiting in fifo.
674 static int ai_read_dregs(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
676 struct rtd_private
*devpriv
= dev
->private;
678 while (readl(devpriv
->las0
+ LAS0_ADC
) & FS_ADC_NOT_EMPTY
) {
680 s16 d
= readw(devpriv
->las1
+ LAS1_ADC_FIFO
);
682 if (0 == devpriv
->ai_count
) { /* done */
683 continue; /* read rest */
686 d
= d
>> 3; /* low 3 bits are marker lines */
687 if (CHAN_ARRAY_TEST(devpriv
->chan_is_bipolar
,
688 s
->async
->cur_chan
)) {
689 /* convert to comedi unsigned data */
694 if (!comedi_buf_put(s
->async
, sample
))
697 if (devpriv
->ai_count
> 0) /* < 0, means read forever */
704 Handle all rtd520 interrupts.
705 Runs atomically and is never re-entered.
706 This is a "slow handler"; other interrupts may be active.
707 The data conversion may someday happen in a "bottom half".
709 static irqreturn_t
rtd_interrupt(int irq
, void *d
)
711 struct comedi_device
*dev
= d
;
712 struct comedi_subdevice
*s
= &dev
->subdevices
[0];
713 struct rtd_private
*devpriv
= dev
->private;
721 fifo_status
= readl(devpriv
->las0
+ LAS0_ADC
);
722 /* check for FIFO full, this automatically halts the ADC! */
723 if (!(fifo_status
& FS_ADC_NOT_FULL
)) /* 0 -> full */
726 status
= readw(devpriv
->las0
+ LAS0_IT
);
727 /* if interrupt was not caused by our board, or handled above */
731 if (status
& IRQM_ADC_ABOUT_CNT
) { /* sample count -> read FIFO */
733 * since the priority interrupt controller may have queued
734 * a sample counter interrupt, even though we have already
735 * finished, we must handle the possibility that there is
738 if (!(fifo_status
& FS_ADC_HEMPTY
)) {
740 if (ai_read_n(dev
, s
, devpriv
->fifosz
/ 2) < 0)
743 if (0 == devpriv
->ai_count
)
746 comedi_event(dev
, s
);
747 } else if (devpriv
->xfer_count
> 0) {
748 if (fifo_status
& FS_ADC_NOT_EMPTY
) {
750 if (ai_read_n(dev
, s
, devpriv
->xfer_count
) < 0)
753 if (0 == devpriv
->ai_count
)
756 comedi_event(dev
, s
);
761 overrun
= readl(devpriv
->las0
+ LAS0_OVERRUN
) & 0xffff;
765 /* clear the interrupt */
766 writew(status
, devpriv
->las0
+ LAS0_CLEAR
);
767 readw(devpriv
->las0
+ LAS0_CLEAR
);
771 writel(0, devpriv
->las0
+ LAS0_ADC_FIFO_CLEAR
);
772 s
->async
->events
|= COMEDI_CB_ERROR
;
773 devpriv
->ai_count
= 0; /* stop and don't transfer any more */
774 /* fall into xfer_done */
777 /* pacer stop source: SOFTWARE */
778 writel(0, devpriv
->las0
+ LAS0_PACER_STOP
);
779 writel(0, devpriv
->las0
+ LAS0_PACER
); /* stop pacer */
780 writel(0, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
781 writew(0, devpriv
->las0
+ LAS0_IT
);
783 if (devpriv
->ai_count
> 0) { /* there shouldn't be anything left */
784 fifo_status
= readl(devpriv
->las0
+ LAS0_ADC
);
785 ai_read_dregs(dev
, s
); /* read anything left in FIFO */
788 s
->async
->events
|= COMEDI_CB_EOA
; /* signal end to comedi */
789 comedi_event(dev
, s
);
791 /* clear the interrupt */
792 status
= readw(devpriv
->las0
+ LAS0_IT
);
793 writew(status
, devpriv
->las0
+ LAS0_CLEAR
);
794 readw(devpriv
->las0
+ LAS0_CLEAR
);
796 fifo_status
= readl(devpriv
->las0
+ LAS0_ADC
);
797 overrun
= readl(devpriv
->las0
+ LAS0_OVERRUN
) & 0xffff;
803 cmdtest tests a particular command to see if it is valid.
804 Using the cmdtest ioctl, a user can create a valid cmd
805 and then have it executed by the cmd ioctl (asynchronously).
807 cmdtest returns 1,2,3,4 or 0, depending on which tests
811 static int rtd_ai_cmdtest(struct comedi_device
*dev
,
812 struct comedi_subdevice
*s
, struct comedi_cmd
*cmd
)
817 /* Step 1 : check if triggers are trivially valid */
819 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_NOW
);
820 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
,
821 TRIG_TIMER
| TRIG_EXT
);
822 err
|= cfc_check_trigger_src(&cmd
->convert_src
, TRIG_TIMER
| TRIG_EXT
);
823 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
824 err
|= cfc_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
829 /* Step 2a : make sure trigger sources are unique */
831 err
|= cfc_check_trigger_is_unique(cmd
->scan_begin_src
);
832 err
|= cfc_check_trigger_is_unique(cmd
->convert_src
);
833 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
835 /* Step 2b : and mutually compatible */
840 /* Step 3: check if arguments are trivially valid */
842 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
844 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
845 /* Note: these are time periods, not actual rates */
846 if (1 == cmd
->chanlist_len
) { /* no scanning */
847 if (cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
849 rtd_ns_to_timer(&cmd
->scan_begin_arg
,
853 if (cfc_check_trigger_arg_max(&cmd
->scan_begin_arg
,
855 rtd_ns_to_timer(&cmd
->scan_begin_arg
,
860 if (cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
862 rtd_ns_to_timer(&cmd
->scan_begin_arg
,
866 if (cfc_check_trigger_arg_max(&cmd
->scan_begin_arg
,
868 rtd_ns_to_timer(&cmd
->scan_begin_arg
,
874 /* external trigger */
875 /* should be level/edge, hi/lo specification here */
876 /* should specify multiple external triggers */
877 err
|= cfc_check_trigger_arg_max(&cmd
->scan_begin_arg
, 9);
880 if (cmd
->convert_src
== TRIG_TIMER
) {
881 if (1 == cmd
->chanlist_len
) { /* no scanning */
882 if (cfc_check_trigger_arg_min(&cmd
->convert_arg
,
884 rtd_ns_to_timer(&cmd
->convert_arg
,
888 if (cfc_check_trigger_arg_max(&cmd
->convert_arg
,
890 rtd_ns_to_timer(&cmd
->convert_arg
,
895 if (cfc_check_trigger_arg_min(&cmd
->convert_arg
,
897 rtd_ns_to_timer(&cmd
->convert_arg
,
901 if (cfc_check_trigger_arg_max(&cmd
->convert_arg
,
903 rtd_ns_to_timer(&cmd
->convert_arg
,
909 /* external trigger */
911 err
|= cfc_check_trigger_arg_max(&cmd
->convert_arg
, 9);
914 if (cmd
->stop_src
== TRIG_COUNT
) {
915 /* TODO check for rounding error due to counter wrap */
918 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
925 /* step 4: fix up any arguments */
927 if (cmd
->chanlist_len
> RTD_MAX_CHANLIST
) {
928 cmd
->chanlist_len
= RTD_MAX_CHANLIST
;
931 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
932 tmp
= cmd
->scan_begin_arg
;
933 rtd_ns_to_timer(&cmd
->scan_begin_arg
,
934 cmd
->flags
& TRIG_ROUND_MASK
);
935 if (tmp
!= cmd
->scan_begin_arg
)
939 if (cmd
->convert_src
== TRIG_TIMER
) {
940 tmp
= cmd
->convert_arg
;
941 rtd_ns_to_timer(&cmd
->convert_arg
,
942 cmd
->flags
& TRIG_ROUND_MASK
);
943 if (tmp
!= cmd
->convert_arg
)
946 if (cmd
->scan_begin_src
== TRIG_TIMER
947 && (cmd
->scan_begin_arg
948 < (cmd
->convert_arg
* cmd
->scan_end_arg
))) {
949 cmd
->scan_begin_arg
=
950 cmd
->convert_arg
* cmd
->scan_end_arg
;
962 Execute a analog in command with many possible triggering options.
963 The data get stored in the async structure of the subdevice.
964 This is usually done by an interrupt handler.
965 Userland gets to the data using read calls.
967 static int rtd_ai_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
969 struct rtd_private
*devpriv
= dev
->private;
970 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
973 /* stop anything currently running */
974 /* pacer stop source: SOFTWARE */
975 writel(0, devpriv
->las0
+ LAS0_PACER_STOP
);
976 writel(0, devpriv
->las0
+ LAS0_PACER
); /* stop pacer */
977 writel(0, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
978 writew(0, devpriv
->las0
+ LAS0_IT
);
979 writel(0, devpriv
->las0
+ LAS0_ADC_FIFO_CLEAR
);
980 writel(0, devpriv
->las0
+ LAS0_OVERRUN
);
982 /* start configuration */
983 /* load channel list and reset CGT */
984 rtd_load_channelgain_list(dev
, cmd
->chanlist_len
, cmd
->chanlist
);
986 /* setup the common case and override if needed */
987 if (cmd
->chanlist_len
> 1) {
988 /* pacer start source: SOFTWARE */
989 writel(0, devpriv
->las0
+ LAS0_PACER_START
);
990 /* burst trigger source: PACER */
991 writel(1, devpriv
->las0
+ LAS0_BURST_START
);
992 /* ADC conversion trigger source: BURST */
993 writel(2, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
994 } else { /* single channel */
995 /* pacer start source: SOFTWARE */
996 writel(0, devpriv
->las0
+ LAS0_PACER_START
);
997 /* ADC conversion trigger source: PACER */
998 writel(1, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
1000 writel((devpriv
->fifosz
/ 2 - 1) & 0xffff, devpriv
->las0
+ LAS0_ACNT
);
1002 if (TRIG_TIMER
== cmd
->scan_begin_src
) {
1003 /* scan_begin_arg is in nanoseconds */
1004 /* find out how many samples to wait before transferring */
1005 if (cmd
->flags
& TRIG_WAKE_EOS
) {
1007 * this may generate un-sustainable interrupt rates
1008 * the application is responsible for doing the
1011 devpriv
->xfer_count
= cmd
->chanlist_len
;
1012 devpriv
->flags
|= SEND_EOS
;
1014 /* arrange to transfer data periodically */
1015 devpriv
->xfer_count
=
1016 (TRANS_TARGET_PERIOD
* cmd
->chanlist_len
) /
1017 cmd
->scan_begin_arg
;
1018 if (devpriv
->xfer_count
< cmd
->chanlist_len
) {
1019 /* transfer after each scan (and avoid 0) */
1020 devpriv
->xfer_count
= cmd
->chanlist_len
;
1021 } else { /* make a multiple of scan length */
1022 devpriv
->xfer_count
=
1023 (devpriv
->xfer_count
+
1024 cmd
->chanlist_len
- 1)
1025 / cmd
->chanlist_len
;
1026 devpriv
->xfer_count
*= cmd
->chanlist_len
;
1028 devpriv
->flags
|= SEND_EOS
;
1030 if (devpriv
->xfer_count
>= (devpriv
->fifosz
/ 2)) {
1031 /* out of counter range, use 1/2 fifo instead */
1032 devpriv
->xfer_count
= 0;
1033 devpriv
->flags
&= ~SEND_EOS
;
1035 /* interrupt for each transfer */
1036 writel((devpriv
->xfer_count
- 1) & 0xffff,
1037 devpriv
->las0
+ LAS0_ACNT
);
1039 } else { /* unknown timing, just use 1/2 FIFO */
1040 devpriv
->xfer_count
= 0;
1041 devpriv
->flags
&= ~SEND_EOS
;
1043 /* pacer clock source: INTERNAL 8MHz */
1044 writel(1, devpriv
->las0
+ LAS0_PACER_SELECT
);
1045 /* just interrupt, don't stop */
1046 writel(1, devpriv
->las0
+ LAS0_ACNT_STOP_ENABLE
);
1048 /* BUG??? these look like enumerated values, but they are bit fields */
1050 /* First, setup when to stop */
1051 switch (cmd
->stop_src
) {
1052 case TRIG_COUNT
: /* stop after N scans */
1053 devpriv
->ai_count
= cmd
->stop_arg
* cmd
->chanlist_len
;
1054 if ((devpriv
->xfer_count
> 0)
1055 && (devpriv
->xfer_count
> devpriv
->ai_count
)) {
1056 devpriv
->xfer_count
= devpriv
->ai_count
;
1060 case TRIG_NONE
: /* stop when cancel is called */
1061 devpriv
->ai_count
= -1; /* read forever */
1066 switch (cmd
->scan_begin_src
) {
1067 case TRIG_TIMER
: /* periodic scanning */
1068 timer
= rtd_ns_to_timer(&cmd
->scan_begin_arg
,
1069 TRIG_ROUND_NEAREST
);
1070 /* set PACER clock */
1071 writel(timer
& 0xffffff, devpriv
->las0
+ LAS0_PCLK
);
1076 /* pacer start source: EXTERNAL */
1077 writel(1, devpriv
->las0
+ LAS0_PACER_START
);
1081 /* Sample timing within a scan */
1082 switch (cmd
->convert_src
) {
1083 case TRIG_TIMER
: /* periodic */
1084 if (cmd
->chanlist_len
> 1) {
1085 /* only needed for multi-channel */
1086 timer
= rtd_ns_to_timer(&cmd
->convert_arg
,
1087 TRIG_ROUND_NEAREST
);
1088 /* setup BURST clock */
1089 writel(timer
& 0x3ff, devpriv
->las0
+ LAS0_BCLK
);
1094 case TRIG_EXT
: /* external */
1095 /* burst trigger source: EXTERNAL */
1096 writel(2, devpriv
->las0
+ LAS0_BURST_START
);
1099 /* end configuration */
1101 /* This doesn't seem to work. There is no way to clear an interrupt
1102 that the priority controller has queued! */
1103 writew(~0, devpriv
->las0
+ LAS0_CLEAR
);
1104 readw(devpriv
->las0
+ LAS0_CLEAR
);
1106 /* TODO: allow multiple interrupt sources */
1107 if (devpriv
->xfer_count
> 0) { /* transfer every N samples */
1108 writew(IRQM_ADC_ABOUT_CNT
, devpriv
->las0
+ LAS0_IT
);
1109 } else { /* 1/2 FIFO transfers */
1110 writew(IRQM_ADC_ABOUT_CNT
, devpriv
->las0
+ LAS0_IT
);
1113 /* BUG: start_src is ASSUMED to be TRIG_NOW */
1114 /* BUG? it seems like things are running before the "start" */
1115 readl(devpriv
->las0
+ LAS0_PACER
); /* start pacer */
1120 Stop a running data acquisition.
1122 static int rtd_ai_cancel(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
1124 struct rtd_private
*devpriv
= dev
->private;
1128 /* pacer stop source: SOFTWARE */
1129 writel(0, devpriv
->las0
+ LAS0_PACER_STOP
);
1130 writel(0, devpriv
->las0
+ LAS0_PACER
); /* stop pacer */
1131 writel(0, devpriv
->las0
+ LAS0_ADC_CONVERSION
);
1132 writew(0, devpriv
->las0
+ LAS0_IT
);
1133 devpriv
->ai_count
= 0; /* stop and don't transfer any more */
1134 status
= readw(devpriv
->las0
+ LAS0_IT
);
1135 overrun
= readl(devpriv
->las0
+ LAS0_OVERRUN
) & 0xffff;
1140 Output one (or more) analog values to a single port as fast as possible.
1142 static int rtd_ao_winsn(struct comedi_device
*dev
,
1143 struct comedi_subdevice
*s
, struct comedi_insn
*insn
,
1146 struct rtd_private
*devpriv
= dev
->private;
1148 int chan
= CR_CHAN(insn
->chanspec
);
1149 int range
= CR_RANGE(insn
->chanspec
);
1151 /* Configure the output range (table index matches the range values) */
1152 writew(range
& 7, devpriv
->las0
+
1153 ((chan
== 0) ? LAS0_DAC1_CTRL
: LAS0_DAC2_CTRL
));
1155 /* Writing a list of values to an AO channel is probably not
1156 * very useful, but that's how the interface is defined. */
1157 for (i
= 0; i
< insn
->n
; ++i
) {
1158 int val
= data
[i
] << 3;
1159 int stat
= 0; /* initialize to avoid bogus warning */
1162 /* VERIFY: comedi range and offset conversions */
1164 if ((range
> 1) /* bipolar */
1165 && (data
[i
] < 2048)) {
1166 /* offset and sign extend */
1167 val
= (((int)data
[i
]) - 2048) << 3;
1168 } else { /* unipolor */
1172 /* a typical programming sequence */
1173 writew(val
, devpriv
->las1
+
1174 ((chan
== 0) ? LAS1_DAC1_FIFO
: LAS1_DAC2_FIFO
));
1175 writew(0, devpriv
->las0
+
1176 ((chan
== 0) ? LAS0_DAC1
: LAS0_DAC2
));
1178 devpriv
->ao_readback
[chan
] = data
[i
];
1180 for (ii
= 0; ii
< RTD_DAC_TIMEOUT
; ++ii
) {
1181 stat
= readl(devpriv
->las0
+ LAS0_ADC
);
1182 /* 1 -> not empty */
1183 if (stat
& ((0 == chan
) ? FS_DAC1_NOT_EMPTY
:
1188 if (ii
>= RTD_DAC_TIMEOUT
)
1192 /* return the number of samples read/written */
1196 /* AO subdevices should have a read insn as well as a write insn.
1197 * Usually this means copying a value stored in devpriv. */
1198 static int rtd_ao_rinsn(struct comedi_device
*dev
,
1199 struct comedi_subdevice
*s
, struct comedi_insn
*insn
,
1202 struct rtd_private
*devpriv
= dev
->private;
1204 int chan
= CR_CHAN(insn
->chanspec
);
1206 for (i
= 0; i
< insn
->n
; i
++)
1207 data
[i
] = devpriv
->ao_readback
[chan
];
1213 static int rtd_dio_insn_bits(struct comedi_device
*dev
,
1214 struct comedi_subdevice
*s
,
1215 struct comedi_insn
*insn
,
1218 struct rtd_private
*devpriv
= dev
->private;
1219 unsigned int mask
= data
[0];
1220 unsigned int bits
= data
[1];
1224 s
->state
|= (bits
& mask
);
1226 writew(s
->state
& 0xff, devpriv
->las0
+ LAS0_DIO0
);
1229 data
[1] = readw(devpriv
->las0
+ LAS0_DIO0
) & 0xff;
1234 static int rtd_dio_insn_config(struct comedi_device
*dev
,
1235 struct comedi_subdevice
*s
,
1236 struct comedi_insn
*insn
,
1239 struct rtd_private
*devpriv
= dev
->private;
1240 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1241 unsigned int mask
= 1 << chan
;
1244 case INSN_CONFIG_DIO_OUTPUT
:
1247 case INSN_CONFIG_DIO_INPUT
:
1248 s
->io_bits
&= ~mask
;
1250 case INSN_CONFIG_DIO_QUERY
:
1251 data
[1] = (s
->io_bits
& mask
) ? COMEDI_OUTPUT
: COMEDI_INPUT
;
1258 /* TODO support digital match interrupts and strobes */
1261 writew(0x01, devpriv
->las0
+ LAS0_DIO_STATUS
);
1262 writew(s
->io_bits
& 0xff, devpriv
->las0
+ LAS0_DIO0_CTRL
);
1264 /* clear interrupts */
1265 writew(0x00, devpriv
->las0
+ LAS0_DIO_STATUS
);
1267 /* port1 can only be all input or all output */
1269 /* there are also 2 user input lines and 2 user output lines */
1274 static void rtd_reset(struct comedi_device
*dev
)
1276 struct rtd_private
*devpriv
= dev
->private;
1278 writel(0, devpriv
->las0
+ LAS0_BOARD_RESET
);
1279 udelay(100); /* needed? */
1280 writel(0, devpriv
->lcfg
+ PLX_INTRCS_REG
);
1281 writew(0, devpriv
->las0
+ LAS0_IT
);
1282 writew(~0, devpriv
->las0
+ LAS0_CLEAR
);
1283 readw(devpriv
->las0
+ LAS0_CLEAR
);
1287 * initialize board, per RTD spec
1288 * also, initialize shadow registers
1290 static void rtd_init_board(struct comedi_device
*dev
)
1292 struct rtd_private
*devpriv
= dev
->private;
1296 writel(0, devpriv
->las0
+ LAS0_OVERRUN
);
1297 writel(0, devpriv
->las0
+ LAS0_CGT_CLEAR
);
1298 writel(0, devpriv
->las0
+ LAS0_ADC_FIFO_CLEAR
);
1299 writel(0, devpriv
->las0
+ LAS0_DAC1_RESET
);
1300 writel(0, devpriv
->las0
+ LAS0_DAC2_RESET
);
1301 /* clear digital IO fifo */
1302 writew(0, devpriv
->las0
+ LAS0_DIO_STATUS
);
1303 writeb((0 << 6) | 0x30, devpriv
->las0
+ LAS0_UTC_CTRL
);
1304 writeb((1 << 6) | 0x30, devpriv
->las0
+ LAS0_UTC_CTRL
);
1305 writeb((2 << 6) | 0x30, devpriv
->las0
+ LAS0_UTC_CTRL
);
1306 writeb((3 << 6) | 0x00, devpriv
->las0
+ LAS0_UTC_CTRL
);
1307 /* TODO: set user out source ??? */
1310 /* The RTD driver does this */
1311 static void rtd_pci_latency_quirk(struct comedi_device
*dev
,
1312 struct pci_dev
*pcidev
)
1314 unsigned char pci_latency
;
1316 pci_read_config_byte(pcidev
, PCI_LATENCY_TIMER
, &pci_latency
);
1317 if (pci_latency
< 32) {
1318 dev_info(dev
->class_dev
,
1319 "PCI latency changed from %d to %d\n",
1321 pci_write_config_byte(pcidev
, PCI_LATENCY_TIMER
, 32);
1325 static int rtd_auto_attach(struct comedi_device
*dev
,
1326 unsigned long context
)
1328 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1329 const struct rtd_boardinfo
*board
= NULL
;
1330 struct rtd_private
*devpriv
;
1331 struct comedi_subdevice
*s
;
1334 if (context
< ARRAY_SIZE(rtd520Boards
))
1335 board
= &rtd520Boards
[context
];
1338 dev
->board_ptr
= board
;
1339 dev
->board_name
= board
->name
;
1341 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
1344 dev
->private = devpriv
;
1346 ret
= comedi_pci_enable(dev
);
1350 devpriv
->las0
= pci_ioremap_bar(pcidev
, 2);
1351 devpriv
->las1
= pci_ioremap_bar(pcidev
, 3);
1352 devpriv
->lcfg
= pci_ioremap_bar(pcidev
, 0);
1353 if (!devpriv
->las0
|| !devpriv
->las1
|| !devpriv
->lcfg
)
1356 rtd_pci_latency_quirk(dev
, pcidev
);
1359 ret
= request_irq(pcidev
->irq
, rtd_interrupt
, IRQF_SHARED
,
1360 dev
->board_name
, dev
);
1362 dev
->irq
= pcidev
->irq
;
1365 ret
= comedi_alloc_subdevices(dev
, 4);
1369 s
= &dev
->subdevices
[0];
1370 /* analog input subdevice */
1371 s
->type
= COMEDI_SUBD_AI
;
1372 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_COMMON
| SDF_DIFF
;
1374 s
->maxdata
= 0x0fff;
1375 s
->range_table
= board
->ai_range
;
1376 s
->len_chanlist
= RTD_MAX_CHANLIST
;
1377 s
->insn_read
= rtd_ai_rinsn
;
1379 dev
->read_subdev
= s
;
1380 s
->subdev_flags
|= SDF_CMD_READ
;
1381 s
->do_cmd
= rtd_ai_cmd
;
1382 s
->do_cmdtest
= rtd_ai_cmdtest
;
1383 s
->cancel
= rtd_ai_cancel
;
1386 s
= &dev
->subdevices
[1];
1387 /* analog output subdevice */
1388 s
->type
= COMEDI_SUBD_AO
;
1389 s
->subdev_flags
= SDF_WRITABLE
;
1391 s
->maxdata
= 0x0fff;
1392 s
->range_table
= &rtd_ao_range
;
1393 s
->insn_write
= rtd_ao_winsn
;
1394 s
->insn_read
= rtd_ao_rinsn
;
1396 s
= &dev
->subdevices
[2];
1397 /* digital i/o subdevice */
1398 s
->type
= COMEDI_SUBD_DIO
;
1399 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1400 /* we only support port 0 right now. Ignoring port 1 and user IO */
1403 s
->range_table
= &range_digital
;
1404 s
->insn_bits
= rtd_dio_insn_bits
;
1405 s
->insn_config
= rtd_dio_insn_config
;
1407 /* timer/counter subdevices (not currently supported) */
1408 s
= &dev
->subdevices
[3];
1409 s
->type
= COMEDI_SUBD_COUNTER
;
1410 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1412 s
->maxdata
= 0xffff;
1414 rtd_init_board(dev
);
1416 ret
= rtd520_probe_fifo_depth(dev
);
1419 devpriv
->fifosz
= ret
;
1422 writel(ICS_PIE
| ICS_PLIE
, devpriv
->lcfg
+ PLX_INTRCS_REG
);
1424 dev_info(dev
->class_dev
, "%s attached\n", dev
->board_name
);
1429 static void rtd_detach(struct comedi_device
*dev
)
1431 struct rtd_private
*devpriv
= dev
->private;
1434 /* Shut down any board ops by resetting it */
1435 if (devpriv
->las0
&& devpriv
->lcfg
)
1438 writel(readl(devpriv
->lcfg
+ PLX_INTRCS_REG
) &
1439 ~(ICS_PLIE
| ICS_DMA0_E
| ICS_DMA1_E
),
1440 devpriv
->lcfg
+ PLX_INTRCS_REG
);
1441 free_irq(dev
->irq
, dev
);
1444 iounmap(devpriv
->las0
);
1446 iounmap(devpriv
->las1
);
1448 iounmap(devpriv
->lcfg
);
1450 comedi_pci_disable(dev
);
1453 static struct comedi_driver rtd520_driver
= {
1454 .driver_name
= "rtd520",
1455 .module
= THIS_MODULE
,
1456 .auto_attach
= rtd_auto_attach
,
1457 .detach
= rtd_detach
,
1460 static int rtd520_pci_probe(struct pci_dev
*dev
,
1461 const struct pci_device_id
*id
)
1463 return comedi_pci_auto_config(dev
, &rtd520_driver
, id
->driver_data
);
1466 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table
) = {
1467 { PCI_VDEVICE(RTD
, 0x7520), BOARD_DM7520
},
1468 { PCI_VDEVICE(RTD
, 0x4520), BOARD_PCI4520
},
1471 MODULE_DEVICE_TABLE(pci
, rtd520_pci_table
);
1473 static struct pci_driver rtd520_pci_driver
= {
1475 .id_table
= rtd520_pci_table
,
1476 .probe
= rtd520_pci_probe
,
1477 .remove
= comedi_pci_auto_unconfig
,
1479 module_comedi_pci_driver(rtd520_driver
, rtd520_pci_driver
);
1481 MODULE_AUTHOR("Comedi http://www.comedi.org");
1482 MODULE_DESCRIPTION("Comedi low-level driver");
1483 MODULE_LICENSE("GPL");