Merge tag 'soc2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[linux-2.6-block.git] / drivers / staging / comedi / drivers / rtd520.c
1 /*
2     comedi/drivers/rtd520.c
3     Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 2001 David A. Schleef <ds@schleef.org>
7
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.
12
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.
17
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.
21 */
22 /*
23 Driver: rtd520
24 Description: Real Time Devices PCI4520/DM7520
25 Author: Dan Christian
26 Devices: [Real Time Devices] DM7520HR-1 (rtd520), DM7520HR-8,
27   PCI4520, PCI4520-8
28 Status: Works.  Only tested on DM7520-8.  Not SMP safe.
29
30 Configuration options:
31   [0] - PCI bus of device (optional)
32         If bus / slot is not specified, the first available PCI
33         device will be used.
34   [1] - PCI slot of device (optional)
35 */
36 /*
37     Created by Dan Christian, NASA Ames Research Center.
38
39     The PCI4520 is a PCI card.  The DM7520 is a PC/104-plus card.
40     Both have:
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
45     2 bits output
46     2 bits input
47     bus mastering DMA
48     timers: ADC sample, pacer, burst, about, delay, DA1, DA2
49     sample counter
50     3 user timer/counters (8254)
51     external interrupt
52
53     The DM7520 has slightly fewer features (fewer gain steps).
54
55     These boards can support external multiplexors and multi-board
56     synchronization, but this driver doesn't support that.
57
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
63
64     Notes:
65     This board is memory mapped.  There is some IO stuff, but it isn't needed.
66
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).
71
72     This board is somewhat related to the RTD PCI4400 board.
73
74     I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
75     das1800, since they have the best documented code.  Driver
76     cb_pcidas64.c uses the same DMA controller.
77
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.
81
82     There was some timer/counter code, but it didn't follow the right API.
83
84 */
85
86 /*
87   driver status:
88
89   Analog-In supports instruction and command mode.
90
91   With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
92   (single channel, 64K read buffer).  I get random system lockups when
93   using DMA with ALI-15xx based systems.  I haven't been able to test
94   any other chipsets.  The lockups happen soon after the start of an
95   acquistion, not in the middle of a long run.
96
97   Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
98   (with a 256K read buffer).
99
100   Digital-IO and Analog-Out only support instruction mode.
101
102 */
103
104 #include <linux/interrupt.h>
105 #include <linux/delay.h>
106
107 #include "../comedidev.h"
108 #include "comedi_pci.h"
109
110 #define DRV_NAME "rtd520"
111
112 /*======================================================================
113   Driver specific stuff (tunable)
114 ======================================================================*/
115 /* Enable this to test the new DMA support. You may get hard lock ups */
116 /*#define USE_DMA*/
117
118 /* We really only need 2 buffers.  More than that means being much
119    smarter about knowing which ones are full. */
120 #define DMA_CHAIN_COUNT 2       /* max DMA segments/buffers in a ring (min 2) */
121
122 /* Target period for periodic transfers.  This sets the user read latency. */
123 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
124 /* If this is too low, efficiency is poor */
125 #define TRANS_TARGET_PERIOD 10000000    /* 10 ms (in nanoseconds) */
126
127 /* Set a practical limit on how long a list to support (affects memory use) */
128 /* The board support a channel list up to the FIFO length (1K or 8K) */
129 #define RTD_MAX_CHANLIST        128     /* max channel list that we allow */
130
131 /* tuning for ai/ao instruction done polling */
132 #ifdef FAST_SPIN
133 #define WAIT_QUIETLY            /* as nothing, spin on done bit */
134 #define RTD_ADC_TIMEOUT 66000   /* 2 msec at 33mhz bus rate */
135 #define RTD_DAC_TIMEOUT 66000
136 #define RTD_DMA_TIMEOUT 33000   /* 1 msec */
137 #else
138 /* by delaying, power and electrical noise are reduced somewhat */
139 #define WAIT_QUIETLY    udelay(1)
140 #define RTD_ADC_TIMEOUT 2000    /* in usec */
141 #define RTD_DAC_TIMEOUT 2000    /* in usec */
142 #define RTD_DMA_TIMEOUT 1000    /* in usec */
143 #endif
144
145 /*======================================================================
146   Board specific stuff
147 ======================================================================*/
148
149 /* registers  */
150 #define PCI_VENDOR_ID_RTD       0x1435
151 /*
152   The board has three memory windows: las0, las1, and lcfg (the PCI chip)
153   Las1 has the data and can be burst DMAed 32bits at a time.
154 */
155 #define LCFG_PCIINDEX   0
156 /* PCI region 1 is a 256 byte IO space mapping.  Use??? */
157 #define LAS0_PCIINDEX   2       /* PCI memory resources */
158 #define LAS1_PCIINDEX   3
159 #define LCFG_PCISIZE    0x100
160 #define LAS0_PCISIZE    0x200
161 #define LAS1_PCISIZE    0x10
162
163 #define RTD_CLOCK_RATE  8000000 /* 8Mhz onboard clock */
164 #define RTD_CLOCK_BASE  125     /* clock period in ns */
165
166 /* Note: these speed are slower than the spec, but fit the counter resolution*/
167 #define RTD_MAX_SPEED   1625    /* when sampling, in nanoseconds */
168 /* max speed if we don't have to wait for settling */
169 #define RTD_MAX_SPEED_1 875     /* if single channel, in nanoseconds */
170
171 #define RTD_MIN_SPEED   2097151875      /* (24bit counter) in nanoseconds */
172 /* min speed when only 1 channel (no burst counter) */
173 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
174
175 #include "rtd520.h"
176 #include "plx9080.h"
177
178 /* Setup continuous ring of 1/2 FIFO transfers.  See RTD manual p91 */
179 #define DMA_MODE_BITS (\
180                        PLX_LOCAL_BUS_16_WIDE_BITS \
181                        | PLX_DMA_EN_READYIN_BIT \
182                        | PLX_DMA_LOCAL_BURST_EN_BIT \
183                        | PLX_EN_CHAIN_BIT \
184                        | PLX_DMA_INTR_PCI_BIT \
185                        | PLX_LOCAL_ADDR_CONST_BIT \
186                        | PLX_DEMAND_MODE_BIT)
187
188 #define DMA_TRANSFER_BITS (\
189 /* descriptors in PCI memory*/  PLX_DESC_IN_PCI_BIT \
190 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
191 /* from board to PCI */         | PLX_XFER_LOCAL_TO_PCI)
192
193 /*======================================================================
194   Comedi specific stuff
195 ======================================================================*/
196
197 /*
198   The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
199 */
200 static const struct comedi_lrange rtd_ai_7520_range = { 18, {
201                                                              /* +-5V input range gain steps */
202                                                              BIP_RANGE(5.0),
203                                                              BIP_RANGE(5.0 / 2),
204                                                              BIP_RANGE(5.0 / 4),
205                                                              BIP_RANGE(5.0 / 8),
206                                                              BIP_RANGE(5.0 /
207                                                                        16),
208                                                              BIP_RANGE(5.0 /
209                                                                        32),
210                                                              /* +-10V input range gain steps */
211                                                              BIP_RANGE(10.0),
212                                                              BIP_RANGE(10.0 /
213                                                                        2),
214                                                              BIP_RANGE(10.0 /
215                                                                        4),
216                                                              BIP_RANGE(10.0 /
217                                                                        8),
218                                                              BIP_RANGE(10.0 /
219                                                                        16),
220                                                              BIP_RANGE(10.0 /
221                                                                        32),
222                                                              /* +10V input range gain steps */
223                                                              UNI_RANGE(10.0),
224                                                              UNI_RANGE(10.0 /
225                                                                        2),
226                                                              UNI_RANGE(10.0 /
227                                                                        4),
228                                                              UNI_RANGE(10.0 /
229                                                                        8),
230                                                              UNI_RANGE(10.0 /
231                                                                        16),
232                                                              UNI_RANGE(10.0 /
233                                                                        32),
234
235                                                              }
236 };
237
238 /* PCI4520 has two more gains (6 more entries) */
239 static const struct comedi_lrange rtd_ai_4520_range = { 24, {
240                                                              /* +-5V input range gain steps */
241                                                              BIP_RANGE(5.0),
242                                                              BIP_RANGE(5.0 / 2),
243                                                              BIP_RANGE(5.0 / 4),
244                                                              BIP_RANGE(5.0 / 8),
245                                                              BIP_RANGE(5.0 /
246                                                                        16),
247                                                              BIP_RANGE(5.0 /
248                                                                        32),
249                                                              BIP_RANGE(5.0 /
250                                                                        64),
251                                                              BIP_RANGE(5.0 /
252                                                                        128),
253                                                              /* +-10V input range gain steps */
254                                                              BIP_RANGE(10.0),
255                                                              BIP_RANGE(10.0 /
256                                                                        2),
257                                                              BIP_RANGE(10.0 /
258                                                                        4),
259                                                              BIP_RANGE(10.0 /
260                                                                        8),
261                                                              BIP_RANGE(10.0 /
262                                                                        16),
263                                                              BIP_RANGE(10.0 /
264                                                                        32),
265                                                              BIP_RANGE(10.0 /
266                                                                        64),
267                                                              BIP_RANGE(10.0 /
268                                                                        128),
269                                                              /* +10V input range gain steps */
270                                                              UNI_RANGE(10.0),
271                                                              UNI_RANGE(10.0 /
272                                                                        2),
273                                                              UNI_RANGE(10.0 /
274                                                                        4),
275                                                              UNI_RANGE(10.0 /
276                                                                        8),
277                                                              UNI_RANGE(10.0 /
278                                                                        16),
279                                                              UNI_RANGE(10.0 /
280                                                                        32),
281                                                              UNI_RANGE(10.0 /
282                                                                        64),
283                                                              UNI_RANGE(10.0 /
284                                                                        128),
285                                                              }
286 };
287
288 /* Table order matches range values */
289 static const struct comedi_lrange rtd_ao_range = { 4, {
290                                                        RANGE(0, 5),
291                                                        RANGE(0, 10),
292                                                        RANGE(-5, 5),
293                                                        RANGE(-10, 10),
294                                                        }
295 };
296
297 /*
298   Board descriptions
299  */
300 struct rtdBoard {
301         const char *name;       /* must be first */
302         int device_id;
303         int aiChans;
304         int aiBits;
305         int aiMaxGain;
306         int range10Start;       /* start of +-10V range */
307         int rangeUniStart;      /* start of +10V range */
308 };
309
310 static const struct rtdBoard rtd520Boards[] = {
311         {
312          .name = "DM7520",
313          .device_id = 0x7520,
314          .aiChans = 16,
315          .aiBits = 12,
316          .aiMaxGain = 32,
317          .range10Start = 6,
318          .rangeUniStart = 12,
319          },
320         {
321          .name = "PCI4520",
322          .device_id = 0x4520,
323          .aiChans = 16,
324          .aiBits = 12,
325          .aiMaxGain = 128,
326          .range10Start = 8,
327          .rangeUniStart = 16,
328          },
329 };
330
331 /*
332  * Useful for shorthand access to the particular board structure
333  */
334 #define thisboard ((const struct rtdBoard *)dev->board_ptr)
335
336 /*
337    This structure is for data unique to this hardware driver.
338    This is also unique for each board in the system.
339 */
340 struct rtdPrivate {
341         /* memory mapped board structures */
342         void __iomem *las0;
343         void __iomem *las1;
344         void __iomem *lcfg;
345
346         unsigned long intCount; /* interrupt count */
347         long aiCount;           /* total transfer size (samples) */
348         int transCount;         /* # to transfer data. 0->1/2FIFO */
349         int flags;              /* flag event modes */
350
351         /* PCI device info */
352         struct pci_dev *pci_dev;
353         int got_regions;        /* non-zero if PCI regions owned */
354
355         /* channel list info */
356         /* chanBipolar tracks whether a channel is bipolar (and needs +2048) */
357         unsigned char chanBipolar[RTD_MAX_CHANLIST / 8];        /* bit array */
358
359         /* read back data */
360         unsigned int aoValue[2];        /* Used for AO read back */
361
362         /* timer gate (when enabled) */
363         u8 utcGate[4];          /* 1 extra allows simple range check */
364
365         /* shadow registers affect other registers, but can't be read back */
366         /* The macros below update these on writes */
367         u16 intMask;            /* interrupt mask */
368         u16 intClearMask;       /* interrupt clear mask */
369         u8 utcCtrl[4];          /* crtl mode for 3 utc + read back */
370         u8 dioStatus;           /* could be read back (dio0Ctrl) */
371 #ifdef USE_DMA
372         /*
373          * Always DMA 1/2 FIFO.  Buffer (dmaBuff?) is (at least) twice that
374          * size.  After transferring, interrupt processes 1/2 FIFO and
375          * passes to comedi
376          */
377         s16 dma0Offset;         /* current processing offset (0, 1/2) */
378         uint16_t *dma0Buff[DMA_CHAIN_COUNT];    /* DMA buffers (for ADC) */
379         dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT];   /* physical addresses */
380         struct plx_dma_desc *dma0Chain; /* DMA descriptor ring for dmaBuff */
381         dma_addr_t dma0ChainPhysAddr;   /* physical addresses */
382         /* shadow registers */
383         u8 dma0Control;
384         u8 dma1Control;
385 #endif                          /* USE_DMA */
386         unsigned fifoLen;
387 };
388
389 /* bit defines for "flags" */
390 #define SEND_EOS        0x01    /* send End Of Scan events */
391 #define DMA0_ACTIVE     0x02    /* DMA0 is active */
392 #define DMA1_ACTIVE     0x04    /* DMA1 is active */
393
394 /* Macros for accessing channel list bit array */
395 #define CHAN_ARRAY_TEST(array, index) \
396         (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
397 #define CHAN_ARRAY_SET(array, index) \
398         (((array)[(index)/8] |= 1 << ((index) & 0x7)))
399 #define CHAN_ARRAY_CLEAR(array, index) \
400         (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
401
402 /*
403  * most drivers define the following macro to make it easy to
404  * access the private structure.
405  */
406 #define devpriv ((struct rtdPrivate *)dev->private)
407
408 /* Macros to access registers */
409
410 /* Reset board */
411 #define RtdResetBoard(dev) \
412         writel(0, devpriv->las0+LAS0_BOARD_RESET)
413
414 /* Reset channel gain table read pointer */
415 #define RtdResetCGT(dev) \
416         writel(0, devpriv->las0+LAS0_CGT_RESET)
417
418 /* Reset channel gain table read and write pointers */
419 #define RtdClearCGT(dev) \
420         writel(0, devpriv->las0+LAS0_CGT_CLEAR)
421
422 /* Reset channel gain table read and write pointers */
423 #define RtdEnableCGT(dev, v) \
424         writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE)
425
426 /* Write channel gain table entry */
427 #define RtdWriteCGTable(dev, v) \
428         writel(v, devpriv->las0+LAS0_CGT_WRITE)
429
430 /* Write Channel Gain Latch */
431 #define RtdWriteCGLatch(dev, v) \
432         writel(v, devpriv->las0+LAS0_CGL_WRITE)
433
434 /* Reset ADC FIFO */
435 #define RtdAdcClearFifo(dev) \
436         writel(0, devpriv->las0+LAS0_ADC_FIFO_CLEAR)
437
438 /* Set ADC start conversion source select (write only) */
439 #define RtdAdcConversionSource(dev, v) \
440         writel(v, devpriv->las0+LAS0_ADC_CONVERSION)
441
442 /* Set burst start source select (write only) */
443 #define RtdBurstStartSource(dev, v) \
444         writel(v, devpriv->las0+LAS0_BURST_START)
445
446 /* Set Pacer start source select (write only) */
447 #define RtdPacerStartSource(dev, v) \
448         writel(v, devpriv->las0+LAS0_PACER_START)
449
450 /* Set Pacer stop source select (write only) */
451 #define RtdPacerStopSource(dev, v) \
452         writel(v, devpriv->las0+LAS0_PACER_STOP)
453
454 /* Set Pacer clock source select (write only) 0=external 1=internal */
455 #define RtdPacerClockSource(dev, v) \
456         writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)
457
458 /* Set sample counter source select (write only) */
459 #define RtdAdcSampleCounterSource(dev, v) \
460         writel(v, devpriv->las0+LAS0_ADC_SCNT_SRC)
461
462 /* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */
463 #define RtdPacerTriggerMode(dev, v) \
464         writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)
465
466 /* Set About counter stop enable (write only) */
467 #define RtdAboutStopEnable(dev, v) \
468         writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)
469
470 /* Set external trigger polarity (write only) 0=positive edge, 1=negative */
471 #define RtdTriggerPolarity(dev, v) \
472         writel((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)
473
474 /* Start single ADC conversion */
475 #define RtdAdcStart(dev) \
476         writew(0, devpriv->las0+LAS0_ADC)
477
478 /* Read one ADC data value (12bit (with sign extend) as 16bit) */
479 /* Note: matches what DMA would get.  Actual value >> 3 */
480 #define RtdAdcFifoGet(dev) \
481         readw(devpriv->las1+LAS1_ADC_FIFO)
482
483 /* Read two ADC data values (DOESN'T WORK) */
484 #define RtdAdcFifoGet2(dev) \
485         readl(devpriv->las1+LAS1_ADC_FIFO)
486
487 /* FIFO status */
488 #define RtdFifoStatus(dev) \
489         readl(devpriv->las0+LAS0_ADC)
490
491 /* pacer start/stop read=start, write=stop*/
492 #define RtdPacerStart(dev) \
493         readl(devpriv->las0+LAS0_PACER)
494 #define RtdPacerStop(dev) \
495         writel(0, devpriv->las0+LAS0_PACER)
496
497 /* Interrupt status */
498 #define RtdInterruptStatus(dev) \
499         readw(devpriv->las0+LAS0_IT)
500
501 /* Interrupt mask */
502 #define RtdInterruptMask(dev, v) \
503         writew((devpriv->intMask = (v)), devpriv->las0+LAS0_IT)
504
505 /* Interrupt status clear (only bits set in mask) */
506 #define RtdInterruptClear(dev) \
507         readw(devpriv->las0+LAS0_CLEAR)
508
509 /* Interrupt clear mask */
510 #define RtdInterruptClearMask(dev, v) \
511         writew((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)
512
513 /* Interrupt overrun status */
514 #define RtdInterruptOverrunStatus(dev) \
515         readl(devpriv->las0+LAS0_OVERRUN)
516
517 /* Interrupt overrun clear */
518 #define RtdInterruptOverrunClear(dev) \
519         writel(0, devpriv->las0+LAS0_OVERRUN)
520
521 /* Pacer counter, 24bit */
522 #define RtdPacerCount(dev) \
523         readl(devpriv->las0+LAS0_PCLK)
524 #define RtdPacerCounter(dev, v) \
525         writel((v) & 0xffffff, devpriv->las0+LAS0_PCLK)
526
527 /* Burst counter, 10bit */
528 #define RtdBurstCount(dev) \
529         readl(devpriv->las0+LAS0_BCLK)
530 #define RtdBurstCounter(dev, v) \
531         writel((v) & 0x3ff, devpriv->las0+LAS0_BCLK)
532
533 /* Delay counter, 16bit */
534 #define RtdDelayCount(dev) \
535         readl(devpriv->las0+LAS0_DCLK)
536 #define RtdDelayCounter(dev, v) \
537         writel((v) & 0xffff, devpriv->las0+LAS0_DCLK)
538
539 /* About counter, 16bit */
540 #define RtdAboutCount(dev) \
541         readl(devpriv->las0+LAS0_ACNT)
542 #define RtdAboutCounter(dev, v) \
543         writel((v) & 0xffff, devpriv->las0+LAS0_ACNT)
544
545 /* ADC sample counter, 10bit */
546 #define RtdAdcSampleCount(dev) \
547         readl(devpriv->las0+LAS0_ADC_SCNT)
548 #define RtdAdcSampleCounter(dev, v) \
549         writel((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)
550
551 /* User Timer/Counter (8254) */
552 #define RtdUtcCounterGet(dev, n) \
553         readb(devpriv->las0 \
554                 + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
555
556 #define RtdUtcCounterPut(dev, n, v) \
557         writeb((v) & 0xff, devpriv->las0 \
558                 + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
559
560 /* Set UTC (8254) control byte  */
561 #define RtdUtcCtrlPut(dev, n, v) \
562         writeb(devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \
563                 devpriv->las0 + LAS0_UTC_CTRL)
564
565 /* Set UTCn clock source (write only) */
566 #define RtdUtcClockSource(dev, n, v) \
567         writew(v, devpriv->las0 \
568                 + ((n <= 0) ? LAS0_UTC0_CLOCK : \
569                         ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))
570
571 /* Set UTCn gate source (write only) */
572 #define RtdUtcGateSource(dev, n, v) \
573         writew(v, devpriv->las0 \
574                 + ((n <= 0) ? LAS0_UTC0_GATE : \
575                         ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))
576
577 /* User output N source select (write only) */
578 #define RtdUsrOutSource(dev, n, v) \
579         writel(v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : \
580                                 LAS0_UOUT1_SELECT))
581
582 /* Digital IO */
583 #define RtdDio0Read(dev) \
584         (readw(devpriv->las0+LAS0_DIO0) & 0xff)
585 #define RtdDio0Write(dev, v) \
586         writew((v) & 0xff, devpriv->las0+LAS0_DIO0)
587
588 #define RtdDio1Read(dev) \
589         (readw(devpriv->las0+LAS0_DIO1) & 0xff)
590 #define RtdDio1Write(dev, v) \
591         writew((v) & 0xff, devpriv->las0+LAS0_DIO1)
592
593 #define RtdDioStatusRead(dev) \
594         (readw(devpriv->las0+LAS0_DIO_STATUS) & 0xff)
595 #define RtdDioStatusWrite(dev, v) \
596         writew((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)
597
598 #define RtdDio0CtrlRead(dev) \
599         (readw(devpriv->las0+LAS0_DIO0_CTRL) & 0xff)
600 #define RtdDio0CtrlWrite(dev, v) \
601         writew((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)
602
603 /* Digital to Analog converter */
604 /* Write one data value (sign + 12bit + marker bits) */
605 /* Note: matches what DMA would put.  Actual value << 3 */
606 #define RtdDacFifoPut(dev, n, v) \
607         writew((v), devpriv->las1 + (((n) == 0) ? LAS1_DAC1_FIFO : \
608                                 LAS1_DAC2_FIFO))
609
610 /* Start single DAC conversion */
611 #define RtdDacUpdate(dev, n) \
612         writew(0, devpriv->las0 + (((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))
613
614 /* Start single DAC conversion on both DACs */
615 #define RtdDacBothUpdate(dev) \
616         writew(0, devpriv->las0+LAS0_DAC)
617
618 /* Set DAC output type and range */
619 #define RtdDacRange(dev, n, v) \
620         writew((v) & 7, devpriv->las0 \
621                 +(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))
622
623 /* Reset DAC FIFO */
624 #define RtdDacClearFifo(dev, n) \
625         writel(0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : \
626                                 LAS0_DAC2_RESET))
627
628 /* Set source for DMA 0 (write only, shadow?) */
629 #define RtdDma0Source(dev, n) \
630         writel((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)
631
632 /* Set source for DMA 1 (write only, shadow?) */
633 #define RtdDma1Source(dev, n) \
634         writel((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)
635
636 /* Reset board state for DMA 0 */
637 #define RtdDma0Reset(dev) \
638         writel(0, devpriv->las0+LAS0_DMA0_RESET)
639
640 /* Reset board state for DMA 1 */
641 #define RtdDma1Reset(dev) \
642         writel(0, devpriv->las0+LAS0_DMA1_SRC)
643
644 /* PLX9080 interrupt mask and status */
645 #define RtdPlxInterruptRead(dev) \
646         readl(devpriv->lcfg+LCFG_ITCSR)
647 #define RtdPlxInterruptWrite(dev, v) \
648         writel(v, devpriv->lcfg+LCFG_ITCSR)
649
650 /* Set  mode for DMA 0 */
651 #define RtdDma0Mode(dev, m) \
652         writel((m), devpriv->lcfg+LCFG_DMAMODE0)
653
654 /* Set PCI address for DMA 0 */
655 #define RtdDma0PciAddr(dev, a) \
656         writel((a), devpriv->lcfg+LCFG_DMAPADR0)
657
658 /* Set local address for DMA 0 */
659 #define RtdDma0LocalAddr(dev, a) \
660         writel((a), devpriv->lcfg+LCFG_DMALADR0)
661
662 /* Set byte count for DMA 0 */
663 #define RtdDma0Count(dev, c) \
664         writel((c), devpriv->lcfg+LCFG_DMASIZ0)
665
666 /* Set next descriptor for DMA 0 */
667 #define RtdDma0Next(dev, a) \
668         writel((a), devpriv->lcfg+LCFG_DMADPR0)
669
670 /* Set  mode for DMA 1 */
671 #define RtdDma1Mode(dev, m) \
672         writel((m), devpriv->lcfg+LCFG_DMAMODE1)
673
674 /* Set PCI address for DMA 1 */
675 #define RtdDma1PciAddr(dev, a) \
676         writel((a), devpriv->lcfg+LCFG_DMAADR1)
677
678 /* Set local address for DMA 1 */
679 #define RtdDma1LocalAddr(dev, a) \
680         writel((a), devpriv->lcfg+LCFG_DMALADR1)
681
682 /* Set byte count for DMA 1 */
683 #define RtdDma1Count(dev, c) \
684         writel((c), devpriv->lcfg+LCFG_DMASIZ1)
685
686 /* Set next descriptor for DMA 1 */
687 #define RtdDma1Next(dev, a) \
688         writel((a), devpriv->lcfg+LCFG_DMADPR1)
689
690 /* Set control for DMA 0 (write only, shadow?) */
691 #define RtdDma0Control(dev, n) \
692         writeb(devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)
693
694 /* Get status for DMA 0 */
695 #define RtdDma0Status(dev) \
696         readb(devpriv->lcfg+LCFG_DMACSR0)
697
698 /* Set control for DMA 1 (write only, shadow?) */
699 #define RtdDma1Control(dev, n) \
700         writeb(devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)
701
702 /* Get status for DMA 1 */
703 #define RtdDma1Status(dev) \
704         readb(devpriv->lcfg+LCFG_DMACSR1)
705
706 static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
707                         struct comedi_insn *insn, unsigned int *data);
708 static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
709                         struct comedi_insn *insn, unsigned int *data);
710 static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
711                         struct comedi_insn *insn, unsigned int *data);
712 static int rtd_dio_insn_bits(struct comedi_device *dev,
713                              struct comedi_subdevice *s,
714                              struct comedi_insn *insn, unsigned int *data);
715 static int rtd_dio_insn_config(struct comedi_device *dev,
716                                struct comedi_subdevice *s,
717                                struct comedi_insn *insn, unsigned int *data);
718 static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
719                           struct comedi_cmd *cmd);
720 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
721 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
722 /*
723  * static int rtd_ai_poll(struct comedi_device *dev,
724  *                        struct comedi_subdevice *s);
725  */
726 static int rtd_ns_to_timer(unsigned int *ns, int roundMode);
727 static irqreturn_t rtd_interrupt(int irq, void *d);
728 static int rtd520_probe_fifo_depth(struct comedi_device *dev);
729
730 /*
731  * Attach is called by the Comedi core to configure the driver
732  * for a particular board.  If you specified a board_name array
733  * in the driver structure, dev->board_ptr contains that
734  * address.
735  */
736 static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
737 {                               /* board name and options flags */
738         struct comedi_subdevice *s;
739         struct pci_dev *pcidev;
740         int ret;
741         resource_size_t physLas0;       /* configuration */
742         resource_size_t physLas1;       /* data area */
743         resource_size_t physLcfg;       /* PLX9080 */
744 #ifdef USE_DMA
745         int index;
746 #endif
747
748         printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor);
749
750 #if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA)
751         /* You can set this a load time: modprobe comedi comedi_debug=1 */
752         if (0 == comedi_debug)  /* force DMA debug printks */
753                 comedi_debug = 1;
754 #endif
755
756         /*
757          * Allocate the private structure area.  alloc_private() is a
758          * convenient macro defined in comedidev.h.
759          */
760         if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
761                 return -ENOMEM;
762
763         /*
764          * Probe the device to determine what device in the series it is.
765          */
766         for (pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, NULL);
767              pcidev != NULL;
768              pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) {
769                 int i;
770
771                 if (it->options[0] || it->options[1]) {
772                         if (pcidev->bus->number != it->options[0]
773                             || PCI_SLOT(pcidev->devfn) != it->options[1]) {
774                                 continue;
775                         }
776                 }
777                 for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i) {
778                         if (pcidev->device == rtd520Boards[i].device_id) {
779                                 dev->board_ptr = &rtd520Boards[i];
780                                 break;
781                         }
782                 }
783                 if (dev->board_ptr)
784                         break;  /* found one */
785         }
786         if (!pcidev) {
787                 if (it->options[0] && it->options[1]) {
788                         printk(KERN_INFO "No RTD card at bus=%d slot=%d.\n",
789                                it->options[0], it->options[1]);
790                 } else {
791                         printk(KERN_INFO "No RTD card found.\n");
792                 }
793                 return -EIO;
794         }
795         devpriv->pci_dev = pcidev;
796         dev->board_name = thisboard->name;
797
798         ret = comedi_pci_enable(pcidev, DRV_NAME);
799         if (ret < 0) {
800                 printk(KERN_INFO "Failed to enable PCI device and request regions.\n");
801                 return ret;
802         }
803         devpriv->got_regions = 1;
804
805         /*
806          * Initialize base addresses
807          */
808         /* Get the physical address from PCI config */
809         physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX);
810         physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX);
811         physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX);
812         /* Now have the kernel map this into memory */
813         /* ASSUME page aligned */
814         devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE);
815         devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE);
816         devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE);
817
818         if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
819                 return -ENOMEM;
820
821
822         DPRINTK("%s: LAS0=%llx, LAS1=%llx, CFG=%llx.\n", dev->board_name,
823                 (unsigned long long)physLas0, (unsigned long long)physLas1,
824                 (unsigned long long)physLcfg);
825         {                       /* The RTD driver does this */
826                 unsigned char pci_latency;
827                 u16 revision;
828                 /*uint32_t epld_version; */
829
830                 pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID,
831                                      &revision);
832                 DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision);
833
834                 pci_read_config_byte(devpriv->pci_dev,
835                                      PCI_LATENCY_TIMER, &pci_latency);
836                 if (pci_latency < 32) {
837                         printk(KERN_INFO "%s: PCI latency changed from %d to %d\n",
838                                dev->board_name, pci_latency, 32);
839                         pci_write_config_byte(devpriv->pci_dev,
840                                               PCI_LATENCY_TIMER, 32);
841                 } else {
842                         DPRINTK("rtd520: PCI latency = %d\n", pci_latency);
843                 }
844
845                 /*
846                  * Undocumented EPLD version (doesn't match RTD driver results)
847                  */
848                 /*DPRINTK ("rtd520: Reading epld from %p\n",
849                    devpriv->las0+0);
850                    epld_version = readl (devpriv->las0+0);
851                    if ((epld_version & 0xF0) >> 4 == 0x0F) {
852                    DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version);
853                    } else {
854                    DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4);
855                    } */
856         }
857
858         /* Show board configuration */
859         printk(KERN_INFO "%s:", dev->board_name);
860
861         /*
862          * Allocate the subdevice structures.  alloc_subdevice() is a
863          * convenient macro defined in comedidev.h.
864          */
865         if (alloc_subdevices(dev, 4) < 0)
866                 return -ENOMEM;
867
868
869         s = dev->subdevices + 0;
870         dev->read_subdev = s;
871         /* analog input subdevice */
872         s->type = COMEDI_SUBD_AI;
873         s->subdev_flags =
874             SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
875         s->n_chan = thisboard->aiChans;
876         s->maxdata = (1 << thisboard->aiBits) - 1;
877         if (thisboard->aiMaxGain <= 32)
878                 s->range_table = &rtd_ai_7520_range;
879         else
880                 s->range_table = &rtd_ai_4520_range;
881
882         s->len_chanlist = RTD_MAX_CHANLIST;     /* devpriv->fifoLen */
883         s->insn_read = rtd_ai_rinsn;
884         s->do_cmd = rtd_ai_cmd;
885         s->do_cmdtest = rtd_ai_cmdtest;
886         s->cancel = rtd_ai_cancel;
887         /* s->poll = rtd_ai_poll; *//* not ready yet */
888
889         s = dev->subdevices + 1;
890         /* analog output subdevice */
891         s->type = COMEDI_SUBD_AO;
892         s->subdev_flags = SDF_WRITABLE;
893         s->n_chan = 2;
894         s->maxdata = (1 << thisboard->aiBits) - 1;
895         s->range_table = &rtd_ao_range;
896         s->insn_write = rtd_ao_winsn;
897         s->insn_read = rtd_ao_rinsn;
898
899         s = dev->subdevices + 2;
900         /* digital i/o subdevice */
901         s->type = COMEDI_SUBD_DIO;
902         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
903         /* we only support port 0 right now.  Ignoring port 1 and user IO */
904         s->n_chan = 8;
905         s->maxdata = 1;
906         s->range_table = &range_digital;
907         s->insn_bits = rtd_dio_insn_bits;
908         s->insn_config = rtd_dio_insn_config;
909
910         /* timer/counter subdevices (not currently supported) */
911         s = dev->subdevices + 3;
912         s->type = COMEDI_SUBD_COUNTER;
913         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
914         s->n_chan = 3;
915         s->maxdata = 0xffff;
916
917         /* initialize board, per RTD spec */
918         /* also, initialize shadow registers */
919         RtdResetBoard(dev);
920         udelay(100);            /* needed? */
921         RtdPlxInterruptWrite(dev, 0);
922         RtdInterruptMask(dev, 0);       /* and sets shadow */
923         RtdInterruptClearMask(dev, ~0); /* and sets shadow */
924         RtdInterruptClear(dev); /* clears bits set by mask */
925         RtdInterruptOverrunClear(dev);
926         RtdClearCGT(dev);
927         RtdAdcClearFifo(dev);
928         RtdDacClearFifo(dev, 0);
929         RtdDacClearFifo(dev, 1);
930         /* clear digital IO fifo */
931         RtdDioStatusWrite(dev, 0);      /* safe state, set shadow */
932         RtdUtcCtrlPut(dev, 0, 0x30);    /* safe state, set shadow */
933         RtdUtcCtrlPut(dev, 1, 0x30);    /* safe state, set shadow */
934         RtdUtcCtrlPut(dev, 2, 0x30);    /* safe state, set shadow */
935         RtdUtcCtrlPut(dev, 3, 0);       /* safe state, set shadow */
936         /* TODO: set user out source ??? */
937
938         /* check if our interrupt is available and get it */
939         ret = request_irq(devpriv->pci_dev->irq, rtd_interrupt,
940                           IRQF_SHARED, DRV_NAME, dev);
941
942         if (ret < 0) {
943                 printk("Could not get interrupt! (%u)\n",
944                        devpriv->pci_dev->irq);
945                 return ret;
946         }
947         dev->irq = devpriv->pci_dev->irq;
948         printk(KERN_INFO "( irq=%u )", dev->irq);
949
950         ret = rtd520_probe_fifo_depth(dev);
951         if (ret < 0)
952                 return ret;
953
954         devpriv->fifoLen = ret;
955         printk("( fifoLen=%d )", devpriv->fifoLen);
956
957 #ifdef USE_DMA
958         if (dev->irq > 0) {
959                 printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT);
960                 /*
961                  * The PLX9080 has 2 DMA controllers, but there could be
962                  * 4 sources: ADC, digital, DAC1, and DAC2.  Since only the
963                  * ADC supports cmd mode right now, this isn't an issue (yet)
964                  */
965                 devpriv->dma0Offset = 0;
966
967                 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
968                         devpriv->dma0Buff[index] =
969                             pci_alloc_consistent(devpriv->pci_dev,
970                                                  sizeof(u16) *
971                                                  devpriv->fifoLen / 2,
972                                                  &devpriv->
973                                                  dma0BuffPhysAddr[index]);
974                         if (devpriv->dma0Buff[index] == NULL) {
975                                 ret = -ENOMEM;
976                                 goto rtd_attach_die_error;
977                         }
978                         /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n",
979                            index,
980                            devpriv->dma0Buff[index],
981                            devpriv->dma0BuffPhysAddr[index]); */
982                 }
983
984                 /*
985                  * setup DMA descriptor ring (use cpu_to_le32 for byte
986                  * ordering?)
987                  */
988                 devpriv->dma0Chain =
989                     pci_alloc_consistent(devpriv->pci_dev,
990                                          sizeof(struct plx_dma_desc) *
991                                          DMA_CHAIN_COUNT,
992                                          &devpriv->dma0ChainPhysAddr);
993                 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
994                         devpriv->dma0Chain[index].pci_start_addr =
995                             devpriv->dma0BuffPhysAddr[index];
996                         devpriv->dma0Chain[index].local_start_addr =
997                             DMALADDR_ADC;
998                         devpriv->dma0Chain[index].transfer_size =
999                             sizeof(u16) * devpriv->fifoLen / 2;
1000                         devpriv->dma0Chain[index].next =
1001                             (devpriv->dma0ChainPhysAddr + ((index +
1002                                                             1) %
1003                                                            (DMA_CHAIN_COUNT))
1004                              * sizeof(devpriv->dma0Chain[0]))
1005                             | DMA_TRANSFER_BITS;
1006                         /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n",
1007                            index,
1008                            ((long)devpriv->dma0ChainPhysAddr
1009                            + (index * sizeof(devpriv->dma0Chain[0]))),
1010                            devpriv->dma0Chain[index].pci_start_addr,
1011                            devpriv->dma0Chain[index].local_start_addr,
1012                            devpriv->dma0Chain[index].transfer_size,
1013                            devpriv->dma0Chain[index].next); */
1014                 }
1015
1016                 if (devpriv->dma0Chain == NULL) {
1017                         ret = -ENOMEM;
1018                         goto rtd_attach_die_error;
1019                 }
1020
1021                 RtdDma0Mode(dev, DMA_MODE_BITS);
1022                 /* set DMA trigger source */
1023                 RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL);
1024         } else {
1025                 printk(KERN_INFO "( no IRQ->no DMA )");
1026         }
1027 #endif /* USE_DMA */
1028
1029         if (dev->irq) {         /* enable plx9080 interrupts */
1030                 RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE);
1031         }
1032
1033         printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor);
1034
1035         return 1;
1036
1037 #if 0
1038         /* hit an error, clean up memory and return ret */
1039 /* rtd_attach_die_error: */
1040 #ifdef USE_DMA
1041         for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1042                 if (NULL != devpriv->dma0Buff[index]) { /* free buffer memory */
1043                         pci_free_consistent(devpriv->pci_dev,
1044                                             sizeof(u16) * devpriv->fifoLen / 2,
1045                                             devpriv->dma0Buff[index],
1046                                             devpriv->dma0BuffPhysAddr[index]);
1047                         devpriv->dma0Buff[index] = NULL;
1048                 }
1049         }
1050         if (NULL != devpriv->dma0Chain) {
1051                 pci_free_consistent(devpriv->pci_dev,
1052                                     sizeof(struct plx_dma_desc)
1053                                     * DMA_CHAIN_COUNT,
1054                                     devpriv->dma0Chain,
1055                                     devpriv->dma0ChainPhysAddr);
1056                 devpriv->dma0Chain = NULL;
1057         }
1058 #endif /* USE_DMA */
1059         /* subdevices and priv are freed by the core */
1060         if (dev->irq) {
1061                 /* disable interrupt controller */
1062                 RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
1063                                      & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
1064                 free_irq(dev->irq, dev);
1065         }
1066
1067         /* release all regions that were allocated */
1068         if (devpriv->las0)
1069                 iounmap(devpriv->las0);
1070
1071         if (devpriv->las1)
1072                 iounmap(devpriv->las1);
1073
1074         if (devpriv->lcfg)
1075                 iounmap(devpriv->lcfg);
1076
1077         if (devpriv->pci_dev)
1078                 pci_dev_put(devpriv->pci_dev);
1079
1080         return ret;
1081 #endif
1082 }
1083
1084 static void rtd_detach(struct comedi_device *dev)
1085 {
1086 #ifdef USE_DMA
1087         int index;
1088 #endif
1089
1090         if (devpriv) {
1091                 /* Shut down any board ops by resetting it */
1092 #ifdef USE_DMA
1093                 if (devpriv->lcfg) {
1094                         RtdDma0Control(dev, 0); /* disable DMA */
1095                         RtdDma1Control(dev, 0); /* disable DMA */
1096                         RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE);
1097                 }
1098 #endif /* USE_DMA */
1099                 if (devpriv->las0) {
1100                         RtdResetBoard(dev);
1101                         RtdInterruptMask(dev, 0);
1102                         RtdInterruptClearMask(dev, ~0);
1103                         RtdInterruptClear(dev); /* clears bits set by mask */
1104                 }
1105 #ifdef USE_DMA
1106                 /* release DMA */
1107                 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1108                         if (NULL != devpriv->dma0Buff[index]) {
1109                                 pci_free_consistent(devpriv->pci_dev,
1110                                                     sizeof(u16) *
1111                                                     devpriv->fifoLen / 2,
1112                                                     devpriv->dma0Buff[index],
1113                                                     devpriv->
1114                                                     dma0BuffPhysAddr[index]);
1115                                 devpriv->dma0Buff[index] = NULL;
1116                         }
1117                 }
1118                 if (NULL != devpriv->dma0Chain) {
1119                         pci_free_consistent(devpriv->pci_dev,
1120                                             sizeof(struct plx_dma_desc) *
1121                                             DMA_CHAIN_COUNT, devpriv->dma0Chain,
1122                                             devpriv->dma0ChainPhysAddr);
1123                         devpriv->dma0Chain = NULL;
1124                 }
1125 #endif /* USE_DMA */
1126                 if (dev->irq) {
1127                         RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
1128                                              & ~(ICS_PLIE | ICS_DMA0_E |
1129                                                  ICS_DMA1_E));
1130                         free_irq(dev->irq, dev);
1131                 }
1132                 if (devpriv->las0)
1133                         iounmap(devpriv->las0);
1134                 if (devpriv->las1)
1135                         iounmap(devpriv->las1);
1136                 if (devpriv->lcfg)
1137                         iounmap(devpriv->lcfg);
1138                 if (devpriv->pci_dev) {
1139                         if (devpriv->got_regions)
1140                                 comedi_pci_disable(devpriv->pci_dev);
1141                         pci_dev_put(devpriv->pci_dev);
1142                 }
1143         }
1144 }
1145
1146 /*
1147   Convert a single comedi channel-gain entry to a RTD520 table entry
1148 */
1149 static unsigned short rtdConvertChanGain(struct comedi_device *dev,
1150                                          unsigned int comediChan, int chanIndex)
1151 {                               /* index in channel list */
1152         unsigned int chan, range, aref;
1153         unsigned short r = 0;
1154
1155         chan = CR_CHAN(comediChan);
1156         range = CR_RANGE(comediChan);
1157         aref = CR_AREF(comediChan);
1158
1159         r |= chan & 0xf;
1160
1161         /* Note: we also setup the channel list bipolar flag array */
1162         if (range < thisboard->range10Start) {  /* first batch are +-5 */
1163                 r |= 0x000;     /* +-5 range */
1164                 r |= (range & 0x7) << 4;        /* gain */
1165                 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
1166         } else if (range < thisboard->rangeUniStart) {  /* second batch are +-10 */
1167                 r |= 0x100;     /* +-10 range */
1168                 /* gain */
1169                 r |= ((range - thisboard->range10Start) & 0x7) << 4;
1170                 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
1171         } else {                /* last batch is +10 */
1172                 r |= 0x200;     /* +10 range */
1173                 /* gain */
1174                 r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;
1175                 CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
1176         }
1177
1178         switch (aref) {
1179         case AREF_GROUND:       /* on-board ground */
1180                 break;
1181
1182         case AREF_COMMON:
1183                 r |= 0x80;      /* ref external analog common */
1184                 break;
1185
1186         case AREF_DIFF:
1187                 r |= 0x400;     /* differential inputs */
1188                 break;
1189
1190         case AREF_OTHER:        /* ??? */
1191                 break;
1192         }
1193         /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
1194            chan, range, aref, r); */
1195         return r;
1196 }
1197
1198 /*
1199   Setup the channel-gain table from a comedi list
1200 */
1201 static void rtd_load_channelgain_list(struct comedi_device *dev,
1202                                       unsigned int n_chan, unsigned int *list)
1203 {
1204         if (n_chan > 1) {       /* setup channel gain table */
1205                 int ii;
1206                 RtdClearCGT(dev);
1207                 RtdEnableCGT(dev, 1);   /* enable table */
1208                 for (ii = 0; ii < n_chan; ii++) {
1209                         RtdWriteCGTable(dev, rtdConvertChanGain(dev, list[ii],
1210                                                                 ii));
1211                 }
1212         } else {                /* just use the channel gain latch */
1213                 RtdEnableCGT(dev, 0);   /* disable table, enable latch */
1214                 RtdWriteCGLatch(dev, rtdConvertChanGain(dev, list[0], 0));
1215         }
1216 }
1217
1218 /* determine fifo size by doing adc conversions until the fifo half
1219 empty status flag clears */
1220 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
1221 {
1222         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
1223         unsigned i;
1224         static const unsigned limit = 0x2000;
1225         unsigned fifo_size = 0;
1226
1227         RtdAdcClearFifo(dev);
1228         rtd_load_channelgain_list(dev, 1, &chanspec);
1229         RtdAdcConversionSource(dev, 0); /* software */
1230         /* convert  samples */
1231         for (i = 0; i < limit; ++i) {
1232                 unsigned fifo_status;
1233                 /* trigger conversion */
1234                 RtdAdcStart(dev);
1235                 udelay(1);
1236                 fifo_status = RtdFifoStatus(dev);
1237                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
1238                         fifo_size = 2 * i;
1239                         break;
1240                 }
1241         }
1242         if (i == limit) {
1243                 printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n",
1244                        DRV_NAME);
1245                 return -EIO;
1246         }
1247         RtdAdcClearFifo(dev);
1248         if (fifo_size != 0x400 && fifo_size != 0x2000) {
1249                 printk
1250                     (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
1251                      DRV_NAME, fifo_size);
1252                 return -EIO;
1253         }
1254         return fifo_size;
1255 }
1256
1257 /*
1258   "instructions" read/write data in "one-shot" or "software-triggered"
1259   mode (simplest case).
1260   This doesn't use interrupts.
1261
1262   Note, we don't do any settling delays.  Use a instruction list to
1263   select, delay, then read.
1264  */
1265 static int rtd_ai_rinsn(struct comedi_device *dev,
1266                         struct comedi_subdevice *s, struct comedi_insn *insn,
1267                         unsigned int *data)
1268 {
1269         int n, ii;
1270         int stat;
1271
1272         /* clear any old fifo data */
1273         RtdAdcClearFifo(dev);
1274
1275         /* write channel to multiplexer and clear channel gain table */
1276         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
1277
1278         /* set conversion source */
1279         RtdAdcConversionSource(dev, 0); /* software */
1280
1281         /* convert n samples */
1282         for (n = 0; n < insn->n; n++) {
1283                 s16 d;
1284                 /* trigger conversion */
1285                 RtdAdcStart(dev);
1286
1287                 for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
1288                         stat = RtdFifoStatus(dev);
1289                         if (stat & FS_ADC_NOT_EMPTY)    /* 1 -> not empty */
1290                                 break;
1291                         WAIT_QUIETLY;
1292                 }
1293                 if (ii >= RTD_ADC_TIMEOUT) {
1294                         DPRINTK
1295                             ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n",
1296                              stat ^ 0x6666);
1297                         return -ETIMEDOUT;
1298                 }
1299
1300                 /* read data */
1301                 d = RtdAdcFifoGet(dev); /* get 2s comp value */
1302                 /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
1303                 d = d >> 3;     /* low 3 bits are marker lines */
1304                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0))
1305                         /* convert to comedi unsigned data */
1306                         data[n] = d + 2048;
1307                 else
1308                         data[n] = d;
1309         }
1310
1311         /* return the number of samples read/written */
1312         return n;
1313 }
1314
1315 /*
1316   Get what we know is there.... Fast!
1317   This uses 1/2 the bus cycles of read_dregs (below).
1318
1319   The manual claims that we can do a lword read, but it doesn't work here.
1320 */
1321 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
1322                      int count)
1323 {
1324         int ii;
1325
1326         for (ii = 0; ii < count; ii++) {
1327                 short sample;
1328                 s16 d;
1329
1330                 if (0 == devpriv->aiCount) {    /* done */
1331                         d = RtdAdcFifoGet(dev); /* Read N and discard */
1332                         continue;
1333                 }
1334 #if 0
1335                 if (0 == (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY)) {     /* DEBUG */
1336                         DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1,
1337                                 count);
1338                         break;
1339                 }
1340 #endif
1341                 d = RtdAdcFifoGet(dev); /* get 2s comp value */
1342
1343                 d = d >> 3;     /* low 3 bits are marker lines */
1344                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1345                         /* convert to comedi unsigned data */
1346                         sample = d + 2048;
1347                 } else
1348                         sample = d;
1349
1350                 if (!comedi_buf_put(s->async, sample))
1351                         return -1;
1352
1353                 if (devpriv->aiCount > 0)       /* < 0, means read forever */
1354                         devpriv->aiCount--;
1355         }
1356         return 0;
1357 }
1358
1359 /*
1360   unknown amout of data is waiting in fifo.
1361 */
1362 static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
1363 {
1364         while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */
1365                 short sample;
1366                 s16 d = RtdAdcFifoGet(dev);     /* get 2s comp value */
1367
1368                 if (0 == devpriv->aiCount) {    /* done */
1369                         continue;       /* read rest */
1370                 }
1371
1372                 d = d >> 3;     /* low 3 bits are marker lines */
1373                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1374                         /* convert to comedi unsigned data */
1375                         sample = d + 2048;
1376                 } else
1377                         sample = d;
1378
1379                 if (!comedi_buf_put(s->async, sample))
1380                         return -1;
1381
1382                 if (devpriv->aiCount > 0)       /* < 0, means read forever */
1383                         devpriv->aiCount--;
1384         }
1385         return 0;
1386 }
1387
1388 #ifdef USE_DMA
1389 /*
1390   Terminate a DMA transfer and wait for everything to quiet down
1391 */
1392 void abort_dma(struct comedi_device *dev, unsigned int channel)
1393 {                               /* DMA channel 0, 1 */
1394         unsigned long dma_cs_addr;      /* the control/status register */
1395         uint8_t status;
1396         unsigned int ii;
1397         /* unsigned long flags; */
1398
1399         dma_cs_addr = (unsigned long)devpriv->lcfg
1400             + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
1401
1402         /*  spinlock for plx dma control/status reg */
1403         /* spin_lock_irqsave( &dev->spinlock, flags ); */
1404
1405         /*  abort dma transfer if necessary */
1406         status = readb(dma_cs_addr);
1407         if ((status & PLX_DMA_EN_BIT) == 0) {   /* not enabled (Error?) */
1408                 DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
1409                         channel, status);
1410                 goto abortDmaExit;
1411         }
1412
1413         /* wait to make sure done bit is zero (needed?) */
1414         for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) {
1415                 WAIT_QUIETLY;
1416                 status = readb(dma_cs_addr);
1417         }
1418         if (status & PLX_DMA_DONE_BIT) {
1419                 printk("rtd520: Timeout waiting for dma %i done clear\n",
1420                        channel);
1421                 goto abortDmaExit;
1422         }
1423
1424         /* disable channel (required) */
1425         writeb(0, dma_cs_addr);
1426         udelay(1);              /* needed?? */
1427         /* set abort bit for channel */
1428         writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
1429
1430         /*  wait for dma done bit to be set */
1431         status = readb(dma_cs_addr);
1432         for (ii = 0;
1433              (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) {
1434                 status = readb(dma_cs_addr);
1435                 WAIT_QUIETLY;
1436         }
1437         if ((status & PLX_DMA_DONE_BIT) == 0) {
1438                 printk("rtd520: Timeout waiting for dma %i done set\n",
1439                        channel);
1440         }
1441
1442 abortDmaExit:
1443         /* spin_unlock_irqrestore( &dev->spinlock, flags ); */
1444 }
1445
1446 /*
1447   Process what is in the DMA transfer buffer and pass to comedi
1448   Note: this is not re-entrant
1449 */
1450 static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1451 {
1452         int ii, n;
1453         s16 *dp;
1454
1455         if (devpriv->aiCount == 0)      /* transfer already complete */
1456                 return 0;
1457
1458         dp = devpriv->dma0Buff[devpriv->dma0Offset];
1459         for (ii = 0; ii < devpriv->fifoLen / 2;) {      /* convert samples */
1460                 short sample;
1461
1462                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1463                         sample = (*dp >> 3) + 2048;     /* convert to comedi unsigned data */
1464                 else
1465                         sample = *dp >> 3;      /* low 3 bits are marker lines */
1466
1467                 *dp++ = sample; /* put processed value back */
1468
1469                 if (++s->async->cur_chan >= s->async->cmd.chanlist_len)
1470                         s->async->cur_chan = 0;
1471
1472                 ++ii;           /* number ready to transfer */
1473                 if (devpriv->aiCount > 0) {     /* < 0, means read forever */
1474                         if (--devpriv->aiCount == 0) {  /* done */
1475                                 /*DPRINTK ("rtd520: Final %d samples\n", ii); */
1476                                 break;
1477                         }
1478                 }
1479         }
1480
1481         /* now pass the whole array to the comedi buffer */
1482         dp = devpriv->dma0Buff[devpriv->dma0Offset];
1483         n = comedi_buf_write_alloc(s->async, ii * sizeof(s16));
1484         if (n < (ii * sizeof(s16))) {   /* any residual is an error */
1485                 DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n",
1486                         ii - (n / sizeof(s16)));
1487                 s->async->events |= COMEDI_CB_ERROR;
1488                 return -1;
1489         }
1490         comedi_buf_memcpy_to(s->async, 0, dp, n);
1491         comedi_buf_write_free(s->async, n);
1492
1493         /*
1494          * always at least 1 scan -- 1/2 FIFO is larger than our max scan list
1495          */
1496         s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
1497
1498         if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */
1499                 devpriv->dma0Offset = 0;
1500         }
1501         return 0;
1502 }
1503 #endif /* USE_DMA */
1504
1505 /*
1506   Handle all rtd520 interrupts.
1507   Runs atomically and is never re-entered.
1508   This is a "slow handler";  other interrupts may be active.
1509   The data conversion may someday happen in a "bottom half".
1510 */
1511 static irqreturn_t rtd_interrupt(int irq,       /* interrupt number (ignored) */
1512                                  void *d)
1513 {                               /* our data *//* cpu context (ignored) */
1514         struct comedi_device *dev = d;  /* must be called "dev" for devpriv */
1515         u16 status;
1516         u16 fifoStatus;
1517         struct comedi_subdevice *s = dev->subdevices + 0;       /* analog in subdevice */
1518
1519         if (!dev->attached)
1520                 return IRQ_NONE;
1521
1522         devpriv->intCount++;    /* DEBUG statistics */
1523
1524         fifoStatus = RtdFifoStatus(dev);
1525         /* check for FIFO full, this automatically halts the ADC! */
1526         if (!(fifoStatus & FS_ADC_NOT_FULL)) {  /* 0 -> full */
1527                 DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777);       /* should be all 0s */
1528                 goto abortTransfer;
1529         }
1530 #ifdef USE_DMA
1531         if (devpriv->flags & DMA0_ACTIVE) {     /* Check DMA */
1532                 u32 istatus = RtdPlxInterruptRead(dev);
1533
1534                 if (istatus & ICS_DMA0_A) {
1535                         if (ai_process_dma(dev, s) < 0) {
1536                                 DPRINTK
1537                                     ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n",
1538                                      devpriv->aiCount);
1539                                 RtdDma0Control(dev,
1540                                                (devpriv->dma0Control &
1541                                                 ~PLX_DMA_START_BIT)
1542                                                | PLX_CLEAR_DMA_INTR_BIT);
1543                                 goto abortTransfer;
1544                         }
1545
1546                         /*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n",
1547                            devpriv->aiCount, istatus); */
1548                         RtdDma0Control(dev,
1549                                        (devpriv->
1550                                         dma0Control & ~PLX_DMA_START_BIT)
1551                                        | PLX_CLEAR_DMA_INTR_BIT);
1552                         if (0 == devpriv->aiCount) {    /* counted down */
1553                                 DPRINTK("rtd520: Samples Done (DMA).\n");
1554                                 goto transferDone;
1555                         }
1556                         comedi_event(dev, s);
1557                 } else {
1558                         /*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus); */
1559                 }
1560         }
1561         /* Fall through and check for other interrupt sources */
1562 #endif /* USE_DMA */
1563
1564         status = RtdInterruptStatus(dev);
1565         /* if interrupt was not caused by our board, or handled above */
1566         if (0 == status)
1567                 return IRQ_HANDLED;
1568
1569         if (status & IRQM_ADC_ABOUT_CNT) {      /* sample count -> read FIFO */
1570                 /* since the priority interrupt controller may have queued a sample
1571                    counter interrupt, even though we have already finished,
1572                    we must handle the possibility that there is no data here */
1573                 if (!(fifoStatus & FS_ADC_HEMPTY)) {    /* 0 -> 1/2 full */
1574                         /*DPRINTK("rtd520: Sample int, reading 1/2FIFO.  fifo_status 0x%x\n",
1575                            (fifoStatus ^ 0x6666) & 0x7777); */
1576                         if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) {
1577                                 DPRINTK
1578                                     ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n",
1579                                      devpriv->aiCount);
1580                                 goto abortTransfer;
1581                         }
1582                         if (0 == devpriv->aiCount) {    /* counted down */
1583                                 DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777);  /* should be all 0s */
1584                                 goto transferDone;
1585                         }
1586                         comedi_event(dev, s);
1587                 } else if (devpriv->transCount > 0) {   /* read often */
1588                         /*DPRINTK("rtd520: Sample int, reading %d  fifo_status 0x%x\n",
1589                            devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */
1590                         if (fifoStatus & FS_ADC_NOT_EMPTY) {    /* 1 -> not empty */
1591                                 if (ai_read_n(dev, s, devpriv->transCount) < 0) {
1592                                         DPRINTK
1593                                             ("rtd520: comedi read buffer overflow (N) with %ld to go!\n",
1594                                              devpriv->aiCount);
1595                                         goto abortTransfer;
1596                                 }
1597                                 if (0 == devpriv->aiCount) {    /* counted down */
1598                                         DPRINTK
1599                                             ("rtd520: Samples Done (N). fifo_status was 0x%x\n",
1600                                              (fifoStatus ^ 0x6666) & 0x7777);
1601                                         goto transferDone;
1602                                 }
1603                                 comedi_event(dev, s);
1604                         }
1605                 } else {        /* wait for 1/2 FIFO (old) */
1606                         DPRINTK
1607                             ("rtd520: Sample int.  Wait for 1/2. fifo_status 0x%x\n",
1608                              (fifoStatus ^ 0x6666) & 0x7777);
1609                 }
1610         } else {
1611                 DPRINTK("rtd520: unknown interrupt source!\n");
1612         }
1613
1614         if (0xffff & RtdInterruptOverrunStatus(dev)) {  /* interrupt overrun */
1615                 DPRINTK
1616                     ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n",
1617                      devpriv->aiCount, 0xffff & RtdInterruptOverrunStatus(dev));
1618                 goto abortTransfer;
1619         }
1620
1621         /* clear the interrupt */
1622         RtdInterruptClearMask(dev, status);
1623         RtdInterruptClear(dev);
1624         return IRQ_HANDLED;
1625
1626 abortTransfer:
1627         RtdAdcClearFifo(dev);   /* clears full flag */
1628         s->async->events |= COMEDI_CB_ERROR;
1629         devpriv->aiCount = 0;   /* stop and don't transfer any more */
1630         /* fall into transferDone */
1631
1632 transferDone:
1633         RtdPacerStopSource(dev, 0);     /* stop on SOFTWARE stop */
1634         RtdPacerStop(dev);      /* Stop PACER */
1635         RtdAdcConversionSource(dev, 0); /* software trigger only */
1636         RtdInterruptMask(dev, 0);       /* mask out SAMPLE */
1637 #ifdef USE_DMA
1638         if (devpriv->flags & DMA0_ACTIVE) {
1639                 RtdPlxInterruptWrite(dev,       /* disable any more interrupts */
1640                                      RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
1641                 abort_dma(dev, 0);
1642                 devpriv->flags &= ~DMA0_ACTIVE;
1643                 /* if Using DMA, then we should have read everything by now */
1644                 if (devpriv->aiCount > 0) {
1645                         DPRINTK("rtd520: Lost DMA data! %ld remain\n",
1646                                 devpriv->aiCount);
1647                 }
1648         }
1649 #endif /* USE_DMA */
1650
1651         if (devpriv->aiCount > 0) {     /* there shouldn't be anything left */
1652                 fifoStatus = RtdFifoStatus(dev);
1653                 DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777);   /* should read all 0s */
1654                 ai_read_dregs(dev, s);  /* read anything left in FIFO */
1655         }
1656
1657         s->async->events |= COMEDI_CB_EOA;      /* signal end to comedi */
1658         comedi_event(dev, s);
1659
1660         /* clear the interrupt */
1661         status = RtdInterruptStatus(dev);
1662         RtdInterruptClearMask(dev, status);
1663         RtdInterruptClear(dev);
1664
1665         fifoStatus = RtdFifoStatus(dev);        /* DEBUG */
1666         DPRINTK
1667             ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n",
1668              devpriv->intCount, status,
1669              0xffff & RtdInterruptOverrunStatus(dev));
1670
1671         return IRQ_HANDLED;
1672 }
1673
1674 #if 0
1675 /*
1676   return the number of samples available
1677 */
1678 static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
1679 {
1680         /* TODO: This needs to mask interrupts, read_dregs, and then re-enable */
1681         /* Not sure what to do if DMA is active */
1682         return s->async->buf_write_count - s->async->buf_read_count;
1683 }
1684 #endif
1685
1686 /*
1687   cmdtest tests a particular command to see if it is valid.
1688   Using the cmdtest ioctl, a user can create a valid cmd
1689   and then have it executed by the cmd ioctl (asyncronously).
1690
1691   cmdtest returns 1,2,3,4 or 0, depending on which tests
1692   the command passes.
1693 */
1694
1695 static int rtd_ai_cmdtest(struct comedi_device *dev,
1696                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
1697 {
1698         int err = 0;
1699         int tmp;
1700
1701         /* step 1: make sure trigger sources are trivially valid */
1702
1703         tmp = cmd->start_src;
1704         cmd->start_src &= TRIG_NOW;
1705         if (!cmd->start_src || tmp != cmd->start_src)
1706                 err++;
1707
1708         tmp = cmd->scan_begin_src;
1709         cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1710         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1711                 err++;
1712
1713
1714         tmp = cmd->convert_src;
1715         cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1716         if (!cmd->convert_src || tmp != cmd->convert_src)
1717                 err++;
1718
1719
1720         tmp = cmd->scan_end_src;
1721         cmd->scan_end_src &= TRIG_COUNT;
1722         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1723                 err++;
1724
1725
1726         tmp = cmd->stop_src;
1727         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1728         if (!cmd->stop_src || tmp != cmd->stop_src)
1729                 err++;
1730
1731
1732         if (err)
1733                 return 1;
1734
1735         /* step 2: make sure trigger sources are unique
1736            and mutually compatible */
1737         /* note that mutual compatibility is not an issue here */
1738         if (cmd->scan_begin_src != TRIG_TIMER &&
1739             cmd->scan_begin_src != TRIG_EXT) {
1740                 err++;
1741         }
1742         if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
1743                 err++;
1744
1745         if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1746                 err++;
1747
1748         if (err)
1749                 return 2;
1750
1751         /* step 3: make sure arguments are trivially compatible */
1752
1753         if (cmd->start_arg != 0) {
1754                 cmd->start_arg = 0;
1755                 err++;
1756         }
1757
1758         if (cmd->scan_begin_src == TRIG_TIMER) {
1759                 /* Note: these are time periods, not actual rates */
1760                 if (1 == cmd->chanlist_len) {   /* no scanning */
1761                         if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) {
1762                                 cmd->scan_begin_arg = RTD_MAX_SPEED_1;
1763                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
1764                                                 TRIG_ROUND_UP);
1765                                 err++;
1766                         }
1767                         if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) {
1768                                 cmd->scan_begin_arg = RTD_MIN_SPEED_1;
1769                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
1770                                                 TRIG_ROUND_DOWN);
1771                                 err++;
1772                         }
1773                 } else {
1774                         if (cmd->scan_begin_arg < RTD_MAX_SPEED) {
1775                                 cmd->scan_begin_arg = RTD_MAX_SPEED;
1776                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
1777                                                 TRIG_ROUND_UP);
1778                                 err++;
1779                         }
1780                         if (cmd->scan_begin_arg > RTD_MIN_SPEED) {
1781                                 cmd->scan_begin_arg = RTD_MIN_SPEED;
1782                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
1783                                                 TRIG_ROUND_DOWN);
1784                                 err++;
1785                         }
1786                 }
1787         } else {
1788                 /* external trigger */
1789                 /* should be level/edge, hi/lo specification here */
1790                 /* should specify multiple external triggers */
1791                 if (cmd->scan_begin_arg > 9) {
1792                         cmd->scan_begin_arg = 9;
1793                         err++;
1794                 }
1795         }
1796         if (cmd->convert_src == TRIG_TIMER) {
1797                 if (1 == cmd->chanlist_len) {   /* no scanning */
1798                         if (cmd->convert_arg < RTD_MAX_SPEED_1) {
1799                                 cmd->convert_arg = RTD_MAX_SPEED_1;
1800                                 rtd_ns_to_timer(&cmd->convert_arg,
1801                                                 TRIG_ROUND_UP);
1802                                 err++;
1803                         }
1804                         if (cmd->convert_arg > RTD_MIN_SPEED_1) {
1805                                 cmd->convert_arg = RTD_MIN_SPEED_1;
1806                                 rtd_ns_to_timer(&cmd->convert_arg,
1807                                                 TRIG_ROUND_DOWN);
1808                                 err++;
1809                         }
1810                 } else {
1811                         if (cmd->convert_arg < RTD_MAX_SPEED) {
1812                                 cmd->convert_arg = RTD_MAX_SPEED;
1813                                 rtd_ns_to_timer(&cmd->convert_arg,
1814                                                 TRIG_ROUND_UP);
1815                                 err++;
1816                         }
1817                         if (cmd->convert_arg > RTD_MIN_SPEED) {
1818                                 cmd->convert_arg = RTD_MIN_SPEED;
1819                                 rtd_ns_to_timer(&cmd->convert_arg,
1820                                                 TRIG_ROUND_DOWN);
1821                                 err++;
1822                         }
1823                 }
1824         } else {
1825                 /* external trigger */
1826                 /* see above */
1827                 if (cmd->convert_arg > 9) {
1828                         cmd->convert_arg = 9;
1829                         err++;
1830                 }
1831         }
1832
1833 #if 0
1834         if (cmd->scan_end_arg != cmd->chanlist_len) {
1835                 cmd->scan_end_arg = cmd->chanlist_len;
1836                 err++;
1837         }
1838 #endif
1839         if (cmd->stop_src == TRIG_COUNT) {
1840                 /* TODO check for rounding error due to counter wrap */
1841
1842         } else {
1843                 /* TRIG_NONE */
1844                 if (cmd->stop_arg != 0) {
1845                         cmd->stop_arg = 0;
1846                         err++;
1847                 }
1848         }
1849
1850         if (err)
1851                 return 3;
1852
1853
1854         /* step 4: fix up any arguments */
1855
1856         if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
1857                 cmd->chanlist_len = RTD_MAX_CHANLIST;
1858                 err++;
1859         }
1860         if (cmd->scan_begin_src == TRIG_TIMER) {
1861                 tmp = cmd->scan_begin_arg;
1862                 rtd_ns_to_timer(&cmd->scan_begin_arg,
1863                                 cmd->flags & TRIG_ROUND_MASK);
1864                 if (tmp != cmd->scan_begin_arg)
1865                         err++;
1866
1867         }
1868         if (cmd->convert_src == TRIG_TIMER) {
1869                 tmp = cmd->convert_arg;
1870                 rtd_ns_to_timer(&cmd->convert_arg,
1871                                 cmd->flags & TRIG_ROUND_MASK);
1872                 if (tmp != cmd->convert_arg)
1873                         err++;
1874
1875                 if (cmd->scan_begin_src == TRIG_TIMER
1876                     && (cmd->scan_begin_arg
1877                         < (cmd->convert_arg * cmd->scan_end_arg))) {
1878                         cmd->scan_begin_arg =
1879                             cmd->convert_arg * cmd->scan_end_arg;
1880                         err++;
1881                 }
1882         }
1883
1884         if (err)
1885                 return 4;
1886
1887         return 0;
1888 }
1889
1890 /*
1891   Execute a analog in command with many possible triggering options.
1892   The data get stored in the async structure of the subdevice.
1893   This is usually done by an interrupt handler.
1894   Userland gets to the data using read calls.
1895 */
1896 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1897 {
1898         struct comedi_cmd *cmd = &s->async->cmd;
1899         int timer;
1900
1901         /* stop anything currently running */
1902         RtdPacerStopSource(dev, 0);     /* stop on SOFTWARE stop */
1903         RtdPacerStop(dev);      /* make sure PACER is stopped */
1904         RtdAdcConversionSource(dev, 0); /* software trigger only */
1905         RtdInterruptMask(dev, 0);
1906 #ifdef USE_DMA
1907         if (devpriv->flags & DMA0_ACTIVE) {     /* cancel anything running */
1908                 RtdPlxInterruptWrite(dev,       /* disable any more interrupts */
1909                                      RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
1910                 abort_dma(dev, 0);
1911                 devpriv->flags &= ~DMA0_ACTIVE;
1912                 if (RtdPlxInterruptRead(dev) & ICS_DMA0_A) {    /*clear pending int */
1913                         RtdDma0Control(dev, PLX_CLEAR_DMA_INTR_BIT);
1914                 }
1915         }
1916         RtdDma0Reset(dev);      /* reset onboard state */
1917 #endif /* USE_DMA */
1918         RtdAdcClearFifo(dev);   /* clear any old data */
1919         RtdInterruptOverrunClear(dev);
1920         devpriv->intCount = 0;
1921
1922         if (!dev->irq) {        /* we need interrupts for this */
1923                 DPRINTK("rtd520: ERROR! No interrupt available!\n");
1924                 return -ENXIO;
1925         }
1926
1927         /* start configuration */
1928         /* load channel list and reset CGT */
1929         rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
1930
1931         /* setup the common case and override if needed */
1932         if (cmd->chanlist_len > 1) {
1933                 /*DPRINTK ("rtd520: Multi channel setup\n"); */
1934                 RtdPacerStartSource(dev, 0);    /* software triggers pacer */
1935                 RtdBurstStartSource(dev, 1);    /* PACER triggers burst */
1936                 RtdAdcConversionSource(dev, 2); /* BURST triggers ADC */
1937         } else {                /* single channel */
1938                 /*DPRINTK ("rtd520: single channel setup\n"); */
1939                 RtdPacerStartSource(dev, 0);    /* software triggers pacer */
1940                 RtdAdcConversionSource(dev, 1); /* PACER triggers ADC */
1941         }
1942         RtdAboutCounter(dev, devpriv->fifoLen / 2 - 1); /* 1/2 FIFO */
1943
1944         if (TRIG_TIMER == cmd->scan_begin_src) {
1945                 /* scan_begin_arg is in nanoseconds */
1946                 /* find out how many samples to wait before transferring */
1947                 if (cmd->flags & TRIG_WAKE_EOS) {
1948                         /* this may generate un-sustainable interrupt rates */
1949                         /* the application is responsible for doing the right thing */
1950                         devpriv->transCount = cmd->chanlist_len;
1951                         devpriv->flags |= SEND_EOS;
1952                 } else {
1953                         /* arrange to transfer data periodically */
1954                         devpriv->transCount
1955                             =
1956                             (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
1957                             cmd->scan_begin_arg;
1958                         if (devpriv->transCount < cmd->chanlist_len) {
1959                                 /* transfer after each scan (and avoid 0) */
1960                                 devpriv->transCount = cmd->chanlist_len;
1961                         } else {        /* make a multiple of scan length */
1962                                 devpriv->transCount =
1963                                     (devpriv->transCount +
1964                                      cmd->chanlist_len - 1)
1965                                     / cmd->chanlist_len;
1966                                 devpriv->transCount *= cmd->chanlist_len;
1967                         }
1968                         devpriv->flags |= SEND_EOS;
1969                 }
1970                 if (devpriv->transCount >= (devpriv->fifoLen / 2)) {
1971                         /* out of counter range, use 1/2 fifo instead */
1972                         devpriv->transCount = 0;
1973                         devpriv->flags &= ~SEND_EOS;
1974                 } else {
1975                         /* interrupt for each transfer */
1976                         RtdAboutCounter(dev, devpriv->transCount - 1);
1977                 }
1978
1979                 DPRINTK
1980                     ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n  scanTime(ns)=%d flags=0x%x\n",
1981                      cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen,
1982                      cmd->scan_begin_arg, devpriv->flags);
1983         } else {                /* unknown timing, just use 1/2 FIFO */
1984                 devpriv->transCount = 0;
1985                 devpriv->flags &= ~SEND_EOS;
1986         }
1987         RtdPacerClockSource(dev, 1);    /* use INTERNAL 8Mhz clock source */
1988         RtdAboutStopEnable(dev, 1);     /* just interrupt, dont stop */
1989
1990         /* BUG??? these look like enumerated values, but they are bit fields */
1991
1992         /* First, setup when to stop */
1993         switch (cmd->stop_src) {
1994         case TRIG_COUNT:        /* stop after N scans */
1995                 devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len;
1996                 if ((devpriv->transCount > 0)
1997                     && (devpriv->transCount > devpriv->aiCount)) {
1998                         devpriv->transCount = devpriv->aiCount;
1999                 }
2000                 break;
2001
2002         case TRIG_NONE: /* stop when cancel is called */
2003                 devpriv->aiCount = -1;  /* read forever */
2004                 break;
2005
2006         default:
2007                 DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n",
2008                         cmd->stop_src);
2009         }
2010
2011         /* Scan timing */
2012         switch (cmd->scan_begin_src) {
2013         case TRIG_TIMER:        /* periodic scanning */
2014                 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
2015                                         TRIG_ROUND_NEAREST);
2016                 /* set PACER clock */
2017                 /*DPRINTK ("rtd520: loading %d into pacer\n", timer); */
2018                 RtdPacerCounter(dev, timer);
2019
2020                 break;
2021
2022         case TRIG_EXT:
2023                 RtdPacerStartSource(dev, 1);    /* EXTERNALy trigger pacer */
2024                 break;
2025
2026         default:
2027                 DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n",
2028                         cmd->scan_begin_src);
2029         }
2030
2031         /* Sample timing within a scan */
2032         switch (cmd->convert_src) {
2033         case TRIG_TIMER:        /* periodic */
2034                 if (cmd->chanlist_len > 1) {    /* only needed for multi-channel */
2035                         timer = rtd_ns_to_timer(&cmd->convert_arg,
2036                                                 TRIG_ROUND_NEAREST);
2037                         /* setup BURST clock */
2038                         /*DPRINTK ("rtd520: loading %d into burst\n", timer); */
2039                         RtdBurstCounter(dev, timer);
2040                 }
2041
2042                 break;
2043
2044         case TRIG_EXT:          /* external */
2045                 RtdBurstStartSource(dev, 2);    /* EXTERNALy trigger burst */
2046                 break;
2047
2048         default:
2049                 DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n",
2050                         cmd->convert_src);
2051         }
2052         /* end configuration */
2053
2054         /* This doesn't seem to work.  There is no way to clear an interrupt
2055            that the priority controller has queued! */
2056         RtdInterruptClearMask(dev, ~0); /* clear any existing flags */
2057         RtdInterruptClear(dev);
2058
2059         /* TODO: allow multiple interrupt sources */
2060         if (devpriv->transCount > 0) {  /* transfer every N samples */
2061                 RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT);
2062                 DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount);
2063         } else {                /* 1/2 FIFO transfers */
2064 #ifdef USE_DMA
2065                 devpriv->flags |= DMA0_ACTIVE;
2066
2067                 /* point to first transfer in ring */
2068                 devpriv->dma0Offset = 0;
2069                 RtdDma0Mode(dev, DMA_MODE_BITS);
2070                 RtdDma0Next(dev,        /* point to first block */
2071                             devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next);
2072                 RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL);      /* set DMA trigger source */
2073
2074                 RtdPlxInterruptWrite(dev,       /* enable interrupt */
2075                                      RtdPlxInterruptRead(dev) | ICS_DMA0_E);
2076                 /* Must be 2 steps.  See PLX app note about "Starting a DMA transfer" */
2077                 RtdDma0Control(dev, PLX_DMA_EN_BIT);    /* enable DMA (clear INTR?) */
2078                 RtdDma0Control(dev, PLX_DMA_EN_BIT | PLX_DMA_START_BIT);        /*start DMA */
2079                 DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n",
2080                         RtdPlxInterruptRead(dev), devpriv->intMask);
2081 #else /* USE_DMA */
2082                 RtdInterruptMask(dev, IRQM_ADC_ABOUT_CNT);
2083                 DPRINTK("rtd520: Transferring every 1/2 FIFO\n");
2084 #endif /* USE_DMA */
2085         }
2086
2087         /* BUG: start_src is ASSUMED to be TRIG_NOW */
2088         /* BUG? it seems like things are running before the "start" */
2089         RtdPacerStart(dev);     /* Start PACER */
2090         return 0;
2091 }
2092
2093 /*
2094   Stop a running data acquisition.
2095 */
2096 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
2097 {
2098         u16 status;
2099
2100         RtdPacerStopSource(dev, 0);     /* stop on SOFTWARE stop */
2101         RtdPacerStop(dev);      /* Stop PACER */
2102         RtdAdcConversionSource(dev, 0); /* software trigger only */
2103         RtdInterruptMask(dev, 0);
2104         devpriv->aiCount = 0;   /* stop and don't transfer any more */
2105 #ifdef USE_DMA
2106         if (devpriv->flags & DMA0_ACTIVE) {
2107                 RtdPlxInterruptWrite(dev,       /* disable any more interrupts */
2108                                      RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
2109                 abort_dma(dev, 0);
2110                 devpriv->flags &= ~DMA0_ACTIVE;
2111         }
2112 #endif /* USE_DMA */
2113         status = RtdInterruptStatus(dev);
2114         DPRINTK
2115             ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n",
2116              devpriv->intCount, status,
2117              0xffff & RtdInterruptOverrunStatus(dev));
2118         return 0;
2119 }
2120
2121 /*
2122   Given a desired period and the clock period (both in ns),
2123   return the proper counter value (divider-1).
2124   Sets the original period to be the true value.
2125   Note: you have to check if the value is larger than the counter range!
2126 */
2127 static int rtd_ns_to_timer_base(unsigned int *nanosec,  /* desired period (in ns) */
2128                                 int round_mode, int base)
2129 {                               /* clock period (in ns) */
2130         int divider;
2131
2132         switch (round_mode) {
2133         case TRIG_ROUND_NEAREST:
2134         default:
2135                 divider = (*nanosec + base / 2) / base;
2136                 break;
2137         case TRIG_ROUND_DOWN:
2138                 divider = (*nanosec) / base;
2139                 break;
2140         case TRIG_ROUND_UP:
2141                 divider = (*nanosec + base - 1) / base;
2142                 break;
2143         }
2144         if (divider < 2)
2145                 divider = 2;    /* min is divide by 2 */
2146
2147         /* Note: we don't check for max, because different timers
2148            have different ranges */
2149
2150         *nanosec = base * divider;
2151         return divider - 1;     /* countdown is divisor+1 */
2152 }
2153
2154 /*
2155   Given a desired period (in ns),
2156   return the proper counter value (divider-1) for the internal clock.
2157   Sets the original period to be the true value.
2158 */
2159 static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
2160 {
2161         return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
2162 }
2163
2164 /*
2165   Output one (or more) analog values to a single port as fast as possible.
2166 */
2167 static int rtd_ao_winsn(struct comedi_device *dev,
2168                         struct comedi_subdevice *s, struct comedi_insn *insn,
2169                         unsigned int *data)
2170 {
2171         int i;
2172         int chan = CR_CHAN(insn->chanspec);
2173         int range = CR_RANGE(insn->chanspec);
2174
2175         /* Configure the output range (table index matches the range values) */
2176         RtdDacRange(dev, chan, range);
2177
2178         /* Writing a list of values to an AO channel is probably not
2179          * very useful, but that's how the interface is defined. */
2180         for (i = 0; i < insn->n; ++i) {
2181                 int val = data[i] << 3;
2182                 int stat = 0;   /* initialize to avoid bogus warning */
2183                 int ii;
2184
2185                 /* VERIFY: comedi range and offset conversions */
2186
2187                 if ((range > 1) /* bipolar */
2188                     && (data[i] < 2048)) {
2189                         /* offset and sign extend */
2190                         val = (((int)data[i]) - 2048) << 3;
2191                 } else {        /* unipolor */
2192                         val = data[i] << 3;
2193                 }
2194
2195                 DPRINTK
2196                     ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n",
2197                      chan, range, data[i], val);
2198
2199                 /* a typical programming sequence */
2200                 RtdDacFifoPut(dev, chan, val);  /* put the value in */
2201                 RtdDacUpdate(dev, chan);        /* trigger the conversion */
2202
2203                 devpriv->aoValue[chan] = data[i];       /* save for read back */
2204
2205                 for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
2206                         stat = RtdFifoStatus(dev);
2207                         /* 1 -> not empty */
2208                         if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
2209                                     FS_DAC2_NOT_EMPTY))
2210                                 break;
2211                         WAIT_QUIETLY;
2212                 }
2213                 if (ii >= RTD_DAC_TIMEOUT) {
2214                         DPRINTK
2215                             ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n",
2216                              stat ^ 0x6666);
2217                         return -ETIMEDOUT;
2218                 }
2219         }
2220
2221         /* return the number of samples read/written */
2222         return i;
2223 }
2224
2225 /* AO subdevices should have a read insn as well as a write insn.
2226  * Usually this means copying a value stored in devpriv. */
2227 static int rtd_ao_rinsn(struct comedi_device *dev,
2228                         struct comedi_subdevice *s, struct comedi_insn *insn,
2229                         unsigned int *data)
2230 {
2231         int i;
2232         int chan = CR_CHAN(insn->chanspec);
2233
2234         for (i = 0; i < insn->n; i++)
2235                 data[i] = devpriv->aoValue[chan];
2236
2237
2238         return i;
2239 }
2240
2241 /*
2242    Write a masked set of bits and the read back the port.
2243    We track what the bits should be (i.e. we don't read the port first).
2244
2245    DIO devices are slightly special.  Although it is possible to
2246  * implement the insn_read/insn_write interface, it is much more
2247  * useful to applications if you implement the insn_bits interface.
2248  * This allows packed reading/writing of the DIO channels.  The
2249  * comedi core can convert between insn_bits and insn_read/write
2250  */
2251 static int rtd_dio_insn_bits(struct comedi_device *dev,
2252                              struct comedi_subdevice *s,
2253                              struct comedi_insn *insn, unsigned int *data)
2254 {
2255         if (insn->n != 2)
2256                 return -EINVAL;
2257
2258         /* The insn data is a mask in data[0] and the new data
2259          * in data[1], each channel cooresponding to a bit. */
2260         if (data[0]) {
2261                 s->state &= ~data[0];
2262                 s->state |= data[0] & data[1];
2263
2264                 /* Write out the new digital output lines */
2265                 RtdDio0Write(dev, s->state);
2266         }
2267         /* on return, data[1] contains the value of the digital
2268          * input lines. */
2269         data[1] = RtdDio0Read(dev);
2270
2271         /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */
2272
2273         return 2;
2274 }
2275
2276 /*
2277   Configure one bit on a IO port as Input or Output (hence the name :-).
2278 */
2279 static int rtd_dio_insn_config(struct comedi_device *dev,
2280                                struct comedi_subdevice *s,
2281                                struct comedi_insn *insn, unsigned int *data)
2282 {
2283         int chan = CR_CHAN(insn->chanspec);
2284
2285         /* The input or output configuration of each digital line is
2286          * configured by a special insn_config instruction.  chanspec
2287          * contains the channel to be changed, and data[0] contains the
2288          * value COMEDI_INPUT or COMEDI_OUTPUT. */
2289         switch (data[0]) {
2290         case INSN_CONFIG_DIO_OUTPUT:
2291                 s->io_bits |= 1 << chan;        /* 1 means Out */
2292                 break;
2293         case INSN_CONFIG_DIO_INPUT:
2294                 s->io_bits &= ~(1 << chan);
2295                 break;
2296         case INSN_CONFIG_DIO_QUERY:
2297                 data[1] =
2298                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
2299                 return insn->n;
2300                 break;
2301         default:
2302                 return -EINVAL;
2303         }
2304
2305         DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits);
2306         /* TODO support digital match interrupts and strobes */
2307         RtdDioStatusWrite(dev, 0x01);   /* make Dio0Ctrl point to direction */
2308         RtdDio0CtrlWrite(dev, s->io_bits);      /* set direction 1 means Out */
2309         RtdDioStatusWrite(dev, 0);      /* make Dio0Ctrl clear interrupts */
2310
2311         /* port1 can only be all input or all output */
2312
2313         /* there are also 2 user input lines and 2 user output lines */
2314
2315         return 1;
2316 }
2317
2318 static struct comedi_driver rtd520_driver = {
2319         .driver_name    = "rtd520",
2320         .module         = THIS_MODULE,
2321         .attach         = rtd_attach,
2322         .detach         = rtd_detach,
2323 };
2324
2325 static int __devinit rtd520_pci_probe(struct pci_dev *dev,
2326                                       const struct pci_device_id *ent)
2327 {
2328         return comedi_pci_auto_config(dev, &rtd520_driver);
2329 }
2330
2331 static void __devexit rtd520_pci_remove(struct pci_dev *dev)
2332 {
2333         comedi_pci_auto_unconfig(dev);
2334 }
2335
2336 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
2337         { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) },
2338         { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) },
2339         { 0 }
2340 };
2341 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
2342
2343 static struct pci_driver rtd520_pci_driver = {
2344         .name           = "rtd520",
2345         .id_table       = rtd520_pci_table,
2346         .probe          = rtd520_pci_probe,
2347         .remove         = __devexit_p(rtd520_pci_remove),
2348 };
2349 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
2350
2351 MODULE_AUTHOR("Comedi http://www.comedi.org");
2352 MODULE_DESCRIPTION("Comedi low-level driver");
2353 MODULE_LICENSE("GPL");