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