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