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