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