Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / comedi / drivers / rtd520.c
1 /*
2     comedi/drivers/rtd520.c
3     Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 2001 David A. Schleef <ds@schleef.org>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 /*
23 Driver: rtd520
24 Description: Real Time Devices PCI4520/DM7520
25 Author: Dan Christian
26 Devices: [Real Time Devices] DM7520HR-1 (rtd520), DM7520HR-8,
27   PCI4520, PCI4520-8
28 Status: Works.  Only tested on DM7520-8.  Not SMP safe.
29
30 Configuration options:
31   [0] - PCI bus of device (optional)
32           If bus/slot is not specified, the first available PCI
33           device will be used.
34   [1] - PCI slot of device (optional)
35 */
36 /*
37     Created by Dan Christian, NASA Ames Research Center.
38
39     The PCI4520 is a PCI card.  The DM7520 is a PC/104-plus card.
40     Both have:
41     8/16 12 bit ADC with FIFO and channel gain table
42     8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
43     8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
44     2 12 bit DACs with FIFOs
45     2 bits output
46     2 bits input
47     bus mastering DMA
48     timers: ADC sample, pacer, burst, about, delay, DA1, DA2
49     sample counter
50     3 user timer/counters (8254)
51     external interrupt
52
53     The DM7520 has slightly fewer features (fewer gain steps).
54
55     These boards can support external multiplexors and multi-board
56     synchronization, but this driver doesn't support that.
57
58     Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
59     Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
60     Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
61     Call them and ask for the register level manual.
62     PCI chip: http://www.plxtech.com/products/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/interrupt.h>
105 #include <linux/delay.h>
106
107 #include "../comedidev.h"
108 #include "comedi_pci.h"
109
110 #define DRV_NAME "rtd520"
111
112 /*======================================================================
113   Driver specific stuff (tunable)
114 ======================================================================*/
115 /* Enable this to test the new DMA support. You may get hard lock ups */
116 /*#define USE_DMA*/
117
118 /* We really only need 2 buffers.  More than that means being much
119    smarter about knowing which ones are full. */
120 #define DMA_CHAIN_COUNT 2       /* max DMA segments/buffers in a ring (min 2) */
121
122 /* Target period for periodic transfers.  This sets the user read latency. */
123 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
124 /* If this is too low, efficiency is poor */
125 #define TRANS_TARGET_PERIOD 10000000    /* 10 ms (in nanoseconds) */
126
127 /* Set a practical limit on how long a list to support (affects memory use) */
128 /* The board support a channel list up to the FIFO length (1K or 8K) */
129 #define RTD_MAX_CHANLIST        128     /* max channel list that we allow */
130
131 /* tuning for ai/ao instruction done polling */
132 #ifdef FAST_SPIN
133 #define WAIT_QUIETLY            /* as nothing, spin on done bit */
134 #define RTD_ADC_TIMEOUT 66000   /* 2 msec at 33mhz bus rate */
135 #define RTD_DAC_TIMEOUT 66000
136 #define RTD_DMA_TIMEOUT 33000   /* 1 msec */
137 #else
138 /* by delaying, power and electrical noise are reduced somewhat */
139 #define WAIT_QUIETLY    udelay (1)
140 #define RTD_ADC_TIMEOUT 2000    /* in usec */
141 #define RTD_DAC_TIMEOUT 2000    /* in usec */
142 #define RTD_DMA_TIMEOUT 1000    /* in usec */
143 #endif
144
145 /*======================================================================
146   Board specific stuff
147 ======================================================================*/
148
149 /* registers  */
150 #define PCI_VENDOR_ID_RTD       0x1435
151 /*
152   The board has three memory windows: las0, las1, and lcfg (the PCI chip)
153   Las1 has the data and can be burst DMAed 32bits at a time.
154 */
155 #define LCFG_PCIINDEX   0
156 /* PCI region 1 is a 256 byte IO space mapping.  Use??? */
157 #define LAS0_PCIINDEX   2       /* PCI memory resources */
158 #define LAS1_PCIINDEX   3
159 #define LCFG_PCISIZE    0x100
160 #define LAS0_PCISIZE    0x200
161 #define LAS1_PCISIZE    0x10
162
163 #define RTD_CLOCK_RATE  8000000 /* 8Mhz onboard clock */
164 #define RTD_CLOCK_BASE  125     /* clock period in ns */
165
166 /* Note: these speed are slower than the spec, but fit the counter resolution*/
167 #define RTD_MAX_SPEED   1625    /* when sampling, in nanoseconds */
168 /* max speed if we don't have to wait for settling */
169 #define RTD_MAX_SPEED_1 875     /* if single channel, in nanoseconds */
170
171 #define RTD_MIN_SPEED   2097151875      /* (24bit counter) in nanoseconds */
172 /* min speed when only 1 channel (no burst counter) */
173 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
174
175 #include "rtd520.h"
176 #include "plx9080.h"
177
178 /* Setup continuous ring of 1/2 FIFO transfers.  See RTD manual p91 */
179 #define DMA_MODE_BITS (\
180                        PLX_LOCAL_BUS_16_WIDE_BITS \
181                        | PLX_DMA_EN_READYIN_BIT \
182                        | PLX_DMA_LOCAL_BURST_EN_BIT \
183                        | PLX_EN_CHAIN_BIT \
184                        | PLX_DMA_INTR_PCI_BIT \
185                        | PLX_LOCAL_ADDR_CONST_BIT \
186                        | PLX_DEMAND_MODE_BIT)
187
188 #define DMA_TRANSFER_BITS (\
189 /* descriptors in PCI memory*/  PLX_DESC_IN_PCI_BIT \
190 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
191 /* from board to PCI */         | PLX_XFER_LOCAL_TO_PCI)
192
193 /*======================================================================
194   Comedi specific stuff
195 ======================================================================*/
196
197 /*
198   The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
199 */
200 static const struct comedi_lrange rtd_ai_7520_range = { 18, {
201                         /* +-5V input range gain steps */
202                         BIP_RANGE(5.0),
203                         BIP_RANGE(5.0 / 2),
204                         BIP_RANGE(5.0 / 4),
205                         BIP_RANGE(5.0 / 8),
206                         BIP_RANGE(5.0 / 16),
207                         BIP_RANGE(5.0 / 32),
208                         /* +-10V input range gain steps */
209                         BIP_RANGE(10.0),
210                         BIP_RANGE(10.0 / 2),
211                         BIP_RANGE(10.0 / 4),
212                         BIP_RANGE(10.0 / 8),
213                         BIP_RANGE(10.0 / 16),
214                         BIP_RANGE(10.0 / 32),
215                         /* +10V input range gain steps */
216                         UNI_RANGE(10.0),
217                         UNI_RANGE(10.0 / 2),
218                         UNI_RANGE(10.0 / 4),
219                         UNI_RANGE(10.0 / 8),
220                         UNI_RANGE(10.0 / 16),
221                         UNI_RANGE(10.0 / 32),
222
223         }
224 };
225
226 /* PCI4520 has two more gains (6 more entries) */
227 static const struct comedi_lrange rtd_ai_4520_range = { 24, {
228                         /* +-5V input range gain steps */
229                         BIP_RANGE(5.0),
230                         BIP_RANGE(5.0 / 2),
231                         BIP_RANGE(5.0 / 4),
232                         BIP_RANGE(5.0 / 8),
233                         BIP_RANGE(5.0 / 16),
234                         BIP_RANGE(5.0 / 32),
235                         BIP_RANGE(5.0 / 64),
236                         BIP_RANGE(5.0 / 128),
237                         /* +-10V input range gain steps */
238                         BIP_RANGE(10.0),
239                         BIP_RANGE(10.0 / 2),
240                         BIP_RANGE(10.0 / 4),
241                         BIP_RANGE(10.0 / 8),
242                         BIP_RANGE(10.0 / 16),
243                         BIP_RANGE(10.0 / 32),
244                         BIP_RANGE(10.0 / 64),
245                         BIP_RANGE(10.0 / 128),
246                         /* +10V input range gain steps */
247                         UNI_RANGE(10.0),
248                         UNI_RANGE(10.0 / 2),
249                         UNI_RANGE(10.0 / 4),
250                         UNI_RANGE(10.0 / 8),
251                         UNI_RANGE(10.0 / 16),
252                         UNI_RANGE(10.0 / 32),
253                         UNI_RANGE(10.0 / 64),
254                         UNI_RANGE(10.0 / 128),
255         }
256 };
257
258 /* Table order matches range values */
259 static const struct comedi_lrange rtd_ao_range = { 4, {
260                         RANGE(0, 5),
261                         RANGE(0, 10),
262                         RANGE(-5, 5),
263                         RANGE(-10, 10),
264         }
265 };
266
267 /*
268   Board descriptions
269  */
270 struct rtdBoard {
271         const char *name;       /* must be first */
272         int device_id;
273         int aiChans;
274         int aiBits;
275         int aiMaxGain;
276         int range10Start;       /* start of +-10V range */
277         int rangeUniStart;      /* start of +10V range */
278 };
279
280 static const struct rtdBoard rtd520Boards[] = {
281         {
282         .name = "DM7520",
283         .device_id = 0x7520,
284         .aiChans = 16,
285         .aiBits = 12,
286         .aiMaxGain = 32,
287         .range10Start = 6,
288         .rangeUniStart = 12,
289                 },
290         {
291         .name = "PCI4520",
292         .device_id = 0x4520,
293         .aiChans = 16,
294         .aiBits = 12,
295         .aiMaxGain = 128,
296         .range10Start = 8,
297         .rangeUniStart = 16,
298                 },
299 };
300
301 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
302         {PCI_VENDOR_ID_RTD, 0x7520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
303         {PCI_VENDOR_ID_RTD, 0x4520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
304         {0}
305 };
306
307 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
308
309 /*
310  * Useful for shorthand access to the particular board structure
311  */
312 #define thisboard ((const struct rtdBoard *)dev->board_ptr)
313
314 /*
315    This structure is for data unique to this hardware driver.
316    This is also unique for each board in the system.
317 */
318 struct rtdPrivate {
319         /* memory mapped board structures */
320         void *las0;
321         void *las1;
322         void *lcfg;
323
324         unsigned long intCount; /* interrupt count */
325         long aiCount;           /* total transfer size (samples) */
326         int transCount;         /* # to tranfer data. 0->1/2FIFO */
327         int flags;              /* flag event modes */
328
329         /* PCI device info */
330         struct pci_dev *pci_dev;
331         int got_regions;        /* non-zero if PCI regions owned */
332
333         /* channel list info */
334         /* chanBipolar tracks whether a channel is bipolar (and needs +2048) */
335         unsigned char chanBipolar[RTD_MAX_CHANLIST / 8];        /* bit array */
336
337         /* read back data */
338         unsigned int aoValue[2];        /* Used for AO read back */
339
340         /* timer gate (when enabled) */
341         u8 utcGate[4];          /* 1 extra allows simple range check */
342
343         /* shadow registers affect other registers, but cant be read back */
344         /* The macros below update these on writes */
345         u16 intMask;            /* interrupt mask */
346         u16 intClearMask;       /* interrupt clear mask */
347         u8 utcCtrl[4];          /* crtl mode for 3 utc + read back */
348         u8 dioStatus;           /* could be read back (dio0Ctrl) */
349 #ifdef USE_DMA
350         /* Always DMA 1/2 FIFO.  Buffer (dmaBuff?) is (at least) twice that size.
351            After transferring, interrupt processes 1/2 FIFO and passes to comedi */
352         s16 dma0Offset;         /* current processing offset (0, 1/2) */
353         uint16_t *dma0Buff[DMA_CHAIN_COUNT];    /* DMA buffers (for ADC) */
354         dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT];   /* physical addresses */
355         struct plx_dma_desc *dma0Chain; /* DMA descriptor ring for dmaBuff */
356         dma_addr_t dma0ChainPhysAddr;   /* physical addresses */
357         /* shadow registers */
358         u8 dma0Control;
359         u8 dma1Control;
360 #endif                          /* USE_DMA */
361         unsigned fifoLen;
362 };
363
364 /* bit defines for "flags" */
365 #define SEND_EOS        0x01    /* send End Of Scan events */
366 #define DMA0_ACTIVE     0x02    /* DMA0 is active */
367 #define DMA1_ACTIVE     0x04    /* DMA1 is active */
368
369 /* Macros for accessing channel list bit array */
370 #define CHAN_ARRAY_TEST(array, index) \
371         (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
372 #define CHAN_ARRAY_SET(array, index) \
373         (((array)[(index)/8] |= 1 << ((index) & 0x7)))
374 #define CHAN_ARRAY_CLEAR(array, index) \
375         (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
376
377 /*
378  * most drivers define the following macro to make it easy to
379  * access the private structure.
380  */
381 #define devpriv ((struct rtdPrivate *)dev->private)
382
383 /* Macros to access registers */
384
385 /* Reset board */
386 #define RtdResetBoard(dev) \
387     writel (0, devpriv->las0+LAS0_BOARD_RESET)
388
389 /* Reset channel gain table read pointer */
390 #define RtdResetCGT(dev) \
391     writel (0, devpriv->las0+LAS0_CGT_RESET)
392
393 /* Reset channel gain table read and write pointers */
394 #define RtdClearCGT(dev) \
395     writel (0, devpriv->las0+LAS0_CGT_CLEAR)
396
397 /* Reset channel gain table read and write pointers */
398 #define RtdEnableCGT(dev, v) \
399     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE)
400
401 /* Write channel gain table entry */
402 #define RtdWriteCGTable(dev, v) \
403     writel (v, devpriv->las0+LAS0_CGT_WRITE)
404
405 /* Write Channel Gain Latch */
406 #define RtdWriteCGLatch(dev, v) \
407     writel (v, devpriv->las0+LAS0_CGL_WRITE)
408
409 /* Reset ADC FIFO */
410 #define RtdAdcClearFifo(dev) \
411     writel (0, devpriv->las0+LAS0_ADC_FIFO_CLEAR)
412
413 /* Set ADC start conversion source select (write only) */
414 #define RtdAdcConversionSource(dev, v) \
415     writel (v, devpriv->las0+LAS0_ADC_CONVERSION)
416
417 /* Set burst start source select (write only) */
418 #define RtdBurstStartSource(dev, v) \
419     writel (v, devpriv->las0+LAS0_BURST_START)
420
421 /* Set Pacer start source select (write only) */
422 #define RtdPacerStartSource(dev, v) \
423     writel (v, devpriv->las0+LAS0_PACER_START)
424
425 /* Set Pacer stop source select (write only) */
426 #define RtdPacerStopSource(dev, v) \
427     writel (v, devpriv->las0+LAS0_PACER_STOP)
428
429 /* Set Pacer clock source select (write only) 0=external 1=internal */
430 #define RtdPacerClockSource(dev, v) \
431     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)
432
433 /* Set sample counter source select (write only) */
434 #define RtdAdcSampleCounterSource(dev, v) \
435     writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC)
436
437 /* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */
438 #define RtdPacerTriggerMode(dev, v) \
439     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)
440
441 /* Set About counter stop enable (write only) */
442 #define RtdAboutStopEnable(dev, v) \
443     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)
444
445 /* Set external trigger polarity (write only) 0=positive edge, 1=negative */
446 #define RtdTriggerPolarity(dev, v) \
447     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)
448
449 /* Start single ADC conversion */
450 #define RtdAdcStart(dev) \
451     writew (0, devpriv->las0+LAS0_ADC)
452
453 /* Read one ADC data value (12bit (with sign extend) as 16bit) */
454 /* Note: matches what DMA would get.  Actual value >> 3 */
455 #define RtdAdcFifoGet(dev) \
456     readw (devpriv->las1+LAS1_ADC_FIFO)
457
458 /* Read two ADC data values (DOESNT WORK) */
459 #define RtdAdcFifoGet2(dev) \
460     readl (devpriv->las1+LAS1_ADC_FIFO)
461
462 /* FIFO status */
463 #define RtdFifoStatus(dev) \
464     readl (devpriv->las0+LAS0_ADC)
465
466 /* pacer start/stop read=start, write=stop*/
467 #define RtdPacerStart(dev) \
468     readl (devpriv->las0+LAS0_PACER)
469 #define RtdPacerStop(dev) \
470     writel (0, devpriv->las0+LAS0_PACER)
471
472 /* Interrupt status */
473 #define RtdInterruptStatus(dev) \
474     readw (devpriv->las0+LAS0_IT)
475
476 /* Interrupt mask */
477 #define RtdInterruptMask(dev, v) \
478     writew ((devpriv->intMask = (v)), devpriv->las0+LAS0_IT)
479
480 /* Interrupt status clear (only bits set in mask) */
481 #define RtdInterruptClear(dev) \
482     readw (devpriv->las0+LAS0_CLEAR)
483
484 /* Interrupt clear mask */
485 #define RtdInterruptClearMask(dev, v) \
486     writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)
487
488 /* Interrupt overrun status */
489 #define RtdInterruptOverrunStatus(dev) \
490     readl (devpriv->las0+LAS0_OVERRUN)
491
492 /* Interrupt overrun clear */
493 #define RtdInterruptOverrunClear(dev) \
494     writel (0, devpriv->las0+LAS0_OVERRUN)
495
496 /* Pacer counter, 24bit */
497 #define RtdPacerCount(dev) \
498     readl (devpriv->las0+LAS0_PCLK)
499 #define RtdPacerCounter(dev, v) \
500     writel ((v) & 0xffffff, devpriv->las0+LAS0_PCLK)
501
502 /* Burst counter, 10bit */
503 #define RtdBurstCount(dev) \
504     readl (devpriv->las0+LAS0_BCLK)
505 #define RtdBurstCounter(dev, v) \
506     writel ((v) & 0x3ff, devpriv->las0+LAS0_BCLK)
507
508 /* Delay counter, 16bit */
509 #define RtdDelayCount(dev) \
510     readl (devpriv->las0+LAS0_DCLK)
511 #define RtdDelayCounter(dev, v) \
512     writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK)
513
514 /* About counter, 16bit */
515 #define RtdAboutCount(dev) \
516     readl (devpriv->las0+LAS0_ACNT)
517 #define RtdAboutCounter(dev, v) \
518     writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT)
519
520 /* ADC sample counter, 10bit */
521 #define RtdAdcSampleCount(dev) \
522     readl (devpriv->las0+LAS0_ADC_SCNT)
523 #define RtdAdcSampleCounter(dev, v) \
524     writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)
525
526 /* User Timer/Counter (8254) */
527 #define RtdUtcCounterGet(dev, n) \
528     readb (devpriv->las0 \
529         + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
530
531 #define RtdUtcCounterPut(dev, n, v) \
532     writeb ((v) & 0xff, devpriv->las0 \
533         + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
534
535 /* Set UTC (8254) control byte  */
536 #define RtdUtcCtrlPut(dev, n, v) \
537     writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \
538       devpriv->las0 + LAS0_UTC_CTRL)
539
540 /* Set UTCn clock source (write only) */
541 #define RtdUtcClockSource(dev, n, v) \
542     writew (v, devpriv->las0 \
543         + ((n <= 0) ? LAS0_UTC0_CLOCK : \
544            ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))
545
546 /* Set UTCn gate source (write only) */
547 #define RtdUtcGateSource(dev, n, v) \
548     writew (v, devpriv->las0 \
549         + ((n <= 0) ? LAS0_UTC0_GATE : \
550            ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))
551
552 /* User output N source select (write only) */
553 #define RtdUsrOutSource(dev, n, v) \
554     writel (v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
555
556 /* Digital IO */
557 #define RtdDio0Read(dev) \
558     (readw (devpriv->las0+LAS0_DIO0) & 0xff)
559 #define RtdDio0Write(dev, v) \
560     writew ((v) & 0xff, devpriv->las0+LAS0_DIO0)
561
562 #define RtdDio1Read(dev) \
563     (readw (devpriv->las0+LAS0_DIO1) & 0xff)
564 #define RtdDio1Write(dev, v) \
565     writew ((v) & 0xff, devpriv->las0+LAS0_DIO1)
566
567 #define RtdDioStatusRead(dev) \
568     (readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff)
569 #define RtdDioStatusWrite(dev, v) \
570     writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)
571
572 #define RtdDio0CtrlRead(dev) \
573     (readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff)
574 #define RtdDio0CtrlWrite(dev, v) \
575     writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)
576
577 /* Digital to Analog converter */
578 /* Write one data value (sign + 12bit + marker bits) */
579 /* Note: matches what DMA would put.  Actual value << 3 */
580 #define RtdDacFifoPut(dev, n, v) \
581     writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO))
582
583 /* Start single DAC conversion */
584 #define RtdDacUpdate(dev, n) \
585     writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))
586
587 /* Start single DAC conversion on both DACs */
588 #define RtdDacBothUpdate(dev) \
589     writew (0, devpriv->las0+LAS0_DAC)
590
591 /* Set DAC output type and range */
592 #define RtdDacRange(dev, n, v) \
593     writew ((v) & 7, devpriv->las0 \
594         +(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))
595
596 /* Reset DAC FIFO */
597 #define RtdDacClearFifo(dev, n) \
598     writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET))
599
600 /* Set source for DMA 0 (write only, shadow?) */
601 #define RtdDma0Source(dev, n) \
602     writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)
603
604 /* Set source for DMA 1 (write only, shadow?) */
605 #define RtdDma1Source(dev, n) \
606     writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)
607
608 /* Reset board state for DMA 0 */
609 #define RtdDma0Reset(dev) \
610     writel (0, devpriv->las0+LAS0_DMA0_RESET)
611
612 /* Reset board state for DMA 1 */
613 #define RtdDma1Reset(dev) \
614     writel (0, devpriv->las0+LAS0_DMA1_SRC)
615
616 /* PLX9080 interrupt mask and status */
617 #define RtdPlxInterruptRead(dev) \
618     readl (devpriv->lcfg+LCFG_ITCSR)
619 #define RtdPlxInterruptWrite(dev, v) \
620     writel (v, devpriv->lcfg+LCFG_ITCSR)
621
622 /* Set  mode for DMA 0 */
623 #define RtdDma0Mode(dev, m) \
624     writel ((m), devpriv->lcfg+LCFG_DMAMODE0)
625
626 /* Set PCI address for DMA 0 */
627 #define RtdDma0PciAddr(dev, a) \
628     writel ((a), devpriv->lcfg+LCFG_DMAPADR0)
629
630 /* Set local address for DMA 0 */
631 #define RtdDma0LocalAddr(dev, a) \
632     writel ((a), devpriv->lcfg+LCFG_DMALADR0)
633
634 /* Set byte count for DMA 0 */
635 #define RtdDma0Count(dev, c) \
636     writel ((c), devpriv->lcfg+LCFG_DMASIZ0)
637
638 /* Set next descriptor for DMA 0 */
639 #define RtdDma0Next(dev, a) \
640     writel ((a), devpriv->lcfg+LCFG_DMADPR0)
641
642 /* Set  mode for DMA 1 */
643 #define RtdDma1Mode(dev, m) \
644     writel ((m), devpriv->lcfg+LCFG_DMAMODE1)
645
646 /* Set PCI address for DMA 1 */
647 #define RtdDma1PciAddr(dev, a) \
648     writel ((a), devpriv->lcfg+LCFG_DMAADR1)
649
650 /* Set local address for DMA 1 */
651 #define RtdDma1LocalAddr(dev, a) \
652     writel ((a), devpriv->lcfg+LCFG_DMALADR1)
653
654 /* Set byte count for DMA 1 */
655 #define RtdDma1Count(dev, c) \
656     writel ((c), devpriv->lcfg+LCFG_DMASIZ1)
657
658 /* Set next descriptor for DMA 1 */
659 #define RtdDma1Next(dev, a) \
660     writel ((a), devpriv->lcfg+LCFG_DMADPR1)
661
662 /* Set control for DMA 0 (write only, shadow?) */
663 #define RtdDma0Control(dev, n) \
664     writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)
665
666 /* Get status for DMA 0 */
667 #define RtdDma0Status(dev) \
668     readb (devpriv->lcfg+LCFG_DMACSR0)
669
670 /* Set control for DMA 1 (write only, shadow?) */
671 #define RtdDma1Control(dev, n) \
672     writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)
673
674 /* Get status for DMA 1 */
675 #define RtdDma1Status(dev) \
676     readb (devpriv->lcfg+LCFG_DMACSR1)
677
678 /*
679  * The struct comedi_driver structure tells the Comedi core module
680  * which functions to call to configure/deconfigure (attac/detach)
681  * the board, and also about the kernel module that contains
682  * the device code.
683  */
684 static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it);
685 static int rtd_detach(struct comedi_device *dev);
686
687 static struct comedi_driver rtd520Driver = {
688         .driver_name = DRV_NAME,
689         .module = THIS_MODULE,
690         .attach = rtd_attach,
691         .detach = rtd_detach,
692 };
693
694 static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
695         struct comedi_insn *insn, unsigned int *data);
696 static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
697         struct comedi_insn *insn, unsigned int *data);
698 static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
699         struct comedi_insn *insn, unsigned int *data);
700 static int rtd_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
701         struct comedi_insn *insn, unsigned int *data);
702 static int rtd_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
703         struct comedi_insn *insn, unsigned int *data);
704 static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
705         struct comedi_cmd *cmd);
706 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
707 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
708 /* static int rtd_ai_poll (struct comedi_device *dev,struct comedi_subdevice *s); */
709 static int rtd_ns_to_timer(unsigned int *ns, int roundMode);
710 static irqreturn_t rtd_interrupt(int irq, void *d);
711 static int rtd520_probe_fifo_depth(struct comedi_device *dev);
712
713 /*
714  * Attach is called by the Comedi core to configure the driver
715  * for a particular board.  If you specified a board_name array
716  * in the driver structure, dev->board_ptr contains that
717  * address.
718  */
719 static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
720 {                               /* board name and options flags */
721         struct comedi_subdevice *s;
722         struct pci_dev *pcidev;
723         int ret;
724         resource_size_t physLas0;       /* configuation */
725         resource_size_t physLas1;       /* data area */
726         resource_size_t physLcfg;       /* PLX9080 */
727 #ifdef USE_DMA
728         int index;
729 #endif
730
731         printk("comedi%d: rtd520 attaching.\n", dev->minor);
732
733 #if defined (CONFIG_COMEDI_DEBUG) && defined (USE_DMA)
734         /* You can set this a load time: modprobe comedi comedi_debug=1 */
735         if (0 == comedi_debug)  /* force DMA debug printks */
736                 comedi_debug = 1;
737 #endif
738
739         /*
740          * Allocate the private structure area.  alloc_private() is a
741          * convenient macro defined in comedidev.h.
742          */
743         if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
744                 return -ENOMEM;
745
746         /*
747          * Probe the device to determine what device in the series it is.
748          */
749         for (pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, NULL);
750                 pcidev != NULL;
751                 pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) {
752                 int i;
753
754                 if (it->options[0] || it->options[1]) {
755                         if (pcidev->bus->number != it->options[0]
756                                 || PCI_SLOT(pcidev->devfn) !=
757                                 it->options[1]) {
758                                 continue;
759                         }
760                 }
761                 for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i)
762                 {
763                         if (pcidev->device == rtd520Boards[i].device_id)
764                         {
765                                 dev->board_ptr = &rtd520Boards[i];
766                                 break;
767                         }
768                 }
769                 if (dev->board_ptr) break;      /* found one */
770         }
771         if (!pcidev) {
772                 if (it->options[0] && it->options[1]) {
773                         printk("No RTD card at bus=%d slot=%d.\n",
774                                 it->options[0], it->options[1]);
775                 } else {
776                         printk("No RTD card found.\n");
777                 }
778                 return -EIO;
779         }
780         devpriv->pci_dev = pcidev;
781         dev->board_name = thisboard->name;
782
783         ret = comedi_pci_enable(pcidev, DRV_NAME);
784         if (ret < 0) {
785                 printk("Failed to enable PCI device and request regions.\n");
786                 return ret;
787         }
788         devpriv->got_regions = 1;
789
790         /*
791          * Initialize base addresses
792          */
793         /* Get the physical address from PCI config */
794         physLas0 = pci_resource_start(devpriv->pci_dev, LAS0_PCIINDEX);
795         physLas1 = pci_resource_start(devpriv->pci_dev, LAS1_PCIINDEX);
796         physLcfg = pci_resource_start(devpriv->pci_dev, LCFG_PCIINDEX);
797         /* Now have the kernel map this into memory */
798         /* ASSUME page aligned */
799         devpriv->las0 = ioremap_nocache(physLas0, LAS0_PCISIZE);
800         devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE);
801         devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE);
802
803         if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) {
804                 return -ENOMEM;
805         }
806
807         DPRINTK("%s: LAS0=%llx, LAS1=%llx, CFG=%llx.\n", dev->board_name,
808                 (unsigned long long)physLas0, (unsigned long long)physLas1,
809                 (unsigned long long)physLcfg);
810         {                       /* The RTD driver does this */
811                 unsigned char pci_latency;
812                 u16 revision;
813                 /*uint32_t epld_version; */
814
815                 pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID,
816                         &revision);
817                 DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision);
818
819                 pci_read_config_byte(devpriv->pci_dev,
820                         PCI_LATENCY_TIMER, &pci_latency);
821                 if (pci_latency < 32) {
822                         printk("%s: PCI latency changed from %d to %d\n",
823                                 dev->board_name, pci_latency, 32);
824                         pci_write_config_byte(devpriv->pci_dev,
825                                 PCI_LATENCY_TIMER, 32);
826                 } else {
827                         DPRINTK("rtd520: PCI latency = %d\n", pci_latency);
828                 }
829
830                 /* Undocumented EPLD version (doesnt match RTD driver results) */
831                 /*DPRINTK ("rtd520: Reading epld from %p\n",
832                    devpriv->las0+0);
833                    epld_version = readl (devpriv->las0+0);
834                    if ((epld_version & 0xF0) >> 4 == 0x0F) {
835                    DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version);
836                    } else {
837                    DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4);
838                    } */
839         }
840
841         /* Show board configuration */
842         printk("%s:", dev->board_name);
843
844         /*
845          * Allocate the subdevice structures.  alloc_subdevice() is a
846          * convenient macro defined in comedidev.h.
847          */
848         if (alloc_subdevices(dev, 4) < 0) {
849                 return -ENOMEM;
850         }
851
852         s = dev->subdevices + 0;
853         dev->read_subdev = s;
854         /* analog input subdevice */
855         s->type = COMEDI_SUBD_AI;
856         s->subdev_flags =
857                 SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF |
858                 SDF_CMD_READ;
859         s->n_chan = thisboard->aiChans;
860         s->maxdata = (1 << thisboard->aiBits) - 1;
861         if (thisboard->aiMaxGain <= 32) {
862                 s->range_table = &rtd_ai_7520_range;
863         } else {
864                 s->range_table = &rtd_ai_4520_range;
865         }
866         s->len_chanlist = RTD_MAX_CHANLIST;     /* devpriv->fifoLen */
867         s->insn_read = rtd_ai_rinsn;
868         s->do_cmd = rtd_ai_cmd;
869         s->do_cmdtest = rtd_ai_cmdtest;
870         s->cancel = rtd_ai_cancel;
871         /* s->poll = rtd_ai_poll; */ /* not ready yet */
872
873         s = dev->subdevices + 1;
874         /* analog output subdevice */
875         s->type = COMEDI_SUBD_AO;
876         s->subdev_flags = SDF_WRITABLE;
877         s->n_chan = 2;
878         s->maxdata = (1 << thisboard->aiBits) - 1;
879         s->range_table = &rtd_ao_range;
880         s->insn_write = rtd_ao_winsn;
881         s->insn_read = rtd_ao_rinsn;
882
883         s = dev->subdevices + 2;
884         /* digital i/o subdevice */
885         s->type = COMEDI_SUBD_DIO;
886         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
887         /* we only support port 0 right now.  Ignoring port 1 and user IO */
888         s->n_chan = 8;
889         s->maxdata = 1;
890         s->range_table = &range_digital;
891         s->insn_bits = rtd_dio_insn_bits;
892         s->insn_config = rtd_dio_insn_config;
893
894         /* timer/counter subdevices (not currently supported) */
895         s = dev->subdevices + 3;
896         s->type = COMEDI_SUBD_COUNTER;
897         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
898         s->n_chan = 3;
899         s->maxdata = 0xffff;
900
901         /* initialize board, per RTD spec */
902         /* also, initialize shadow registers */
903         RtdResetBoard(dev);
904         udelay(100);    /* needed? */
905         RtdPlxInterruptWrite(dev, 0);
906         RtdInterruptMask(dev, 0);       /* and sets shadow */
907         RtdInterruptClearMask(dev, ~0); /* and sets shadow */
908         RtdInterruptClear(dev); /* clears bits set by mask */
909         RtdInterruptOverrunClear(dev);
910         RtdClearCGT(dev);
911         RtdAdcClearFifo(dev);
912         RtdDacClearFifo(dev, 0);
913         RtdDacClearFifo(dev, 1);
914         /* clear digital IO fifo */
915         RtdDioStatusWrite(dev, 0);      /* safe state, set shadow */
916         RtdUtcCtrlPut(dev, 0, 0x30);    /* safe state, set shadow */
917         RtdUtcCtrlPut(dev, 1, 0x30);    /* safe state, set shadow */
918         RtdUtcCtrlPut(dev, 2, 0x30);    /* safe state, set shadow */
919         RtdUtcCtrlPut(dev, 3, 0);       /* safe state, set shadow */
920         /* TODO: set user out source ??? */
921
922         /* check if our interrupt is available and get it */
923         ret = request_irq(devpriv->pci_dev->irq, rtd_interrupt,
924                                  IRQF_SHARED, DRV_NAME, dev);
925
926         if (ret < 0) {
927                 printk("Could not get interrupt! (%u)\n",
928                         devpriv->pci_dev->irq);
929                 return ret;
930         }
931         dev->irq = devpriv->pci_dev->irq;
932         printk("( irq=%u )", dev->irq);
933
934         ret = rtd520_probe_fifo_depth(dev);
935         if (ret < 0) {
936                 return ret;
937         }
938         devpriv->fifoLen = ret;
939         printk("( fifoLen=%d )", devpriv->fifoLen);
940
941 #ifdef USE_DMA
942         if (dev->irq > 0) {
943                 printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT);
944                 /* The PLX9080 has 2 DMA controllers, but there could be 4 sources:
945                    ADC, digital, DAC1, and DAC2.  Since only the ADC supports cmd mode
946                    right now, this isn't an issue (yet) */
947                 devpriv->dma0Offset = 0;
948
949                 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
950                         devpriv->dma0Buff[index] =
951                                 pci_alloc_consistent(devpriv->pci_dev,
952                                 sizeof(u16) * devpriv->fifoLen / 2,
953                                 &devpriv->dma0BuffPhysAddr[index]);
954                         if (devpriv->dma0Buff[index] == NULL) {
955                                 ret = -ENOMEM;
956                                 goto rtd_attach_die_error;
957                         }
958                         /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n",
959                            index,
960                            devpriv->dma0Buff[index], devpriv->dma0BuffPhysAddr[index]); */
961                 }
962
963                 /* setup DMA descriptor ring (use cpu_to_le32 for byte ordering?) */
964                 devpriv->dma0Chain =
965                         pci_alloc_consistent(devpriv->pci_dev,
966                         sizeof(struct plx_dma_desc) * DMA_CHAIN_COUNT,
967                         &devpriv->dma0ChainPhysAddr);
968                 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
969                         devpriv->dma0Chain[index].pci_start_addr =
970                                 devpriv->dma0BuffPhysAddr[index];
971                         devpriv->dma0Chain[index].local_start_addr =
972                                 DMALADDR_ADC;
973                         devpriv->dma0Chain[index].transfer_size =
974                                 sizeof(u16) * devpriv->fifoLen / 2;
975                         devpriv->dma0Chain[index].next =
976                                 (devpriv->dma0ChainPhysAddr + ((index +
977                                                 1) % (DMA_CHAIN_COUNT))
978                                 * sizeof(devpriv->dma0Chain[0]))
979                                 | DMA_TRANSFER_BITS;
980                         /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n",
981                            index,
982                            ((long)devpriv->dma0ChainPhysAddr
983                            + (index * sizeof(devpriv->dma0Chain[0]))),
984                            devpriv->dma0Chain[index].pci_start_addr,
985                            devpriv->dma0Chain[index].local_start_addr,
986                            devpriv->dma0Chain[index].transfer_size,
987                            devpriv->dma0Chain[index].next); */
988                 }
989
990                 if (devpriv->dma0Chain == NULL) {
991                         ret = -ENOMEM;
992                         goto rtd_attach_die_error;
993                 }
994
995                 RtdDma0Mode(dev, DMA_MODE_BITS);
996                 RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL);      /* set DMA trigger source */
997         } else {
998                 printk("( no IRQ->no DMA )");
999         }
1000 #endif /* USE_DMA */
1001
1002         if (dev->irq) {         /* enable plx9080 interrupts */
1003                 RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE);
1004         }
1005
1006         printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor);
1007
1008         return 1;
1009
1010 #if 0
1011         /* hit an error, clean up memory and return ret */
1012 /* rtd_attach_die_error: */
1013 #ifdef USE_DMA
1014         for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1015                 if (NULL != devpriv->dma0Buff[index]) { /* free buffer memory */
1016                         pci_free_consistent(devpriv->pci_dev,
1017                                 sizeof(u16) * devpriv->fifoLen / 2,
1018                                 devpriv->dma0Buff[index],
1019                                 devpriv->dma0BuffPhysAddr[index]);
1020                         devpriv->dma0Buff[index] = NULL;
1021                 }
1022         }
1023         if (NULL != devpriv->dma0Chain) {
1024                 pci_free_consistent(devpriv->pci_dev,
1025                         sizeof(struct plx_dma_desc)
1026                         * DMA_CHAIN_COUNT,
1027                         devpriv->dma0Chain, devpriv->dma0ChainPhysAddr);
1028                 devpriv->dma0Chain = NULL;
1029         }
1030 #endif /* USE_DMA */
1031         /* subdevices and priv are freed by the core */
1032         if (dev->irq) {
1033                 /* disable interrupt controller */
1034                 RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
1035                         & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
1036                 free_irq(dev->irq, dev);
1037         }
1038
1039         /* release all regions that were allocated */
1040         if (devpriv->las0) {
1041                 iounmap(devpriv->las0);
1042         }
1043         if (devpriv->las1) {
1044                 iounmap(devpriv->las1);
1045         }
1046         if (devpriv->lcfg) {
1047                 iounmap(devpriv->lcfg);
1048         }
1049         if (devpriv->pci_dev) {
1050                 pci_dev_put(devpriv->pci_dev);
1051         }
1052         return ret;
1053 #endif
1054 }
1055
1056 /*
1057  * _detach is called to deconfigure a device.  It should deallocate
1058  * resources.
1059  * This function is also called when _attach() fails, so it should be
1060  * careful not to release resources that were not necessarily
1061  * allocated by _attach().  dev->private and dev->subdevices are
1062  * deallocated automatically by the core.
1063  */
1064 static int rtd_detach(struct comedi_device *dev)
1065 {
1066 #ifdef USE_DMA
1067         int index;
1068 #endif
1069
1070         DPRINTK("comedi%d: rtd520: removing (%ld ints)\n",
1071                 dev->minor, (devpriv ? devpriv->intCount : 0L));
1072         if (devpriv && devpriv->lcfg) {
1073                 DPRINTK("(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n", 0xffff & RtdInterruptStatus(dev), 0xffff & RtdInterruptOverrunStatus(dev), (0xffff & RtdFifoStatus(dev)) ^ 0x6666);
1074         }
1075
1076         if (devpriv) {
1077                 /* Shut down any board ops by resetting it */
1078 #ifdef USE_DMA
1079                 if (devpriv->lcfg) {
1080                         RtdDma0Control(dev, 0); /* disable DMA */
1081                         RtdDma1Control(dev, 0); /* disable DMA */
1082                         RtdPlxInterruptWrite(dev, ICS_PIE | ICS_PLIE);
1083                 }
1084 #endif /* USE_DMA */
1085                 if (devpriv->las0) {
1086                         RtdResetBoard(dev);
1087                         RtdInterruptMask(dev, 0);
1088                         RtdInterruptClearMask(dev, ~0);
1089                         RtdInterruptClear(dev); /* clears bits set by mask */
1090                 }
1091 #ifdef USE_DMA
1092                 /* release DMA */
1093                 for (index = 0; index < DMA_CHAIN_COUNT; index++) {
1094                         if (NULL != devpriv->dma0Buff[index]) {
1095                                 pci_free_consistent(devpriv->pci_dev,
1096                                         sizeof(u16) * devpriv->fifoLen / 2,
1097                                         devpriv->dma0Buff[index],
1098                                         devpriv->dma0BuffPhysAddr[index]);
1099                                 devpriv->dma0Buff[index] = NULL;
1100                         }
1101                 }
1102                 if (NULL != devpriv->dma0Chain) {
1103                         pci_free_consistent(devpriv->pci_dev,
1104                                 sizeof(struct plx_dma_desc) * DMA_CHAIN_COUNT,
1105                                 devpriv->dma0Chain, devpriv->dma0ChainPhysAddr);
1106                         devpriv->dma0Chain = NULL;
1107                 }
1108 #endif /* USE_DMA */
1109
1110                 /* release IRQ */
1111                 if (dev->irq) {
1112                         /* disable interrupt controller */
1113                         RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
1114                                 & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
1115                         free_irq(dev->irq, dev);
1116                 }
1117
1118                 /* release all regions that were allocated */
1119                 if (devpriv->las0) {
1120                         iounmap(devpriv->las0);
1121                 }
1122                 if (devpriv->las1) {
1123                         iounmap(devpriv->las1);
1124                 }
1125                 if (devpriv->lcfg) {
1126                         iounmap(devpriv->lcfg);
1127                 }
1128                 if (devpriv->pci_dev) {
1129                         if (devpriv->got_regions) {
1130                                 comedi_pci_disable(devpriv->pci_dev);
1131                         }
1132                         pci_dev_put(devpriv->pci_dev);
1133                 }
1134         }
1135
1136         printk("comedi%d: rtd520: removed.\n", dev->minor);
1137
1138         return 0;
1139 }
1140
1141 /*
1142   Convert a single comedi channel-gain entry to a RTD520 table entry
1143 */
1144 static unsigned short rtdConvertChanGain(struct comedi_device *dev,
1145         unsigned int comediChan, int chanIndex)
1146 {                               /* index in channel list */
1147         unsigned int chan, range, aref;
1148         unsigned short r = 0;
1149
1150         chan = CR_CHAN(comediChan);
1151         range = CR_RANGE(comediChan);
1152         aref = CR_AREF(comediChan);
1153
1154         r |= chan & 0xf;
1155
1156         /* Note: we also setup the channel list bipolar flag array */
1157         if (range < thisboard->range10Start) {  /* first batch are +-5 */
1158                 r |= 0x000;     /* +-5 range */
1159                 r |= (range & 0x7) << 4;        /* gain */
1160                 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
1161         } else if (range < thisboard->rangeUniStart) {  /* second batch are +-10 */
1162                 r |= 0x100;     /* +-10 range */
1163                 r |= ((range - thisboard->range10Start) & 0x7) << 4;    /* gain */
1164                 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
1165         } else {                /* last batch is +10 */
1166                 r |= 0x200;     /* +10 range */
1167                 r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;   /* gain */
1168                 CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
1169         }
1170
1171         switch (aref) {
1172         case AREF_GROUND:       /* on-board ground */
1173                 break;
1174
1175         case AREF_COMMON:
1176                 r |= 0x80;      /* ref external analog common */
1177                 break;
1178
1179         case AREF_DIFF:
1180                 r |= 0x400;     /* differential inputs */
1181                 break;
1182
1183         case AREF_OTHER:        /* ??? */
1184                 break;
1185         }
1186         /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
1187            chan, range, aref, r); */
1188         return r;
1189 }
1190
1191 /*
1192   Setup the channel-gain table from a comedi list
1193 */
1194 static void rtd_load_channelgain_list(struct comedi_device *dev,
1195         unsigned int n_chan, unsigned int *list)
1196 {
1197         if (n_chan > 1) {       /* setup channel gain table */
1198                 int ii;
1199                 RtdClearCGT(dev);
1200                 RtdEnableCGT(dev, 1);   /* enable table */
1201                 for (ii = 0; ii < n_chan; ii++) {
1202                         RtdWriteCGTable(dev, rtdConvertChanGain(dev, list[ii],
1203                                         ii));
1204                 }
1205         } else {                /* just use the channel gain latch */
1206                 RtdEnableCGT(dev, 0);   /* disable table, enable latch */
1207                 RtdWriteCGLatch(dev, rtdConvertChanGain(dev, list[0], 0));
1208         }
1209 }
1210
1211 /* determine fifo size by doing adc conversions until the fifo half
1212 empty status flag clears */
1213 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
1214 {
1215         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
1216         unsigned i;
1217         static const unsigned limit = 0x2000;
1218         unsigned fifo_size = 0;
1219
1220         RtdAdcClearFifo(dev);
1221         rtd_load_channelgain_list(dev, 1, &chanspec);
1222         RtdAdcConversionSource(dev, 0); /* software */
1223         /* convert  samples */
1224         for (i = 0; i < limit; ++i) {
1225                 unsigned fifo_status;
1226                 /* trigger conversion */
1227                 RtdAdcStart(dev);
1228                 udelay(1);
1229                 fifo_status = RtdFifoStatus(dev);
1230                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
1231                         fifo_size = 2 * i;
1232                         break;
1233                 }
1234         }
1235         if (i == limit)
1236         {
1237                 printk("\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME);
1238                 return -EIO;
1239         }
1240         RtdAdcClearFifo(dev);
1241         if (fifo_size != 0x400 && fifo_size != 0x2000)
1242         {
1243                 printk("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
1244                         DRV_NAME, fifo_size);
1245                 return -EIO;
1246         }
1247         return fifo_size;
1248 }
1249
1250 /*
1251   "instructions" read/write data in "one-shot" or "software-triggered"
1252   mode (simplest case).
1253   This doesnt use interrupts.
1254
1255   Note, we don't do any settling delays.  Use a instruction list to
1256   select, delay, then read.
1257  */
1258 static int rtd_ai_rinsn(struct comedi_device *dev,
1259         struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1260 {
1261         int n, ii;
1262         int stat;
1263
1264         /* clear any old fifo data */
1265         RtdAdcClearFifo(dev);
1266
1267         /* write channel to multiplexer and clear channel gain table */
1268         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
1269
1270         /* set conversion source */
1271         RtdAdcConversionSource(dev, 0); /* software */
1272
1273         /* convert n samples */
1274         for (n = 0; n < insn->n; n++) {
1275                 s16 d;
1276                 /* trigger conversion */
1277                 RtdAdcStart(dev);
1278
1279                 for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
1280                         stat = RtdFifoStatus(dev);
1281                         if (stat & FS_ADC_NOT_EMPTY)    /* 1 -> not empty */
1282                                 break;
1283                         WAIT_QUIETLY;
1284                 }
1285                 if (ii >= RTD_ADC_TIMEOUT) {
1286                         DPRINTK("rtd520: Error: ADC never finished! FifoStatus=0x%x\n", stat ^ 0x6666);
1287                         return -ETIMEDOUT;
1288                 }
1289
1290                 /* read data */
1291                 d = RtdAdcFifoGet(dev); /* get 2s comp value */
1292                 /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
1293                 d = d >> 3;     /* low 3 bits are marker lines */
1294                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) {
1295                         data[n] = d + 2048;     /* convert to comedi unsigned data */
1296                 } else {
1297                         data[n] = d;
1298                 }
1299         }
1300
1301         /* return the number of samples read/written */
1302         return n;
1303 }
1304
1305 /*
1306   Get what we know is there.... Fast!
1307   This uses 1/2 the bus cycles of read_dregs (below).
1308
1309   The manual claims that we can do a lword read, but it doesn't work here.
1310 */
1311 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count)
1312 {
1313         int ii;
1314
1315         for (ii = 0; ii < count; ii++) {
1316                 short sample;
1317                 s16 d;
1318
1319                 if (0 == devpriv->aiCount) {    /* done */
1320                         d = RtdAdcFifoGet(dev); /* Read N and discard */
1321                         continue;
1322                 }
1323 #if 0
1324                 if (0 == (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY)) {     /* DEBUG */
1325                         DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1,
1326                                 count);
1327                         break;
1328                 }
1329 #endif
1330                 d = RtdAdcFifoGet(dev); /* get 2s comp value */
1331
1332                 d = d >> 3;     /* low 3 bits are marker lines */
1333                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1334                         sample = d + 2048;      /* convert to comedi unsigned data */
1335                 } else {
1336                         sample = d;
1337                 }
1338                 if (!comedi_buf_put(s->async, sample))
1339                         return -1;
1340
1341                 if (devpriv->aiCount > 0)       /* < 0, means read forever */
1342                         devpriv->aiCount--;
1343         }
1344         return 0;
1345 }
1346
1347 /*
1348   unknown amout of data is waiting in fifo.
1349 */
1350 static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
1351 {
1352         while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */
1353                 short sample;
1354                 s16 d = RtdAdcFifoGet(dev);     /* get 2s comp value */
1355
1356                 if (0 == devpriv->aiCount) {    /* done */
1357                         continue;       /* read rest */
1358                 }
1359
1360                 d = d >> 3;     /* low 3 bits are marker lines */
1361                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1362                         sample = d + 2048;      /* convert to comedi unsigned data */
1363                 } else {
1364                         sample = d;
1365                 }
1366                 if (!comedi_buf_put(s->async, sample))
1367                         return -1;
1368
1369                 if (devpriv->aiCount > 0)       /* < 0, means read forever */
1370                         devpriv->aiCount--;
1371         }
1372         return 0;
1373 }
1374
1375 #ifdef USE_DMA
1376 /*
1377   Terminate a DMA transfer and wait for everything to quiet down
1378 */
1379 void abort_dma(struct comedi_device *dev, unsigned int channel)
1380 {                               /* DMA channel 0, 1 */
1381         unsigned long dma_cs_addr;      /* the control/status register */
1382         uint8_t status;
1383         unsigned int ii;
1384         /* unsigned long flags; */
1385
1386         dma_cs_addr = (unsigned long)devpriv->lcfg
1387                 + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
1388
1389         /*  spinlock for plx dma control/status reg */
1390         /* spin_lock_irqsave( &dev->spinlock, flags ); */
1391
1392         /*  abort dma transfer if necessary */
1393         status = readb(dma_cs_addr);
1394         if ((status & PLX_DMA_EN_BIT) == 0) {   /* not enabled (Error?) */
1395                 DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
1396                         channel, status);
1397                 goto abortDmaExit;
1398         }
1399
1400         /* wait to make sure done bit is zero (needed?) */
1401         for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) {
1402                 WAIT_QUIETLY;
1403                 status = readb(dma_cs_addr);
1404         }
1405         if (status & PLX_DMA_DONE_BIT) {
1406                 printk("rtd520: Timeout waiting for dma %i done clear\n",
1407                         channel);
1408                 goto abortDmaExit;
1409         }
1410
1411         /* disable channel (required) */
1412         writeb(0, dma_cs_addr);
1413         udelay(1);      /* needed?? */
1414         /* set abort bit for channel */
1415         writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
1416
1417         /*  wait for dma done bit to be set */
1418         status = readb(dma_cs_addr);
1419         for (ii = 0;
1420                 (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT;
1421                 ii++) {
1422                 status = readb(dma_cs_addr);
1423                 WAIT_QUIETLY;
1424         }
1425         if ((status & PLX_DMA_DONE_BIT) == 0) {
1426                 printk("rtd520: Timeout waiting for dma %i done set\n",
1427                         channel);
1428         }
1429
1430       abortDmaExit:
1431         /* spin_unlock_irqrestore( &dev->spinlock, flags ); */
1432 }
1433
1434 /*
1435   Process what is in the DMA transfer buffer and pass to comedi
1436   Note: this is not re-entrant
1437 */
1438 static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1439 {
1440         int ii, n;
1441         s16 *dp;
1442
1443         if (devpriv->aiCount == 0)      /* transfer already complete */
1444                 return 0;
1445
1446         dp = devpriv->dma0Buff[devpriv->dma0Offset];
1447         for (ii = 0; ii < devpriv->fifoLen / 2;) {      /* convert samples */
1448                 short sample;
1449
1450                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
1451                         sample = (*dp >> 3) + 2048;     /* convert to comedi unsigned data */
1452                 } else {
1453                         sample = *dp >> 3;      /* low 3 bits are marker lines */
1454                 }
1455                 *dp++ = sample; /* put processed value back */
1456
1457                 if (++s->async->cur_chan >= s->async->cmd.chanlist_len)
1458                         s->async->cur_chan = 0;
1459
1460                 ++ii;           /* number ready to transfer */
1461                 if (devpriv->aiCount > 0) {     /* < 0, means read forever */
1462                         if (--devpriv->aiCount == 0) {  /* done */
1463                                 /*DPRINTK ("rtd520: Final %d samples\n", ii); */
1464                                 break;
1465                         }
1466                 }
1467         }
1468
1469         /* now pass the whole array to the comedi buffer */
1470         dp = devpriv->dma0Buff[devpriv->dma0Offset];
1471         n = comedi_buf_write_alloc(s->async, ii * sizeof(s16));
1472         if (n < (ii * sizeof(s16))) {   /* any residual is an error */
1473                 DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n",
1474                         ii - (n / sizeof(s16)));
1475                 s->async->events |= COMEDI_CB_ERROR;
1476                 return -1;
1477         }
1478         comedi_buf_memcpy_to(s->async, 0, dp, n);
1479         comedi_buf_write_free(s->async, n);
1480
1481         /* always at least 1 scan -- 1/2 FIFO is larger than our max scan list */
1482         s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
1483
1484         if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */
1485                 devpriv->dma0Offset = 0;
1486         }
1487         return 0;
1488 }
1489 #endif /* USE_DMA */
1490
1491 /*
1492   Handle all rtd520 interrupts.
1493   Runs atomically and is never re-entered.
1494   This is a "slow handler";  other interrupts may be active.
1495   The data conversion may someday happen in a "bottom half".
1496 */
1497 static irqreturn_t rtd_interrupt(int irq,       /* interrupt number (ignored) */
1498         void *d)                /* our data */
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);