]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/rtd520.c
Merge branch 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[karo-tx-linux.git] / drivers / staging / comedi / drivers / rtd520.c
1 /*
2     comedi/drivers/rtd520.c
3     Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 2001 David A. Schleef <ds@schleef.org>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 /*
23 Driver: rtd520
24 Description: Real Time Devices PCI4520/DM7520
25 Author: Dan Christian
26 Devices: [Real Time Devices] DM7520HR-1 (rtd520), DM7520HR-8,
27   PCI4520, PCI4520-8
28 Status: Works.  Only tested on DM7520-8.  Not SMP safe.
29
30 Configuration options:
31   [0] - PCI bus of device (optional)
32         If bus / slot is not specified, the first available PCI
33         device will be used.
34   [1] - PCI slot of device (optional)
35 */
36 /*
37     Created by Dan Christian, NASA Ames Research Center.
38
39     The PCI4520 is a PCI card.  The DM7520 is a PC/104-plus card.
40     Both have:
41     8/16 12 bit ADC with FIFO and channel gain table
42     8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
43     8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
44     2 12 bit DACs with FIFOs
45     2 bits output
46     2 bits input
47     bus mastering DMA
48     timers: ADC sample, pacer, burst, about, delay, DA1, DA2
49     sample counter
50     3 user timer/counters (8254)
51     external interrupt
52
53     The DM7520 has slightly fewer features (fewer gain steps).
54
55     These boards can support external multiplexors and multi-board
56     synchronization, but this driver doesn't support that.
57
58     Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
59     Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
60     Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
61     Call them and ask for the register level manual.
62     PCI chip: http://www.plxtech.com/products/io/pci9080
63
64     Notes:
65     This board is memory mapped.  There is some IO stuff, but it isn't needed.
66
67     I use a pretty loose naming style within the driver (rtd_blah).
68     All externally visible names should be rtd520_blah.
69     I use camelCase for structures (and inside them).
70     I may also use upper CamelCase for function names (old habit).
71
72     This board is somewhat related to the RTD PCI4400 board.
73
74     I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
75     das1800, since they have the best documented code.  Driver
76     cb_pcidas64.c uses the same DMA controller.
77
78     As far as I can tell, the About interrupt doesn't work if Sample is
79     also enabled.  It turns out that About really isn't needed, since
80     we always count down samples read.
81
82     There was some timer/counter code, but it didn't follow the right API.
83
84 */
85
86 /*
87   driver status:
88
89   Analog-In supports instruction and command mode.
90
91   With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
92   (single channel, 64K read buffer).  I get random system lockups when
93   using DMA with ALI-15xx based systems.  I haven't been able to test
94   any other chipsets.  The lockups happen soon after the start of an
95   acquistion, not in the middle of a long run.
96
97   Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
98   (with a 256K read buffer).
99
100   Digital-IO and Analog-Out only support instruction mode.
101
102 */
103
104 #include <linux/pci.h>
105 #include <linux/delay.h>
106 #include <linux/interrupt.h>
107
108 #include "../comedidev.h"
109
110 #include "comedi_fc.h"
111 #include "rtd520.h"
112 #include "plx9080.h"
113
114 /*======================================================================
115   Driver specific stuff (tunable)
116 ======================================================================*/
117
118 /* We really only need 2 buffers.  More than that means being much
119    smarter about knowing which ones are full. */
120 #define DMA_CHAIN_COUNT 2       /* max DMA segments/buffers in a ring (min 2) */
121
122 /* Target period for periodic transfers.  This sets the user read latency. */
123 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
124 /* If this is too low, efficiency is poor */
125 #define TRANS_TARGET_PERIOD 10000000    /* 10 ms (in nanoseconds) */
126
127 /* Set a practical limit on how long a list to support (affects memory use) */
128 /* The board support a channel list up to the FIFO length (1K or 8K) */
129 #define RTD_MAX_CHANLIST        128     /* max channel list that we allow */
130
131 /* tuning for ai/ao instruction done polling */
132 #ifdef FAST_SPIN
133 #define WAIT_QUIETLY            /* as nothing, spin on done bit */
134 #define RTD_ADC_TIMEOUT 66000   /* 2 msec at 33mhz bus rate */
135 #define RTD_DAC_TIMEOUT 66000
136 #define RTD_DMA_TIMEOUT 33000   /* 1 msec */
137 #else
138 /* by delaying, power and electrical noise are reduced somewhat */
139 #define WAIT_QUIETLY    udelay(1)
140 #define RTD_ADC_TIMEOUT 2000    /* in usec */
141 #define RTD_DAC_TIMEOUT 2000    /* in usec */
142 #define RTD_DMA_TIMEOUT 1000    /* in usec */
143 #endif
144
145 /*======================================================================
146   Board specific stuff
147 ======================================================================*/
148
149 #define RTD_CLOCK_RATE  8000000 /* 8Mhz onboard clock */
150 #define RTD_CLOCK_BASE  125     /* clock period in ns */
151
152 /* Note: these speed are slower than the spec, but fit the counter resolution*/
153 #define RTD_MAX_SPEED   1625    /* when sampling, in nanoseconds */
154 /* max speed if we don't have to wait for settling */
155 #define RTD_MAX_SPEED_1 875     /* if single channel, in nanoseconds */
156
157 #define RTD_MIN_SPEED   2097151875      /* (24bit counter) in nanoseconds */
158 /* min speed when only 1 channel (no burst counter) */
159 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
160
161 /* Setup continuous ring of 1/2 FIFO transfers.  See RTD manual p91 */
162 #define DMA_MODE_BITS (\
163                        PLX_LOCAL_BUS_16_WIDE_BITS \
164                        | PLX_DMA_EN_READYIN_BIT \
165                        | PLX_DMA_LOCAL_BURST_EN_BIT \
166                        | PLX_EN_CHAIN_BIT \
167                        | PLX_DMA_INTR_PCI_BIT \
168                        | PLX_LOCAL_ADDR_CONST_BIT \
169                        | PLX_DEMAND_MODE_BIT)
170
171 #define DMA_TRANSFER_BITS (\
172 /* descriptors in PCI memory*/  PLX_DESC_IN_PCI_BIT \
173 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
174 /* from board to PCI */         | PLX_XFER_LOCAL_TO_PCI)
175
176 /*======================================================================
177   Comedi specific stuff
178 ======================================================================*/
179
180 /*
181  * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
182  */
183 static const struct comedi_lrange rtd_ai_7520_range = {
184         18, {
185                 /* +-5V input range gain steps */
186                 BIP_RANGE(5.0),
187                 BIP_RANGE(5.0 / 2),
188                 BIP_RANGE(5.0 / 4),
189                 BIP_RANGE(5.0 / 8),
190                 BIP_RANGE(5.0 / 16),
191                 BIP_RANGE(5.0 / 32),
192                 /* +-10V input range gain steps */
193                 BIP_RANGE(10.0),
194                 BIP_RANGE(10.0 / 2),
195                 BIP_RANGE(10.0 / 4),
196                 BIP_RANGE(10.0 / 8),
197                 BIP_RANGE(10.0 / 16),
198                 BIP_RANGE(10.0 / 32),
199                 /* +10V input range gain steps */
200                 UNI_RANGE(10.0),
201                 UNI_RANGE(10.0 / 2),
202                 UNI_RANGE(10.0 / 4),
203                 UNI_RANGE(10.0 / 8),
204                 UNI_RANGE(10.0 / 16),
205                 UNI_RANGE(10.0 / 32),
206         }
207 };
208
209 /* PCI4520 has two more gains (6 more entries) */
210 static const struct comedi_lrange rtd_ai_4520_range = {
211         24, {
212                 /* +-5V input range gain steps */
213                 BIP_RANGE(5.0),
214                 BIP_RANGE(5.0 / 2),
215                 BIP_RANGE(5.0 / 4),
216                 BIP_RANGE(5.0 / 8),
217                 BIP_RANGE(5.0 / 16),
218                 BIP_RANGE(5.0 / 32),
219                 BIP_RANGE(5.0 / 64),
220                 BIP_RANGE(5.0 / 128),
221                 /* +-10V input range gain steps */
222                 BIP_RANGE(10.0),
223                 BIP_RANGE(10.0 / 2),
224                 BIP_RANGE(10.0 / 4),
225                 BIP_RANGE(10.0 / 8),
226                 BIP_RANGE(10.0 / 16),
227                 BIP_RANGE(10.0 / 32),
228                 BIP_RANGE(10.0 / 64),
229                 BIP_RANGE(10.0 / 128),
230                 /* +10V input range gain steps */
231                 UNI_RANGE(10.0),
232                 UNI_RANGE(10.0 / 2),
233                 UNI_RANGE(10.0 / 4),
234                 UNI_RANGE(10.0 / 8),
235                 UNI_RANGE(10.0 / 16),
236                 UNI_RANGE(10.0 / 32),
237                 UNI_RANGE(10.0 / 64),
238                 UNI_RANGE(10.0 / 128),
239         }
240 };
241
242 /* Table order matches range values */
243 static const struct comedi_lrange rtd_ao_range = {
244         4, {
245                 UNI_RANGE(5),
246                 UNI_RANGE(10),
247                 BIP_RANGE(5),
248                 BIP_RANGE(10),
249         }
250 };
251
252 struct rtdBoard {
253         const char *name;
254         int device_id;
255         int range10Start;       /* start of +-10V range */
256         int rangeUniStart;      /* start of +10V range */
257         const struct comedi_lrange *ai_range;
258 };
259
260 static const struct rtdBoard rtd520Boards[] = {
261         {
262                 .name           = "DM7520",
263                 .device_id      = 0x7520,
264                 .range10Start   = 6,
265                 .rangeUniStart  = 12,
266                 .ai_range       = &rtd_ai_7520_range,
267         }, {
268                 .name           = "PCI4520",
269                 .device_id      = 0x4520,
270                 .range10Start   = 8,
271                 .rangeUniStart  = 16,
272                 .ai_range       = &rtd_ai_4520_range,
273         },
274 };
275
276 /*
277    This structure is for data unique to this hardware driver.
278    This is also unique for each board in the system.
279 */
280 struct rtdPrivate {
281         /* memory mapped board structures */
282         void __iomem *las0;
283         void __iomem *las1;
284         void __iomem *lcfg;
285
286         long aiCount;           /* total transfer size (samples) */
287         int transCount;         /* # to transfer data. 0->1/2FIFO */
288         int flags;              /* flag event modes */
289
290         /* channel list info */
291         /* chanBipolar tracks whether a channel is bipolar (and needs +2048) */
292         unsigned char chanBipolar[RTD_MAX_CHANLIST / 8];        /* bit array */
293
294         /* read back data */
295         unsigned int aoValue[2];        /* Used for AO read back */
296
297         /* timer gate (when enabled) */
298         u8 utcGate[4];          /* 1 extra allows simple range check */
299
300         /* shadow registers affect other registers, but can't be read back */
301         /* The macros below update these on writes */
302         u16 intMask;            /* interrupt mask */
303         u16 intClearMask;       /* interrupt clear mask */
304         u8 utcCtrl[4];          /* crtl mode for 3 utc + read back */
305         u8 dioStatus;           /* could be read back (dio0Ctrl) */
306         unsigned fifoLen;
307 };
308
309 /* bit defines for "flags" */
310 #define SEND_EOS        0x01    /* send End Of Scan events */
311 #define DMA0_ACTIVE     0x02    /* DMA0 is active */
312 #define DMA1_ACTIVE     0x04    /* DMA1 is active */
313
314 /* Macros for accessing channel list bit array */
315 #define CHAN_ARRAY_TEST(array, index) \
316         (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
317 #define CHAN_ARRAY_SET(array, index) \
318         (((array)[(index)/8] |= 1 << ((index) & 0x7)))
319 #define CHAN_ARRAY_CLEAR(array, index) \
320         (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
321
322 /*
323   Given a desired period and the clock period (both in ns),
324   return the proper counter value (divider-1).
325   Sets the original period to be the true value.
326   Note: you have to check if the value is larger than the counter range!
327 */
328 static int rtd_ns_to_timer_base(unsigned int *nanosec,
329                                 int round_mode, int base)
330 {
331         int divider;
332
333         switch (round_mode) {
334         case TRIG_ROUND_NEAREST:
335         default:
336                 divider = (*nanosec + base / 2) / base;
337                 break;
338         case TRIG_ROUND_DOWN:
339                 divider = (*nanosec) / base;
340                 break;
341         case TRIG_ROUND_UP:
342                 divider = (*nanosec + base - 1) / base;
343                 break;
344         }
345         if (divider < 2)
346                 divider = 2;    /* min is divide by 2 */
347
348         /* Note: we don't check for max, because different timers
349            have different ranges */
350
351         *nanosec = base * divider;
352         return divider - 1;     /* countdown is divisor+1 */
353 }
354
355 /*
356   Given a desired period (in ns),
357   return the proper counter value (divider-1) for the internal clock.
358   Sets the original period to be the true value.
359 */
360 static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
361 {
362         return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
363 }
364
365 /*
366   Convert a single comedi channel-gain entry to a RTD520 table entry
367 */
368 static unsigned short rtdConvertChanGain(struct comedi_device *dev,
369                                          unsigned int comediChan, int chanIndex)
370 {                               /* index in channel list */
371         const struct rtdBoard *thisboard = comedi_board(dev);
372         struct rtdPrivate *devpriv = dev->private;
373         unsigned int chan, range, aref;
374         unsigned short r = 0;
375
376         chan = CR_CHAN(comediChan);
377         range = CR_RANGE(comediChan);
378         aref = CR_AREF(comediChan);
379
380         r |= chan & 0xf;
381
382         /* Note: we also setup the channel list bipolar flag array */
383         if (range < thisboard->range10Start) {
384                 /* +-5 range */
385                 r |= 0x000;
386                 r |= (range & 0x7) << 4;
387                 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
388         } else if (range < thisboard->rangeUniStart) {
389                 /* +-10 range */
390                 r |= 0x100;
391                 r |= ((range - thisboard->range10Start) & 0x7) << 4;
392                 CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex);
393         } else {
394                 /* +10 range */
395                 r |= 0x200;
396                 r |= ((range - thisboard->rangeUniStart) & 0x7) << 4;
397                 CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex);
398         }
399
400         switch (aref) {
401         case AREF_GROUND:       /* on-board ground */
402                 break;
403
404         case AREF_COMMON:
405                 r |= 0x80;      /* ref external analog common */
406                 break;
407
408         case AREF_DIFF:
409                 r |= 0x400;     /* differential inputs */
410                 break;
411
412         case AREF_OTHER:        /* ??? */
413                 break;
414         }
415         /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
416            chan, range, aref, r); */
417         return r;
418 }
419
420 /*
421   Setup the channel-gain table from a comedi list
422 */
423 static void rtd_load_channelgain_list(struct comedi_device *dev,
424                                       unsigned int n_chan, unsigned int *list)
425 {
426         struct rtdPrivate *devpriv = dev->private;
427
428         if (n_chan > 1) {       /* setup channel gain table */
429                 int ii;
430
431                 writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
432                 writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
433                 for (ii = 0; ii < n_chan; ii++) {
434                         writel(rtdConvertChanGain(dev, list[ii], ii),
435                                 devpriv->las0 + LAS0_CGT_WRITE);
436                 }
437         } else {                /* just use the channel gain latch */
438                 writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
439                 writel(rtdConvertChanGain(dev, list[0], 0),
440                         devpriv->las0 + LAS0_CGL_WRITE);
441         }
442 }
443
444 /* determine fifo size by doing adc conversions until the fifo half
445 empty status flag clears */
446 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
447 {
448         struct rtdPrivate *devpriv = dev->private;
449         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
450         unsigned i;
451         static const unsigned limit = 0x2000;
452         unsigned fifo_size = 0;
453
454         writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
455         rtd_load_channelgain_list(dev, 1, &chanspec);
456         /* ADC conversion trigger source: SOFTWARE */
457         writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
458         /* convert  samples */
459         for (i = 0; i < limit; ++i) {
460                 unsigned fifo_status;
461                 /* trigger conversion */
462                 writew(0, devpriv->las0 + LAS0_ADC);
463                 udelay(1);
464                 fifo_status = readl(devpriv->las0 + LAS0_ADC);
465                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
466                         fifo_size = 2 * i;
467                         break;
468                 }
469         }
470         if (i == limit) {
471                 dev_info(dev->class_dev, "failed to probe fifo size.\n");
472                 return -EIO;
473         }
474         writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
475         if (fifo_size != 0x400 && fifo_size != 0x2000) {
476                 dev_info(dev->class_dev,
477                          "unexpected fifo size of %i, expected 1024 or 8192.\n",
478                          fifo_size);
479                 return -EIO;
480         }
481         return fifo_size;
482 }
483
484 /*
485   "instructions" read/write data in "one-shot" or "software-triggered"
486   mode (simplest case).
487   This doesn't use interrupts.
488
489   Note, we don't do any settling delays.  Use a instruction list to
490   select, delay, then read.
491  */
492 static int rtd_ai_rinsn(struct comedi_device *dev,
493                         struct comedi_subdevice *s, struct comedi_insn *insn,
494                         unsigned int *data)
495 {
496         struct rtdPrivate *devpriv = dev->private;
497         int n, ii;
498         int stat;
499
500         /* clear any old fifo data */
501         writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
502
503         /* write channel to multiplexer and clear channel gain table */
504         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
505
506         /* ADC conversion trigger source: SOFTWARE */
507         writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
508
509         /* convert n samples */
510         for (n = 0; n < insn->n; n++) {
511                 s16 d;
512                 /* trigger conversion */
513                 writew(0, devpriv->las0 + LAS0_ADC);
514
515                 for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
516                         stat = readl(devpriv->las0 + LAS0_ADC);
517                         if (stat & FS_ADC_NOT_EMPTY)    /* 1 -> not empty */
518                                 break;
519                         WAIT_QUIETLY;
520                 }
521                 if (ii >= RTD_ADC_TIMEOUT)
522                         return -ETIMEDOUT;
523
524                 /* read data */
525                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
526                 /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
527                 d = d >> 3;     /* low 3 bits are marker lines */
528                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0))
529                         /* convert to comedi unsigned data */
530                         data[n] = d + 2048;
531                 else
532                         data[n] = d;
533         }
534
535         /* return the number of samples read/written */
536         return n;
537 }
538
539 /*
540   Get what we know is there.... Fast!
541   This uses 1/2 the bus cycles of read_dregs (below).
542
543   The manual claims that we can do a lword read, but it doesn't work here.
544 */
545 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
546                      int count)
547 {
548         struct rtdPrivate *devpriv = dev->private;
549         int ii;
550
551         for (ii = 0; ii < count; ii++) {
552                 short sample;
553                 s16 d;
554
555                 if (0 == devpriv->aiCount) {    /* done */
556                         d = readw(devpriv->las1 + LAS1_ADC_FIFO);
557                         continue;
558                 }
559
560                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
561                 d = d >> 3;     /* low 3 bits are marker lines */
562                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
563                         /* convert to comedi unsigned data */
564                         sample = d + 2048;
565                 } else
566                         sample = d;
567
568                 if (!comedi_buf_put(s->async, sample))
569                         return -1;
570
571                 if (devpriv->aiCount > 0)       /* < 0, means read forever */
572                         devpriv->aiCount--;
573         }
574         return 0;
575 }
576
577 /*
578   unknown amout of data is waiting in fifo.
579 */
580 static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
581 {
582         struct rtdPrivate *devpriv = dev->private;
583
584         while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
585                 short sample;
586                 s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
587
588                 if (0 == devpriv->aiCount) {    /* done */
589                         continue;       /* read rest */
590                 }
591
592                 d = d >> 3;     /* low 3 bits are marker lines */
593                 if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
594                         /* convert to comedi unsigned data */
595                         sample = d + 2048;
596                 } else
597                         sample = d;
598
599                 if (!comedi_buf_put(s->async, sample))
600                         return -1;
601
602                 if (devpriv->aiCount > 0)       /* < 0, means read forever */
603                         devpriv->aiCount--;
604         }
605         return 0;
606 }
607
608 /*
609   Handle all rtd520 interrupts.
610   Runs atomically and is never re-entered.
611   This is a "slow handler";  other interrupts may be active.
612   The data conversion may someday happen in a "bottom half".
613 */
614 static irqreturn_t rtd_interrupt(int irq,       /* interrupt number (ignored) */
615                                  void *d)
616 {                               /* our data *//* cpu context (ignored) */
617         struct comedi_device *dev = d;
618         struct comedi_subdevice *s = &dev->subdevices[0];
619         struct rtdPrivate *devpriv = dev->private;
620         u32 overrun;
621         u16 status;
622         u16 fifoStatus;
623
624         if (!dev->attached)
625                 return IRQ_NONE;
626
627         fifoStatus = readl(devpriv->las0 + LAS0_ADC);
628         /* check for FIFO full, this automatically halts the ADC! */
629         if (!(fifoStatus & FS_ADC_NOT_FULL))    /* 0 -> full */
630                 goto abortTransfer;
631
632         status = readw(devpriv->las0 + LAS0_IT);
633         /* if interrupt was not caused by our board, or handled above */
634         if (0 == status)
635                 return IRQ_HANDLED;
636
637         if (status & IRQM_ADC_ABOUT_CNT) {      /* sample count -> read FIFO */
638                 /*
639                  * since the priority interrupt controller may have queued
640                  * a sample counter interrupt, even though we have already
641                  * finished, we must handle the possibility that there is
642                  * no data here
643                  */
644                 if (!(fifoStatus & FS_ADC_HEMPTY)) {
645                         /* FIFO half full */
646                         if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0)
647                                 goto abortTransfer;
648
649                         if (0 == devpriv->aiCount)
650                                 goto transferDone;
651
652                         comedi_event(dev, s);
653                 } else if (devpriv->transCount > 0) {
654                         if (fifoStatus & FS_ADC_NOT_EMPTY) {
655                                 /* FIFO not empty */
656                                 if (ai_read_n(dev, s, devpriv->transCount) < 0)
657                                         goto abortTransfer;
658
659                                 if (0 == devpriv->aiCount)
660                                         goto transferDone;
661
662                                 comedi_event(dev, s);
663                         }
664                 }
665         }
666
667         overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
668         if (overrun)
669                 goto abortTransfer;
670
671         /* clear the interrupt */
672         devpriv->intClearMask = status;
673         writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
674         readw(devpriv->las0 + LAS0_CLEAR);
675         return IRQ_HANDLED;
676
677 abortTransfer:
678         writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
679         s->async->events |= COMEDI_CB_ERROR;
680         devpriv->aiCount = 0;   /* stop and don't transfer any more */
681         /* fall into transferDone */
682
683 transferDone:
684         /* pacer stop source: SOFTWARE */
685         writel(0, devpriv->las0 + LAS0_PACER_STOP);
686         writel(0, devpriv->las0 + LAS0_PACER);  /* stop pacer */
687         writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
688         devpriv->intMask = 0;
689         writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
690
691         if (devpriv->aiCount > 0) {     /* there shouldn't be anything left */
692                 fifoStatus = readl(devpriv->las0 + LAS0_ADC);
693                 ai_read_dregs(dev, s);  /* read anything left in FIFO */
694         }
695
696         s->async->events |= COMEDI_CB_EOA;      /* signal end to comedi */
697         comedi_event(dev, s);
698
699         /* clear the interrupt */
700         status = readw(devpriv->las0 + LAS0_IT);
701         devpriv->intClearMask = status;
702         writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
703         readw(devpriv->las0 + LAS0_CLEAR);
704
705         fifoStatus = readl(devpriv->las0 + LAS0_ADC);
706         overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
707
708         return IRQ_HANDLED;
709 }
710
711 /*
712   cmdtest tests a particular command to see if it is valid.
713   Using the cmdtest ioctl, a user can create a valid cmd
714   and then have it executed by the cmd ioctl (asynchronously).
715
716   cmdtest returns 1,2,3,4 or 0, depending on which tests
717   the command passes.
718 */
719
720 static int rtd_ai_cmdtest(struct comedi_device *dev,
721                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
722 {
723         int err = 0;
724         int tmp;
725
726         /* Step 1 : check if triggers are trivially valid */
727
728         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
729         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
730                                         TRIG_TIMER | TRIG_EXT);
731         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
732         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
733         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
734
735         if (err)
736                 return 1;
737
738         /* Step 2a : make sure trigger sources are unique */
739
740         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
741         err |= cfc_check_trigger_is_unique(cmd->convert_src);
742         err |= cfc_check_trigger_is_unique(cmd->stop_src);
743
744         /* Step 2b : and mutually compatible */
745
746         if (err)
747                 return 2;
748
749         /* Step 3: check if arguments are trivially valid */
750
751         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
752
753         if (cmd->scan_begin_src == TRIG_TIMER) {
754                 /* Note: these are time periods, not actual rates */
755                 if (1 == cmd->chanlist_len) {   /* no scanning */
756                         if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
757                                                       RTD_MAX_SPEED_1)) {
758                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
759                                                 TRIG_ROUND_UP);
760                                 err |= -EINVAL;
761                         }
762                         if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
763                                                       RTD_MIN_SPEED_1)) {
764                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
765                                                 TRIG_ROUND_DOWN);
766                                 err |= -EINVAL;
767                         }
768                 } else {
769                         if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
770                                                       RTD_MAX_SPEED)) {
771                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
772                                                 TRIG_ROUND_UP);
773                                 err |= -EINVAL;
774                         }
775                         if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
776                                                       RTD_MIN_SPEED)) {
777                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
778                                                 TRIG_ROUND_DOWN);
779                                 err |= -EINVAL;
780                         }
781                 }
782         } else {
783                 /* external trigger */
784                 /* should be level/edge, hi/lo specification here */
785                 /* should specify multiple external triggers */
786                 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
787         }
788
789         if (cmd->convert_src == TRIG_TIMER) {
790                 if (1 == cmd->chanlist_len) {   /* no scanning */
791                         if (cfc_check_trigger_arg_min(&cmd->convert_arg,
792                                                       RTD_MAX_SPEED_1)) {
793                                 rtd_ns_to_timer(&cmd->convert_arg,
794                                                 TRIG_ROUND_UP);
795                                 err |= -EINVAL;
796                         }
797                         if (cfc_check_trigger_arg_max(&cmd->convert_arg,
798                                                       RTD_MIN_SPEED_1)) {
799                                 rtd_ns_to_timer(&cmd->convert_arg,
800                                                 TRIG_ROUND_DOWN);
801                                 err |= -EINVAL;
802                         }
803                 } else {
804                         if (cfc_check_trigger_arg_min(&cmd->convert_arg,
805                                                       RTD_MAX_SPEED)) {
806                                 rtd_ns_to_timer(&cmd->convert_arg,
807                                                 TRIG_ROUND_UP);
808                                 err |= -EINVAL;
809                         }
810                         if (cfc_check_trigger_arg_max(&cmd->convert_arg,
811                                                       RTD_MIN_SPEED)) {
812                                 rtd_ns_to_timer(&cmd->convert_arg,
813                                                 TRIG_ROUND_DOWN);
814                                 err |= -EINVAL;
815                         }
816                 }
817         } else {
818                 /* external trigger */
819                 /* see above */
820                 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
821         }
822
823         if (cmd->stop_src == TRIG_COUNT) {
824                 /* TODO check for rounding error due to counter wrap */
825         } else {
826                 /* TRIG_NONE */
827                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
828         }
829
830         if (err)
831                 return 3;
832
833
834         /* step 4: fix up any arguments */
835
836         if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
837                 cmd->chanlist_len = RTD_MAX_CHANLIST;
838                 err++;
839         }
840         if (cmd->scan_begin_src == TRIG_TIMER) {
841                 tmp = cmd->scan_begin_arg;
842                 rtd_ns_to_timer(&cmd->scan_begin_arg,
843                                 cmd->flags & TRIG_ROUND_MASK);
844                 if (tmp != cmd->scan_begin_arg)
845                         err++;
846
847         }
848         if (cmd->convert_src == TRIG_TIMER) {
849                 tmp = cmd->convert_arg;
850                 rtd_ns_to_timer(&cmd->convert_arg,
851                                 cmd->flags & TRIG_ROUND_MASK);
852                 if (tmp != cmd->convert_arg)
853                         err++;
854
855                 if (cmd->scan_begin_src == TRIG_TIMER
856                     && (cmd->scan_begin_arg
857                         < (cmd->convert_arg * cmd->scan_end_arg))) {
858                         cmd->scan_begin_arg =
859                             cmd->convert_arg * cmd->scan_end_arg;
860                         err++;
861                 }
862         }
863
864         if (err)
865                 return 4;
866
867         return 0;
868 }
869
870 /*
871   Execute a analog in command with many possible triggering options.
872   The data get stored in the async structure of the subdevice.
873   This is usually done by an interrupt handler.
874   Userland gets to the data using read calls.
875 */
876 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
877 {
878         struct rtdPrivate *devpriv = dev->private;
879         struct comedi_cmd *cmd = &s->async->cmd;
880         int timer;
881
882         /* stop anything currently running */
883         /* pacer stop source: SOFTWARE */
884         writel(0, devpriv->las0 + LAS0_PACER_STOP);
885         writel(0, devpriv->las0 + LAS0_PACER);  /* stop pacer */
886         writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
887         devpriv->intMask = 0;
888         writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
889         writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
890         writel(0, devpriv->las0 + LAS0_OVERRUN);
891
892         /* start configuration */
893         /* load channel list and reset CGT */
894         rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
895
896         /* setup the common case and override if needed */
897         if (cmd->chanlist_len > 1) {
898                 /* pacer start source: SOFTWARE */
899                 writel(0, devpriv->las0 + LAS0_PACER_START);
900                 /* burst trigger source: PACER */
901                 writel(1, devpriv->las0 + LAS0_BURST_START);
902                 /* ADC conversion trigger source: BURST */
903                 writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
904         } else {                /* single channel */
905                 /* pacer start source: SOFTWARE */
906                 writel(0, devpriv->las0 + LAS0_PACER_START);
907                 /* ADC conversion trigger source: PACER */
908                 writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
909         }
910         writel((devpriv->fifoLen / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
911
912         if (TRIG_TIMER == cmd->scan_begin_src) {
913                 /* scan_begin_arg is in nanoseconds */
914                 /* find out how many samples to wait before transferring */
915                 if (cmd->flags & TRIG_WAKE_EOS) {
916                         /*
917                          * this may generate un-sustainable interrupt rates
918                          * the application is responsible for doing the
919                          * right thing
920                          */
921                         devpriv->transCount = cmd->chanlist_len;
922                         devpriv->flags |= SEND_EOS;
923                 } else {
924                         /* arrange to transfer data periodically */
925                         devpriv->transCount
926                             =
927                             (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
928                             cmd->scan_begin_arg;
929                         if (devpriv->transCount < cmd->chanlist_len) {
930                                 /* transfer after each scan (and avoid 0) */
931                                 devpriv->transCount = cmd->chanlist_len;
932                         } else {        /* make a multiple of scan length */
933                                 devpriv->transCount =
934                                     (devpriv->transCount +
935                                      cmd->chanlist_len - 1)
936                                     / cmd->chanlist_len;
937                                 devpriv->transCount *= cmd->chanlist_len;
938                         }
939                         devpriv->flags |= SEND_EOS;
940                 }
941                 if (devpriv->transCount >= (devpriv->fifoLen / 2)) {
942                         /* out of counter range, use 1/2 fifo instead */
943                         devpriv->transCount = 0;
944                         devpriv->flags &= ~SEND_EOS;
945                 } else {
946                         /* interrupt for each transfer */
947                         writel((devpriv->transCount - 1) & 0xffff,
948                                 devpriv->las0 + LAS0_ACNT);
949                 }
950         } else {                /* unknown timing, just use 1/2 FIFO */
951                 devpriv->transCount = 0;
952                 devpriv->flags &= ~SEND_EOS;
953         }
954         /* pacer clock source: INTERNAL 8MHz */
955         writel(1, devpriv->las0 + LAS0_PACER_SELECT);
956         /* just interrupt, don't stop */
957         writel(1, devpriv->las0 + LAS0_ACNT_STOP_ENABLE);
958
959         /* BUG??? these look like enumerated values, but they are bit fields */
960
961         /* First, setup when to stop */
962         switch (cmd->stop_src) {
963         case TRIG_COUNT:        /* stop after N scans */
964                 devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len;
965                 if ((devpriv->transCount > 0)
966                     && (devpriv->transCount > devpriv->aiCount)) {
967                         devpriv->transCount = devpriv->aiCount;
968                 }
969                 break;
970
971         case TRIG_NONE: /* stop when cancel is called */
972                 devpriv->aiCount = -1;  /* read forever */
973                 break;
974         }
975
976         /* Scan timing */
977         switch (cmd->scan_begin_src) {
978         case TRIG_TIMER:        /* periodic scanning */
979                 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
980                                         TRIG_ROUND_NEAREST);
981                 /* set PACER clock */
982                 writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
983
984                 break;
985
986         case TRIG_EXT:
987                 /* pacer start source: EXTERNAL */
988                 writel(1, devpriv->las0 + LAS0_PACER_START);
989                 break;
990         }
991
992         /* Sample timing within a scan */
993         switch (cmd->convert_src) {
994         case TRIG_TIMER:        /* periodic */
995                 if (cmd->chanlist_len > 1) {
996                         /* only needed for multi-channel */
997                         timer = rtd_ns_to_timer(&cmd->convert_arg,
998                                                 TRIG_ROUND_NEAREST);
999                         /* setup BURST clock */
1000                         writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
1001                 }
1002
1003                 break;
1004
1005         case TRIG_EXT:          /* external */
1006                 /* burst trigger source: EXTERNAL */
1007                 writel(2, devpriv->las0 + LAS0_BURST_START);
1008                 break;
1009         }
1010         /* end configuration */
1011
1012         /* This doesn't seem to work.  There is no way to clear an interrupt
1013            that the priority controller has queued! */
1014         devpriv->intClearMask = ~0;
1015         writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
1016         readw(devpriv->las0 + LAS0_CLEAR);
1017
1018         /* TODO: allow multiple interrupt sources */
1019         if (devpriv->transCount > 0) {  /* transfer every N samples */
1020                 devpriv->intMask = IRQM_ADC_ABOUT_CNT;
1021                 writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
1022         } else {                /* 1/2 FIFO transfers */
1023                 devpriv->intMask = IRQM_ADC_ABOUT_CNT;
1024                 writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
1025         }
1026
1027         /* BUG: start_src is ASSUMED to be TRIG_NOW */
1028         /* BUG? it seems like things are running before the "start" */
1029         readl(devpriv->las0 + LAS0_PACER);      /* start pacer */
1030         return 0;
1031 }
1032
1033 /*
1034   Stop a running data acquisition.
1035 */
1036 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1037 {
1038         struct rtdPrivate *devpriv = dev->private;
1039         u32 overrun;
1040         u16 status;
1041
1042         /* pacer stop source: SOFTWARE */
1043         writel(0, devpriv->las0 + LAS0_PACER_STOP);
1044         writel(0, devpriv->las0 + LAS0_PACER);  /* stop pacer */
1045         writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
1046         devpriv->intMask = 0;
1047         writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
1048         devpriv->aiCount = 0;   /* stop and don't transfer any more */
1049         status = readw(devpriv->las0 + LAS0_IT);
1050         overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
1051         return 0;
1052 }
1053
1054 /*
1055   Output one (or more) analog values to a single port as fast as possible.
1056 */
1057 static int rtd_ao_winsn(struct comedi_device *dev,
1058                         struct comedi_subdevice *s, struct comedi_insn *insn,
1059                         unsigned int *data)
1060 {
1061         struct rtdPrivate *devpriv = dev->private;
1062         int i;
1063         int chan = CR_CHAN(insn->chanspec);
1064         int range = CR_RANGE(insn->chanspec);
1065
1066         /* Configure the output range (table index matches the range values) */
1067         writew(range & 7, devpriv->las0 +
1068                 ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
1069
1070         /* Writing a list of values to an AO channel is probably not
1071          * very useful, but that's how the interface is defined. */
1072         for (i = 0; i < insn->n; ++i) {
1073                 int val = data[i] << 3;
1074                 int stat = 0;   /* initialize to avoid bogus warning */
1075                 int ii;
1076
1077                 /* VERIFY: comedi range and offset conversions */
1078
1079                 if ((range > 1) /* bipolar */
1080                     && (data[i] < 2048)) {
1081                         /* offset and sign extend */
1082                         val = (((int)data[i]) - 2048) << 3;
1083                 } else {        /* unipolor */
1084                         val = data[i] << 3;
1085                 }
1086
1087                 /* a typical programming sequence */
1088                 writew(val, devpriv->las1 +
1089                         ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
1090                 writew(0, devpriv->las0 +
1091                         ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
1092
1093                 devpriv->aoValue[chan] = data[i];       /* save for read back */
1094
1095                 for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
1096                         stat = readl(devpriv->las0 + LAS0_ADC);
1097                         /* 1 -> not empty */
1098                         if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
1099                                     FS_DAC2_NOT_EMPTY))
1100                                 break;
1101                         WAIT_QUIETLY;
1102                 }
1103                 if (ii >= RTD_DAC_TIMEOUT)
1104                         return -ETIMEDOUT;
1105         }
1106
1107         /* return the number of samples read/written */
1108         return i;
1109 }
1110
1111 /* AO subdevices should have a read insn as well as a write insn.
1112  * Usually this means copying a value stored in devpriv. */
1113 static int rtd_ao_rinsn(struct comedi_device *dev,
1114                         struct comedi_subdevice *s, struct comedi_insn *insn,
1115                         unsigned int *data)
1116 {
1117         struct rtdPrivate *devpriv = dev->private;
1118         int i;
1119         int chan = CR_CHAN(insn->chanspec);
1120
1121         for (i = 0; i < insn->n; i++)
1122                 data[i] = devpriv->aoValue[chan];
1123
1124
1125         return i;
1126 }
1127
1128 /*
1129    Write a masked set of bits and the read back the port.
1130    We track what the bits should be (i.e. we don't read the port first).
1131
1132    DIO devices are slightly special.  Although it is possible to
1133  * implement the insn_read/insn_write interface, it is much more
1134  * useful to applications if you implement the insn_bits interface.
1135  * This allows packed reading/writing of the DIO channels.  The
1136  * comedi core can convert between insn_bits and insn_read/write
1137  */
1138 static int rtd_dio_insn_bits(struct comedi_device *dev,
1139                              struct comedi_subdevice *s,
1140                              struct comedi_insn *insn, unsigned int *data)
1141 {
1142         struct rtdPrivate *devpriv = dev->private;
1143
1144         /* The insn data is a mask in data[0] and the new data
1145          * in data[1], each channel cooresponding to a bit. */
1146         if (data[0]) {
1147                 s->state &= ~data[0];
1148                 s->state |= data[0] & data[1];
1149
1150                 /* Write out the new digital output lines */
1151                 writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
1152         }
1153         /* on return, data[1] contains the value of the digital
1154          * input lines. */
1155         data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
1156
1157         return insn->n;
1158 }
1159
1160 /*
1161   Configure one bit on a IO port as Input or Output (hence the name :-).
1162 */
1163 static int rtd_dio_insn_config(struct comedi_device *dev,
1164                                struct comedi_subdevice *s,
1165                                struct comedi_insn *insn, unsigned int *data)
1166 {
1167         struct rtdPrivate *devpriv = dev->private;
1168         int chan = CR_CHAN(insn->chanspec);
1169
1170         /* The input or output configuration of each digital line is
1171          * configured by a special insn_config instruction.  chanspec
1172          * contains the channel to be changed, and data[0] contains the
1173          * value COMEDI_INPUT or COMEDI_OUTPUT. */
1174         switch (data[0]) {
1175         case INSN_CONFIG_DIO_OUTPUT:
1176                 s->io_bits |= 1 << chan;        /* 1 means Out */
1177                 break;
1178         case INSN_CONFIG_DIO_INPUT:
1179                 s->io_bits &= ~(1 << chan);
1180                 break;
1181         case INSN_CONFIG_DIO_QUERY:
1182                 data[1] =
1183                     (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1184                 return insn->n;
1185                 break;
1186         default:
1187                 return -EINVAL;
1188         }
1189
1190         /* TODO support digital match interrupts and strobes */
1191         devpriv->dioStatus = 0x01;      /* set direction */
1192         writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
1193         writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
1194         devpriv->dioStatus = 0x00;      /* clear interrupts */
1195         writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
1196
1197         /* port1 can only be all input or all output */
1198
1199         /* there are also 2 user input lines and 2 user output lines */
1200
1201         return 1;
1202 }
1203
1204 static void rtd_reset(struct comedi_device *dev)
1205 {
1206         struct rtdPrivate *devpriv = dev->private;
1207
1208         writel(0, devpriv->las0 + LAS0_BOARD_RESET);
1209         udelay(100);            /* needed? */
1210         writel(0, devpriv->lcfg + LCFG_ITCSR);
1211         devpriv->intMask = 0;
1212         writew(devpriv->intMask, devpriv->las0 + LAS0_IT);
1213         devpriv->intClearMask = ~0;
1214         writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR);
1215         readw(devpriv->las0 + LAS0_CLEAR);
1216 }
1217
1218 /*
1219  * initialize board, per RTD spec
1220  * also, initialize shadow registers
1221  */
1222 static void rtd_init_board(struct comedi_device *dev)
1223 {
1224         struct rtdPrivate *devpriv = dev->private;
1225
1226         rtd_reset(dev);
1227
1228         writel(0, devpriv->las0 + LAS0_OVERRUN);
1229         writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
1230         writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
1231         writel(0, devpriv->las0 + LAS0_DAC1_RESET);
1232         writel(0, devpriv->las0 + LAS0_DAC2_RESET);
1233         /* clear digital IO fifo */
1234         devpriv->dioStatus = 0;
1235         writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS);
1236         devpriv->utcCtrl[0] = (0 << 6) | 0x30;
1237         devpriv->utcCtrl[1] = (1 << 6) | 0x30;
1238         devpriv->utcCtrl[2] = (2 << 6) | 0x30;
1239         devpriv->utcCtrl[3] = (3 << 6) | 0x00;
1240         writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL);
1241         writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL);
1242         writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL);
1243         writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL);
1244         /* TODO: set user out source ??? */
1245 }
1246
1247 /* The RTD driver does this */
1248 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1249                                   struct pci_dev *pcidev)
1250 {
1251         unsigned char pci_latency;
1252
1253         pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1254         if (pci_latency < 32) {
1255                 dev_info(dev->class_dev,
1256                         "PCI latency changed from %d to %d\n",
1257                         pci_latency, 32);
1258                 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1259         }
1260 }
1261
1262 static const void *rtd_find_boardinfo(struct comedi_device *dev,
1263                                       struct pci_dev *pcidev)
1264 {
1265         const struct rtdBoard *thisboard;
1266         int i;
1267
1268         for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) {
1269                 thisboard = &rtd520Boards[i];
1270                 if (pcidev->device == thisboard->device_id)
1271                         return thisboard;
1272         }
1273         return NULL;
1274 }
1275
1276 static int rtd_auto_attach(struct comedi_device *dev,
1277                                      unsigned long context_unused)
1278 {
1279         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1280         const struct rtdBoard *thisboard;
1281         struct rtdPrivate *devpriv;
1282         struct comedi_subdevice *s;
1283         int ret;
1284
1285         thisboard = rtd_find_boardinfo(dev, pcidev);
1286         if (!thisboard)
1287                 return -ENODEV;
1288         dev->board_ptr = thisboard;
1289         dev->board_name = thisboard->name;
1290
1291         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1292         if (!devpriv)
1293                 return -ENOMEM;
1294         dev->private = devpriv;
1295
1296         ret = comedi_pci_enable(pcidev, dev->board_name);
1297         if (ret)
1298                 return ret;
1299         dev->iobase = 1;        /* the "detach" needs this */
1300
1301         devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2),
1302                                         pci_resource_len(pcidev, 2));
1303         devpriv->las1 = ioremap_nocache(pci_resource_start(pcidev, 3),
1304                                         pci_resource_len(pcidev, 3));
1305         devpriv->lcfg = ioremap_nocache(pci_resource_start(pcidev, 0),
1306                                         pci_resource_len(pcidev, 0));
1307         if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
1308                 return -ENOMEM;
1309
1310         rtd_pci_latency_quirk(dev, pcidev);
1311
1312         if (pcidev->irq) {
1313                 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1314                                   dev->board_name, dev);
1315                 if (ret == 0)
1316                         dev->irq = pcidev->irq;
1317         }
1318
1319         ret = comedi_alloc_subdevices(dev, 4);
1320         if (ret)
1321                 return ret;
1322
1323         s = &dev->subdevices[0];
1324         /* analog input subdevice */
1325         s->type         = COMEDI_SUBD_AI;
1326         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1327         s->n_chan       = 16;
1328         s->maxdata      = 0x0fff;
1329         s->range_table  = thisboard->ai_range;
1330         s->len_chanlist = RTD_MAX_CHANLIST;
1331         s->insn_read    = rtd_ai_rinsn;
1332         if (dev->irq) {
1333                 dev->read_subdev = s;
1334                 s->subdev_flags |= SDF_CMD_READ;
1335                 s->do_cmd       = rtd_ai_cmd;
1336                 s->do_cmdtest   = rtd_ai_cmdtest;
1337                 s->cancel       = rtd_ai_cancel;
1338         }
1339
1340         s = &dev->subdevices[1];
1341         /* analog output subdevice */
1342         s->type         = COMEDI_SUBD_AO;
1343         s->subdev_flags = SDF_WRITABLE;
1344         s->n_chan       = 2;
1345         s->maxdata      = 0x0fff;
1346         s->range_table  = &rtd_ao_range;
1347         s->insn_write   = rtd_ao_winsn;
1348         s->insn_read    = rtd_ao_rinsn;
1349
1350         s = &dev->subdevices[2];
1351         /* digital i/o subdevice */
1352         s->type         = COMEDI_SUBD_DIO;
1353         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1354         /* we only support port 0 right now.  Ignoring port 1 and user IO */
1355         s->n_chan       = 8;
1356         s->maxdata      = 1;
1357         s->range_table  = &range_digital;
1358         s->insn_bits    = rtd_dio_insn_bits;
1359         s->insn_config  = rtd_dio_insn_config;
1360
1361         /* timer/counter subdevices (not currently supported) */
1362         s = &dev->subdevices[3];
1363         s->type         = COMEDI_SUBD_COUNTER;
1364         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1365         s->n_chan       = 3;
1366         s->maxdata      = 0xffff;
1367
1368         rtd_init_board(dev);
1369
1370         ret = rtd520_probe_fifo_depth(dev);
1371         if (ret < 0)
1372                 return ret;
1373         devpriv->fifoLen = ret;
1374
1375         if (dev->irq)
1376                 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR);
1377
1378         dev_info(dev->class_dev, "%s attached\n", dev->board_name);
1379
1380         return 0;
1381 }
1382
1383 static void rtd_detach(struct comedi_device *dev)
1384 {
1385         struct rtdPrivate *devpriv = dev->private;
1386         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1387
1388         if (devpriv) {
1389                 /* Shut down any board ops by resetting it */
1390                 if (devpriv->las0 && devpriv->lcfg)
1391                         rtd_reset(dev);
1392                 if (dev->irq) {
1393                         writel(readl(devpriv->lcfg + LCFG_ITCSR) &
1394                                 ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
1395                                 devpriv->lcfg + LCFG_ITCSR);
1396                         free_irq(dev->irq, dev);
1397                 }
1398                 if (devpriv->las0)
1399                         iounmap(devpriv->las0);
1400                 if (devpriv->las1)
1401                         iounmap(devpriv->las1);
1402                 if (devpriv->lcfg)
1403                         iounmap(devpriv->lcfg);
1404         }
1405         if (pcidev) {
1406                 if (dev->iobase)
1407                         comedi_pci_disable(pcidev);
1408         }
1409 }
1410
1411 static struct comedi_driver rtd520_driver = {
1412         .driver_name    = "rtd520",
1413         .module         = THIS_MODULE,
1414         .auto_attach    = rtd_auto_attach,
1415         .detach         = rtd_detach,
1416 };
1417
1418 static int rtd520_pci_probe(struct pci_dev *dev,
1419                                       const struct pci_device_id *ent)
1420 {
1421         return comedi_pci_auto_config(dev, &rtd520_driver);
1422 }
1423
1424 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
1425         { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) },
1426         { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) },
1427         { 0 }
1428 };
1429 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1430
1431 static struct pci_driver rtd520_pci_driver = {
1432         .name           = "rtd520",
1433         .id_table       = rtd520_pci_table,
1434         .probe          = rtd520_pci_probe,
1435         .remove         = comedi_pci_auto_unconfig,
1436 };
1437 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1438
1439 MODULE_AUTHOR("Comedi http://www.comedi.org");
1440 MODULE_DESCRIPTION("Comedi low-level driver");
1441 MODULE_LICENSE("GPL");