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