Version:  2.0.40 2.2.26 2.4.37 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19

Linux/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 
 19 /*
 20  * Driver: rtd520
 21  * Description: Real Time Devices PCI4520/DM7520
 22  * Devices: (Real Time Devices) DM7520HR-1 [DM7520]
 23  *          (Real Time Devices) DM7520HR-8 [DM7520]
 24  *          (Real Time Devices) PCI4520 [PCI4520]
 25  *          (Real Time Devices) PCI4520-8 [PCI4520]
 26  * Author: Dan Christian
 27  * Status: Works. Only tested on DM7520-8. Not SMP safe.
 28  *
 29  * Configuration options: not applicable, uses PCI auto config
 30  */
 31 
 32 /*
 33  * Created by Dan Christian, NASA Ames Research Center.
 34  *
 35  * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
 36  * Both have:
 37  *   8/16 12 bit ADC with FIFO and channel gain table
 38  *   8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
 39  *   8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
 40  *   2 12 bit DACs with FIFOs
 41  *   2 bits output
 42  *   2 bits input
 43  *   bus mastering DMA
 44  *   timers: ADC sample, pacer, burst, about, delay, DA1, DA2
 45  *   sample counter
 46  *   3 user timer/counters (8254)
 47  *   external interrupt
 48  *
 49  * The DM7520 has slightly fewer features (fewer gain steps).
 50  *
 51  * These boards can support external multiplexors and multi-board
 52  * synchronization, but this driver doesn't support that.
 53  *
 54  * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
 55  * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
 56  * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
 57  * Call them and ask for the register level manual.
 58  * PCI chip: http://www.plxtech.com/products/io/pci9080
 59  *
 60  * Notes:
 61  * This board is memory mapped. There is some IO stuff, but it isn't needed.
 62  *
 63  * I use a pretty loose naming style within the driver (rtd_blah).
 64  * All externally visible names should be rtd520_blah.
 65  * I use camelCase for structures (and inside them).
 66  * I may also use upper CamelCase for function names (old habit).
 67  *
 68  * This board is somewhat related to the RTD PCI4400 board.
 69  *
 70  * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
 71  * das1800, since they have the best documented code. Driver cb_pcidas64.c
 72  * uses the same DMA controller.
 73  *
 74  * As far as I can tell, the About interrupt doesn't work if Sample is
 75  * also enabled. It turns out that About really isn't needed, since
 76  * we always count down samples read.
 77  *
 78  * There was some timer/counter code, but it didn't follow the right API.
 79  */
 80 
 81 /*
 82  * driver status:
 83  *
 84  * Analog-In supports instruction and command mode.
 85  *
 86  * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
 87  * (single channel, 64K read buffer). I get random system lockups when
 88  * using DMA with ALI-15xx based systems. I haven't been able to test
 89  * any other chipsets. The lockups happen soon after the start of an
 90  * acquistion, not in the middle of a long run.
 91  *
 92  * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
 93  * (with a 256K read buffer).
 94  *
 95  * Digital-IO and Analog-Out only support instruction mode.
 96  */
 97 
 98 #include <linux/module.h>
 99 #include <linux/pci.h>
100 #include <linux/delay.h>
101 #include <linux/interrupt.h>
102 
103 #include "../comedidev.h"
104 
105 #include "comedi_fc.h"
106 #include "plx9080.h"
107 
108 /*
109  * Local Address Space 0 Offsets
110  */
111 #define LAS0_USER_IO            0x0008  /* User I/O */
112 #define LAS0_ADC                0x0010  /* FIFO Status/Software A/D Start */
113 #define FS_DAC1_NOT_EMPTY       (1 << 0)        /* DAC1 FIFO not empty */
114 #define FS_DAC1_HEMPTY          (1 << 1)        /* DAC1 FIFO half empty */
115 #define FS_DAC1_NOT_FULL        (1 << 2)        /* DAC1 FIFO not full */
116 #define FS_DAC2_NOT_EMPTY       (1 << 4)        /* DAC2 FIFO not empty */
117 #define FS_DAC2_HEMPTY          (1 << 5)        /* DAC2 FIFO half empty */
118 #define FS_DAC2_NOT_FULL        (1 << 6)        /* DAC2 FIFO not full */
119 #define FS_ADC_NOT_EMPTY        (1 << 8)        /* ADC FIFO not empty */
120 #define FS_ADC_HEMPTY           (1 << 9)        /* ADC FIFO half empty */
121 #define FS_ADC_NOT_FULL         (1 << 10)       /* ADC FIFO not full */
122 #define FS_DIN_NOT_EMPTY        (1 << 12)       /* DIN FIFO not empty */
123 #define FS_DIN_HEMPTY           (1 << 13)       /* DIN FIFO half empty */
124 #define FS_DIN_NOT_FULL         (1 << 14)       /* DIN FIFO not full */
125 #define LAS0_DAC1               0x0014  /* Software D/A1 Update (w) */
126 #define LAS0_DAC2               0x0018  /* Software D/A2 Update (w) */
127 #define LAS0_DAC                0x0024  /* Software Simultaneous Update (w) */
128 #define LAS0_PACER              0x0028  /* Software Pacer Start/Stop */
129 #define LAS0_TIMER              0x002c  /* Timer Status/HDIN Software Trig. */
130 #define LAS0_IT                 0x0030  /* Interrupt Status/Enable */
131 #define IRQM_ADC_FIFO_WRITE     (1 << 0)        /* ADC FIFO Write */
132 #define IRQM_CGT_RESET          (1 << 1)        /* Reset CGT */
133 #define IRQM_CGT_PAUSE          (1 << 3)        /* Pause CGT */
134 #define IRQM_ADC_ABOUT_CNT      (1 << 4)        /* About Counter out */
135 #define IRQM_ADC_DELAY_CNT      (1 << 5)        /* Delay Counter out */
136 #define IRQM_ADC_SAMPLE_CNT     (1 << 6)        /* ADC Sample Counter */
137 #define IRQM_DAC1_UCNT          (1 << 7)        /* DAC1 Update Counter */
138 #define IRQM_DAC2_UCNT          (1 << 8)        /* DAC2 Update Counter */
139 #define IRQM_UTC1               (1 << 9)        /* User TC1 out */
140 #define IRQM_UTC1_INV           (1 << 10)       /* User TC1 out, inverted */
141 #define IRQM_UTC2               (1 << 11)       /* User TC2 out */
142 #define IRQM_DIGITAL_IT         (1 << 12)       /* Digital Interrupt */
143 #define IRQM_EXTERNAL_IT        (1 << 13)       /* External Interrupt */
144 #define IRQM_ETRIG_RISING       (1 << 14)       /* Ext Trigger rising-edge */
145 #define IRQM_ETRIG_FALLING      (1 << 15)       /* Ext Trigger falling-edge */
146 #define LAS0_CLEAR              0x0034  /* Clear/Set Interrupt Clear Mask */
147 #define LAS0_OVERRUN            0x0038  /* Pending interrupts/Clear Overrun */
148 #define LAS0_PCLK               0x0040  /* Pacer Clock (24bit) */
149 #define LAS0_BCLK               0x0044  /* Burst Clock (10bit) */
150 #define LAS0_ADC_SCNT           0x0048  /* A/D Sample counter (10bit) */
151 #define LAS0_DAC1_UCNT          0x004c  /* D/A1 Update counter (10 bit) */
152 #define LAS0_DAC2_UCNT          0x0050  /* D/A2 Update counter (10 bit) */
153 #define LAS0_DCNT               0x0054  /* Delay counter (16 bit) */
154 #define LAS0_ACNT               0x0058  /* About counter (16 bit) */
155 #define LAS0_DAC_CLK            0x005c  /* DAC clock (16bit) */
156 #define LAS0_UTC0               0x0060  /* 8254 TC Counter 0 */
157 #define LAS0_UTC1               0x0064  /* 8254 TC Counter 1 */
158 #define LAS0_UTC2               0x0068  /* 8254 TC Counter 2 */
159 #define LAS0_UTC_CTRL           0x006c  /* 8254 TC Control */
160 #define LAS0_DIO0               0x0070  /* Digital I/O Port 0 */
161 #define LAS0_DIO1               0x0074  /* Digital I/O Port 1 */
162 #define LAS0_DIO0_CTRL          0x0078  /* Digital I/O Control */
163 #define LAS0_DIO_STATUS         0x007c  /* Digital I/O Status */
164 #define LAS0_BOARD_RESET        0x0100  /* Board reset */
165 #define LAS0_DMA0_SRC           0x0104  /* DMA 0 Sources select */
166 #define LAS0_DMA1_SRC           0x0108  /* DMA 1 Sources select */
167 #define LAS0_ADC_CONVERSION     0x010c  /* A/D Conversion Signal select */
168 #define LAS0_BURST_START        0x0110  /* Burst Clock Start Trigger select */
169 #define LAS0_PACER_START        0x0114  /* Pacer Clock Start Trigger select */
170 #define LAS0_PACER_STOP         0x0118  /* Pacer Clock Stop Trigger select */
171 #define LAS0_ACNT_STOP_ENABLE   0x011c  /* About Counter Stop Enable */
172 #define LAS0_PACER_REPEAT       0x0120  /* Pacer Start Trigger Mode select */
173 #define LAS0_DIN_START          0x0124  /* HiSpd DI Sampling Signal select */
174 #define LAS0_DIN_FIFO_CLEAR     0x0128  /* Digital Input FIFO Clear */
175 #define LAS0_ADC_FIFO_CLEAR     0x012c  /* A/D FIFO Clear */
176 #define LAS0_CGT_WRITE          0x0130  /* Channel Gain Table Write */
177 #define LAS0_CGL_WRITE          0x0134  /* Channel Gain Latch Write */
178 #define LAS0_CG_DATA            0x0138  /* Digital Table Write */
179 #define LAS0_CGT_ENABLE         0x013c  /* Channel Gain Table Enable */
180 #define LAS0_CG_ENABLE          0x0140  /* Digital Table Enable */
181 #define LAS0_CGT_PAUSE          0x0144  /* Table Pause Enable */
182 #define LAS0_CGT_RESET          0x0148  /* Reset Channel Gain Table */
183 #define LAS0_CGT_CLEAR          0x014c  /* Clear Channel Gain Table */
184 #define LAS0_DAC1_CTRL          0x0150  /* D/A1 output type/range */
185 #define LAS0_DAC1_SRC           0x0154  /* D/A1 update source */
186 #define LAS0_DAC1_CYCLE         0x0158  /* D/A1 cycle mode */
187 #define LAS0_DAC1_RESET         0x015c  /* D/A1 FIFO reset */
188 #define LAS0_DAC1_FIFO_CLEAR    0x0160  /* D/A1 FIFO clear */
189 #define LAS0_DAC2_CTRL          0x0164  /* D/A2 output type/range */
190 #define LAS0_DAC2_SRC           0x0168  /* D/A2 update source */
191 #define LAS0_DAC2_CYCLE         0x016c  /* D/A2 cycle mode */
192 #define LAS0_DAC2_RESET         0x0170  /* D/A2 FIFO reset */
193 #define LAS0_DAC2_FIFO_CLEAR    0x0174  /* D/A2 FIFO clear */
194 #define LAS0_ADC_SCNT_SRC       0x0178  /* A/D Sample Counter Source select */
195 #define LAS0_PACER_SELECT       0x0180  /* Pacer Clock select */
196 #define LAS0_SBUS0_SRC          0x0184  /* SyncBus 0 Source select */
197 #define LAS0_SBUS0_ENABLE       0x0188  /* SyncBus 0 enable */
198 #define LAS0_SBUS1_SRC          0x018c  /* SyncBus 1 Source select */
199 #define LAS0_SBUS1_ENABLE       0x0190  /* SyncBus 1 enable */
200 #define LAS0_SBUS2_SRC          0x0198  /* SyncBus 2 Source select */
201 #define LAS0_SBUS2_ENABLE       0x019c  /* SyncBus 2 enable */
202 #define LAS0_ETRG_POLARITY      0x01a4  /* Ext. Trigger polarity select */
203 #define LAS0_EINT_POLARITY      0x01a8  /* Ext. Interrupt polarity select */
204 #define LAS0_UTC0_CLOCK         0x01ac  /* UTC0 Clock select */
205 #define LAS0_UTC0_GATE          0x01b0  /* UTC0 Gate select */
206 #define LAS0_UTC1_CLOCK         0x01b4  /* UTC1 Clock select */
207 #define LAS0_UTC1_GATE          0x01b8  /* UTC1 Gate select */
208 #define LAS0_UTC2_CLOCK         0x01bc  /* UTC2 Clock select */
209 #define LAS0_UTC2_GATE          0x01c0  /* UTC2 Gate select */
210 #define LAS0_UOUT0_SELECT       0x01c4  /* User Output 0 source select */
211 #define LAS0_UOUT1_SELECT       0x01c8  /* User Output 1 source select */
212 #define LAS0_DMA0_RESET         0x01cc  /* DMA0 Request state machine reset */
213 #define LAS0_DMA1_RESET         0x01d0  /* DMA1 Request state machine reset */
214 
215 /*
216  * Local Address Space 1 Offsets
217  */
218 #define LAS1_ADC_FIFO           0x0000  /* A/D FIFO (16bit) */
219 #define LAS1_HDIO_FIFO          0x0004  /* HiSpd DI FIFO (16bit) */
220 #define LAS1_DAC1_FIFO          0x0008  /* D/A1 FIFO (16bit) */
221 #define LAS1_DAC2_FIFO          0x000c  /* D/A2 FIFO (16bit) */
222 
223 /*======================================================================
224   Driver specific stuff (tunable)
225 ======================================================================*/
226 
227 /* We really only need 2 buffers.  More than that means being much
228    smarter about knowing which ones are full. */
229 #define DMA_CHAIN_COUNT 2       /* max DMA segments/buffers in a ring (min 2) */
230 
231 /* Target period for periodic transfers.  This sets the user read latency. */
232 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
233 /* If this is too low, efficiency is poor */
234 #define TRANS_TARGET_PERIOD 10000000    /* 10 ms (in nanoseconds) */
235 
236 /* Set a practical limit on how long a list to support (affects memory use) */
237 /* The board support a channel list up to the FIFO length (1K or 8K) */
238 #define RTD_MAX_CHANLIST        128     /* max channel list that we allow */
239 
240 /*======================================================================
241   Board specific stuff
242 ======================================================================*/
243 
244 #define RTD_CLOCK_RATE  8000000 /* 8Mhz onboard clock */
245 #define RTD_CLOCK_BASE  125     /* clock period in ns */
246 
247 /* Note: these speed are slower than the spec, but fit the counter resolution*/
248 #define RTD_MAX_SPEED   1625    /* when sampling, in nanoseconds */
249 /* max speed if we don't have to wait for settling */
250 #define RTD_MAX_SPEED_1 875     /* if single channel, in nanoseconds */
251 
252 #define RTD_MIN_SPEED   2097151875      /* (24bit counter) in nanoseconds */
253 /* min speed when only 1 channel (no burst counter) */
254 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
255 
256 /* Setup continuous ring of 1/2 FIFO transfers.  See RTD manual p91 */
257 #define DMA_MODE_BITS (\
258                        PLX_LOCAL_BUS_16_WIDE_BITS \
259                        | PLX_DMA_EN_READYIN_BIT \
260                        | PLX_DMA_LOCAL_BURST_EN_BIT \
261                        | PLX_EN_CHAIN_BIT \
262                        | PLX_DMA_INTR_PCI_BIT \
263                        | PLX_LOCAL_ADDR_CONST_BIT \
264                        | PLX_DEMAND_MODE_BIT)
265 
266 #define DMA_TRANSFER_BITS (\
267 /* descriptors in PCI memory*/  PLX_DESC_IN_PCI_BIT \
268 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
269 /* from board to PCI */         | PLX_XFER_LOCAL_TO_PCI)
270 
271 /*======================================================================
272   Comedi specific stuff
273 ======================================================================*/
274 
275 /*
276  * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
277  */
278 static const struct comedi_lrange rtd_ai_7520_range = {
279         18, {
280                 /* +-5V input range gain steps */
281                 BIP_RANGE(5.0),
282                 BIP_RANGE(5.0 / 2),
283                 BIP_RANGE(5.0 / 4),
284                 BIP_RANGE(5.0 / 8),
285                 BIP_RANGE(5.0 / 16),
286                 BIP_RANGE(5.0 / 32),
287                 /* +-10V input range gain steps */
288                 BIP_RANGE(10.0),
289                 BIP_RANGE(10.0 / 2),
290                 BIP_RANGE(10.0 / 4),
291                 BIP_RANGE(10.0 / 8),
292                 BIP_RANGE(10.0 / 16),
293                 BIP_RANGE(10.0 / 32),
294                 /* +10V input range gain steps */
295                 UNI_RANGE(10.0),
296                 UNI_RANGE(10.0 / 2),
297                 UNI_RANGE(10.0 / 4),
298                 UNI_RANGE(10.0 / 8),
299                 UNI_RANGE(10.0 / 16),
300                 UNI_RANGE(10.0 / 32),
301         }
302 };
303 
304 /* PCI4520 has two more gains (6 more entries) */
305 static const struct comedi_lrange rtd_ai_4520_range = {
306         24, {
307                 /* +-5V input range gain steps */
308                 BIP_RANGE(5.0),
309                 BIP_RANGE(5.0 / 2),
310                 BIP_RANGE(5.0 / 4),
311                 BIP_RANGE(5.0 / 8),
312                 BIP_RANGE(5.0 / 16),
313                 BIP_RANGE(5.0 / 32),
314                 BIP_RANGE(5.0 / 64),
315                 BIP_RANGE(5.0 / 128),
316                 /* +-10V input range gain steps */
317                 BIP_RANGE(10.0),
318                 BIP_RANGE(10.0 / 2),
319                 BIP_RANGE(10.0 / 4),
320                 BIP_RANGE(10.0 / 8),
321                 BIP_RANGE(10.0 / 16),
322                 BIP_RANGE(10.0 / 32),
323                 BIP_RANGE(10.0 / 64),
324                 BIP_RANGE(10.0 / 128),
325                 /* +10V input range gain steps */
326                 UNI_RANGE(10.0),
327                 UNI_RANGE(10.0 / 2),
328                 UNI_RANGE(10.0 / 4),
329                 UNI_RANGE(10.0 / 8),
330                 UNI_RANGE(10.0 / 16),
331                 UNI_RANGE(10.0 / 32),
332                 UNI_RANGE(10.0 / 64),
333                 UNI_RANGE(10.0 / 128),
334         }
335 };
336 
337 /* Table order matches range values */
338 static const struct comedi_lrange rtd_ao_range = {
339         4, {
340                 UNI_RANGE(5),
341                 UNI_RANGE(10),
342                 BIP_RANGE(5),
343                 BIP_RANGE(10),
344         }
345 };
346 
347 enum rtd_boardid {
348         BOARD_DM7520,
349         BOARD_PCI4520,
350 };
351 
352 struct rtd_boardinfo {
353         const char *name;
354         int range_bip10;        /* start of +-10V range */
355         int range_uni10;        /* start of +10V range */
356         const struct comedi_lrange *ai_range;
357 };
358 
359 static const struct rtd_boardinfo rtd520Boards[] = {
360         [BOARD_DM7520] = {
361                 .name           = "DM7520",
362                 .range_bip10    = 6,
363                 .range_uni10    = 12,
364                 .ai_range       = &rtd_ai_7520_range,
365         },
366         [BOARD_PCI4520] = {
367                 .name           = "PCI4520",
368                 .range_bip10    = 8,
369                 .range_uni10    = 16,
370                 .ai_range       = &rtd_ai_4520_range,
371         },
372 };
373 
374 struct rtd_private {
375         /* memory mapped board structures */
376         void __iomem *las1;
377         void __iomem *lcfg;
378 
379         long ai_count;          /* total transfer size (samples) */
380         int xfer_count;         /* # to transfer data. 0->1/2FIFO */
381         int flags;              /* flag event modes */
382         unsigned fifosz;
383 };
384 
385 /* bit defines for "flags" */
386 #define SEND_EOS        0x01    /* send End Of Scan events */
387 #define DMA0_ACTIVE     0x02    /* DMA0 is active */
388 #define DMA1_ACTIVE     0x04    /* DMA1 is active */
389 
390 /*
391   Given a desired period and the clock period (both in ns),
392   return the proper counter value (divider-1).
393   Sets the original period to be the true value.
394   Note: you have to check if the value is larger than the counter range!
395 */
396 static int rtd_ns_to_timer_base(unsigned int *nanosec,
397                                 unsigned int flags, int base)
398 {
399         int divider;
400 
401         switch (flags & CMDF_ROUND_MASK) {
402         case CMDF_ROUND_NEAREST:
403         default:
404                 divider = (*nanosec + base / 2) / base;
405                 break;
406         case CMDF_ROUND_DOWN:
407                 divider = (*nanosec) / base;
408                 break;
409         case CMDF_ROUND_UP:
410                 divider = (*nanosec + base - 1) / base;
411                 break;
412         }
413         if (divider < 2)
414                 divider = 2;    /* min is divide by 2 */
415 
416         /* Note: we don't check for max, because different timers
417            have different ranges */
418 
419         *nanosec = base * divider;
420         return divider - 1;     /* countdown is divisor+1 */
421 }
422 
423 /*
424   Given a desired period (in ns),
425   return the proper counter value (divider-1) for the internal clock.
426   Sets the original period to be the true value.
427 */
428 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
429 {
430         return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
431 }
432 
433 /*
434   Convert a single comedi channel-gain entry to a RTD520 table entry
435 */
436 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
437                                             unsigned int chanspec, int index)
438 {
439         const struct rtd_boardinfo *board = dev->board_ptr;
440         unsigned int chan = CR_CHAN(chanspec);
441         unsigned int range = CR_RANGE(chanspec);
442         unsigned int aref = CR_AREF(chanspec);
443         unsigned short r = 0;
444 
445         r |= chan & 0xf;
446 
447         /* Note: we also setup the channel list bipolar flag array */
448         if (range < board->range_bip10) {
449                 /* +-5 range */
450                 r |= 0x000;
451                 r |= (range & 0x7) << 4;
452         } else if (range < board->range_uni10) {
453                 /* +-10 range */
454                 r |= 0x100;
455                 r |= ((range - board->range_bip10) & 0x7) << 4;
456         } else {
457                 /* +10 range */
458                 r |= 0x200;
459                 r |= ((range - board->range_uni10) & 0x7) << 4;
460         }
461 
462         switch (aref) {
463         case AREF_GROUND:       /* on-board ground */
464                 break;
465 
466         case AREF_COMMON:
467                 r |= 0x80;      /* ref external analog common */
468                 break;
469 
470         case AREF_DIFF:
471                 r |= 0x400;     /* differential inputs */
472                 break;
473 
474         case AREF_OTHER:        /* ??? */
475                 break;
476         }
477         return r;
478 }
479 
480 /*
481   Setup the channel-gain table from a comedi list
482 */
483 static void rtd_load_channelgain_list(struct comedi_device *dev,
484                                       unsigned int n_chan, unsigned int *list)
485 {
486         if (n_chan > 1) {       /* setup channel gain table */
487                 int ii;
488 
489                 writel(0, dev->mmio + LAS0_CGT_CLEAR);
490                 writel(1, dev->mmio + LAS0_CGT_ENABLE);
491                 for (ii = 0; ii < n_chan; ii++) {
492                         writel(rtd_convert_chan_gain(dev, list[ii], ii),
493                                dev->mmio + LAS0_CGT_WRITE);
494                 }
495         } else {                /* just use the channel gain latch */
496                 writel(0, dev->mmio + LAS0_CGT_ENABLE);
497                 writel(rtd_convert_chan_gain(dev, list[0], 0),
498                        dev->mmio + LAS0_CGL_WRITE);
499         }
500 }
501 
502 /* determine fifo size by doing adc conversions until the fifo half
503 empty status flag clears */
504 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
505 {
506         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
507         unsigned i;
508         static const unsigned limit = 0x2000;
509         unsigned fifo_size = 0;
510 
511         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
512         rtd_load_channelgain_list(dev, 1, &chanspec);
513         /* ADC conversion trigger source: SOFTWARE */
514         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
515         /* convert  samples */
516         for (i = 0; i < limit; ++i) {
517                 unsigned fifo_status;
518                 /* trigger conversion */
519                 writew(0, dev->mmio + LAS0_ADC);
520                 udelay(1);
521                 fifo_status = readl(dev->mmio + LAS0_ADC);
522                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
523                         fifo_size = 2 * i;
524                         break;
525                 }
526         }
527         if (i == limit) {
528                 dev_info(dev->class_dev, "failed to probe fifo size.\n");
529                 return -EIO;
530         }
531         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
532         if (fifo_size != 0x400 && fifo_size != 0x2000) {
533                 dev_info(dev->class_dev,
534                          "unexpected fifo size of %i, expected 1024 or 8192.\n",
535                          fifo_size);
536                 return -EIO;
537         }
538         return fifo_size;
539 }
540 
541 static int rtd_ai_eoc(struct comedi_device *dev,
542                       struct comedi_subdevice *s,
543                       struct comedi_insn *insn,
544                       unsigned long context)
545 {
546         unsigned int status;
547 
548         status = readl(dev->mmio + LAS0_ADC);
549         if (status & FS_ADC_NOT_EMPTY)
550                 return 0;
551         return -EBUSY;
552 }
553 
554 static int rtd_ai_rinsn(struct comedi_device *dev,
555                         struct comedi_subdevice *s, struct comedi_insn *insn,
556                         unsigned int *data)
557 {
558         struct rtd_private *devpriv = dev->private;
559         unsigned int range = CR_RANGE(insn->chanspec);
560         int ret;
561         int n;
562 
563         /* clear any old fifo data */
564         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
565 
566         /* write channel to multiplexer and clear channel gain table */
567         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
568 
569         /* ADC conversion trigger source: SOFTWARE */
570         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
571 
572         /* convert n samples */
573         for (n = 0; n < insn->n; n++) {
574                 unsigned short d;
575                 /* trigger conversion */
576                 writew(0, dev->mmio + LAS0_ADC);
577 
578                 ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
579                 if (ret)
580                         return ret;
581 
582                 /* read data */
583                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
584                 d = d >> 3;     /* low 3 bits are marker lines */
585 
586                 /* convert bipolar data to comedi unsigned data */
587                 if (comedi_range_is_bipolar(s, range))
588                         d = comedi_offset_munge(s, d);
589 
590                 data[n] = d & s->maxdata;
591         }
592 
593         /* return the number of samples read/written */
594         return n;
595 }
596 
597 /*
598   Get what we know is there.... Fast!
599   This uses 1/2 the bus cycles of read_dregs (below).
600 
601   The manual claims that we can do a lword read, but it doesn't work here.
602 */
603 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
604                      int count)
605 {
606         struct rtd_private *devpriv = dev->private;
607         struct comedi_async *async = s->async;
608         struct comedi_cmd *cmd = &async->cmd;
609         int ii;
610 
611         for (ii = 0; ii < count; ii++) {
612                 unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]);
613                 unsigned short d;
614 
615                 if (0 == devpriv->ai_count) {   /* done */
616                         d = readw(devpriv->las1 + LAS1_ADC_FIFO);
617                         continue;
618                 }
619 
620                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
621                 d = d >> 3;     /* low 3 bits are marker lines */
622 
623                 /* convert bipolar data to comedi unsigned data */
624                 if (comedi_range_is_bipolar(s, range))
625                         d = comedi_offset_munge(s, d);
626                 d &= s->maxdata;
627 
628                 if (!comedi_buf_write_samples(s, &d, 1))
629                         return -1;
630 
631                 if (devpriv->ai_count > 0)      /* < 0, means read forever */
632                         devpriv->ai_count--;
633         }
634         return 0;
635 }
636 
637 /*
638   Handle all rtd520 interrupts.
639   Runs atomically and is never re-entered.
640   This is a "slow handler";  other interrupts may be active.
641   The data conversion may someday happen in a "bottom half".
642 */
643 static irqreturn_t rtd_interrupt(int irq, void *d)
644 {
645         struct comedi_device *dev = d;
646         struct comedi_subdevice *s = dev->read_subdev;
647         struct rtd_private *devpriv = dev->private;
648         u32 overrun;
649         u16 status;
650         u16 fifo_status;
651 
652         if (!dev->attached)
653                 return IRQ_NONE;
654 
655         fifo_status = readl(dev->mmio + LAS0_ADC);
656         /* check for FIFO full, this automatically halts the ADC! */
657         if (!(fifo_status & FS_ADC_NOT_FULL))   /* 0 -> full */
658                 goto xfer_abort;
659 
660         status = readw(dev->mmio + LAS0_IT);
661         /* if interrupt was not caused by our board, or handled above */
662         if (0 == status)
663                 return IRQ_HANDLED;
664 
665         if (status & IRQM_ADC_ABOUT_CNT) {      /* sample count -> read FIFO */
666                 /*
667                  * since the priority interrupt controller may have queued
668                  * a sample counter interrupt, even though we have already
669                  * finished, we must handle the possibility that there is
670                  * no data here
671                  */
672                 if (!(fifo_status & FS_ADC_HEMPTY)) {
673                         /* FIFO half full */
674                         if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
675                                 goto xfer_abort;
676 
677                         if (0 == devpriv->ai_count)
678                                 goto xfer_done;
679                 } else if (devpriv->xfer_count > 0) {
680                         if (fifo_status & FS_ADC_NOT_EMPTY) {
681                                 /* FIFO not empty */
682                                 if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
683                                         goto xfer_abort;
684 
685                                 if (0 == devpriv->ai_count)
686                                         goto xfer_done;
687                         }
688                 }
689         }
690 
691         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
692         if (overrun)
693                 goto xfer_abort;
694 
695         /* clear the interrupt */
696         writew(status, dev->mmio + LAS0_CLEAR);
697         readw(dev->mmio + LAS0_CLEAR);
698 
699         comedi_handle_events(dev, s);
700 
701         return IRQ_HANDLED;
702 
703 xfer_abort:
704         s->async->events |= COMEDI_CB_ERROR;
705 
706 xfer_done:
707         s->async->events |= COMEDI_CB_EOA;
708 
709         /* clear the interrupt */
710         status = readw(dev->mmio + LAS0_IT);
711         writew(status, dev->mmio + LAS0_CLEAR);
712         readw(dev->mmio + LAS0_CLEAR);
713 
714         fifo_status = readl(dev->mmio + LAS0_ADC);
715         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
716 
717         comedi_handle_events(dev, s);
718 
719         return IRQ_HANDLED;
720 }
721 
722 /*
723   cmdtest tests a particular command to see if it is valid.
724   Using the cmdtest ioctl, a user can create a valid cmd
725   and then have it executed by the cmd ioctl (asynchronously).
726 
727   cmdtest returns 1,2,3,4 or 0, depending on which tests
728   the command passes.
729 */
730 
731 static int rtd_ai_cmdtest(struct comedi_device *dev,
732                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
733 {
734         int err = 0;
735         unsigned int arg;
736 
737         /* Step 1 : check if triggers are trivially valid */
738 
739         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
740         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
741                                         TRIG_TIMER | TRIG_EXT);
742         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
743         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
744         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
745 
746         if (err)
747                 return 1;
748 
749         /* Step 2a : make sure trigger sources are unique */
750 
751         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
752         err |= cfc_check_trigger_is_unique(cmd->convert_src);
753         err |= cfc_check_trigger_is_unique(cmd->stop_src);
754 
755         /* Step 2b : and mutually compatible */
756 
757         if (err)
758                 return 2;
759 
760         /* Step 3: check if arguments are trivially valid */
761 
762         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
763 
764         if (cmd->scan_begin_src == TRIG_TIMER) {
765                 /* Note: these are time periods, not actual rates */
766                 if (1 == cmd->chanlist_len) {   /* no scanning */
767                         if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
768                                                       RTD_MAX_SPEED_1)) {
769                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
770                                                 CMDF_ROUND_UP);
771                                 err |= -EINVAL;
772                         }
773                         if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
774                                                       RTD_MIN_SPEED_1)) {
775                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
776                                                 CMDF_ROUND_DOWN);
777                                 err |= -EINVAL;
778                         }
779                 } else {
780                         if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
781                                                       RTD_MAX_SPEED)) {
782                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
783                                                 CMDF_ROUND_UP);
784                                 err |= -EINVAL;
785                         }
786                         if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
787                                                       RTD_MIN_SPEED)) {
788                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
789                                                 CMDF_ROUND_DOWN);
790                                 err |= -EINVAL;
791                         }
792                 }
793         } else {
794                 /* external trigger */
795                 /* should be level/edge, hi/lo specification here */
796                 /* should specify multiple external triggers */
797                 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
798         }
799 
800         if (cmd->convert_src == TRIG_TIMER) {
801                 if (1 == cmd->chanlist_len) {   /* no scanning */
802                         if (cfc_check_trigger_arg_min(&cmd->convert_arg,
803                                                       RTD_MAX_SPEED_1)) {
804                                 rtd_ns_to_timer(&cmd->convert_arg,
805                                                 CMDF_ROUND_UP);
806                                 err |= -EINVAL;
807                         }
808                         if (cfc_check_trigger_arg_max(&cmd->convert_arg,
809                                                       RTD_MIN_SPEED_1)) {
810                                 rtd_ns_to_timer(&cmd->convert_arg,
811                                                 CMDF_ROUND_DOWN);
812                                 err |= -EINVAL;
813                         }
814                 } else {
815                         if (cfc_check_trigger_arg_min(&cmd->convert_arg,
816                                                       RTD_MAX_SPEED)) {
817                                 rtd_ns_to_timer(&cmd->convert_arg,
818                                                 CMDF_ROUND_UP);
819                                 err |= -EINVAL;
820                         }
821                         if (cfc_check_trigger_arg_max(&cmd->convert_arg,
822                                                       RTD_MIN_SPEED)) {
823                                 rtd_ns_to_timer(&cmd->convert_arg,
824                                                 CMDF_ROUND_DOWN);
825                                 err |= -EINVAL;
826                         }
827                 }
828         } else {
829                 /* external trigger */
830                 /* see above */
831                 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
832         }
833 
834         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
835 
836         if (cmd->stop_src == TRIG_COUNT)
837                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
838         else    /* TRIG_NONE */
839                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
840 
841         if (err)
842                 return 3;
843 
844 
845         /* step 4: fix up any arguments */
846 
847         if (cmd->scan_begin_src == TRIG_TIMER) {
848                 arg = cmd->scan_begin_arg;
849                 rtd_ns_to_timer(&arg, cmd->flags);
850                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
851         }
852 
853         if (cmd->convert_src == TRIG_TIMER) {
854                 arg = cmd->convert_arg;
855                 rtd_ns_to_timer(&arg, cmd->flags);
856                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
857 
858                 if (cmd->scan_begin_src == TRIG_TIMER) {
859                         arg = cmd->convert_arg * cmd->scan_end_arg;
860                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
861                                                          arg);
862                 }
863         }
864 
865         if (err)
866                 return 4;
867 
868         return 0;
869 }
870 
871 /*
872   Execute a analog in command with many possible triggering options.
873   The data get stored in the async structure of the subdevice.
874   This is usually done by an interrupt handler.
875   Userland gets to the data using read calls.
876 */
877 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
878 {
879         struct rtd_private *devpriv = dev->private;
880         struct comedi_cmd *cmd = &s->async->cmd;
881         int timer;
882 
883         /* stop anything currently running */
884         /* pacer stop source: SOFTWARE */
885         writel(0, dev->mmio + LAS0_PACER_STOP);
886         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
887         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
888         writew(0, dev->mmio + LAS0_IT);
889         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
890         writel(0, dev->mmio + 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, dev->mmio + LAS0_PACER_START);
900                 /* burst trigger source: PACER */
901                 writel(1, dev->mmio + LAS0_BURST_START);
902                 /* ADC conversion trigger source: BURST */
903                 writel(2, dev->mmio + LAS0_ADC_CONVERSION);
904         } else {                /* single channel */
905                 /* pacer start source: SOFTWARE */
906                 writel(0, dev->mmio + LAS0_PACER_START);
907                 /* ADC conversion trigger source: PACER */
908                 writel(1, dev->mmio + LAS0_ADC_CONVERSION);
909         }
910         writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + 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 & CMDF_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->xfer_count = cmd->chanlist_len;
922                         devpriv->flags |= SEND_EOS;
923                 } else {
924                         /* arrange to transfer data periodically */
925                         devpriv->xfer_count =
926                             (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
927                             cmd->scan_begin_arg;
928                         if (devpriv->xfer_count < cmd->chanlist_len) {
929                                 /* transfer after each scan (and avoid 0) */
930                                 devpriv->xfer_count = cmd->chanlist_len;
931                         } else {        /* make a multiple of scan length */
932                                 devpriv->xfer_count =
933                                     (devpriv->xfer_count +
934                                      cmd->chanlist_len - 1)
935                                     / cmd->chanlist_len;
936                                 devpriv->xfer_count *= cmd->chanlist_len;
937                         }
938                         devpriv->flags |= SEND_EOS;
939                 }
940                 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
941                         /* out of counter range, use 1/2 fifo instead */
942                         devpriv->xfer_count = 0;
943                         devpriv->flags &= ~SEND_EOS;
944                 } else {
945                         /* interrupt for each transfer */
946                         writel((devpriv->xfer_count - 1) & 0xffff,
947                                dev->mmio + LAS0_ACNT);
948                 }
949         } else {                /* unknown timing, just use 1/2 FIFO */
950                 devpriv->xfer_count = 0;
951                 devpriv->flags &= ~SEND_EOS;
952         }
953         /* pacer clock source: INTERNAL 8MHz */
954         writel(1, dev->mmio + LAS0_PACER_SELECT);
955         /* just interrupt, don't stop */
956         writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
957 
958         /* BUG??? these look like enumerated values, but they are bit fields */
959 
960         /* First, setup when to stop */
961         switch (cmd->stop_src) {
962         case TRIG_COUNT:        /* stop after N scans */
963                 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
964                 if ((devpriv->xfer_count > 0)
965                     && (devpriv->xfer_count > devpriv->ai_count)) {
966                         devpriv->xfer_count = devpriv->ai_count;
967                 }
968                 break;
969 
970         case TRIG_NONE: /* stop when cancel is called */
971                 devpriv->ai_count = -1; /* read forever */
972                 break;
973         }
974 
975         /* Scan timing */
976         switch (cmd->scan_begin_src) {
977         case TRIG_TIMER:        /* periodic scanning */
978                 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
979                                         CMDF_ROUND_NEAREST);
980                 /* set PACER clock */
981                 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
982 
983                 break;
984 
985         case TRIG_EXT:
986                 /* pacer start source: EXTERNAL */
987                 writel(1, dev->mmio + LAS0_PACER_START);
988                 break;
989         }
990 
991         /* Sample timing within a scan */
992         switch (cmd->convert_src) {
993         case TRIG_TIMER:        /* periodic */
994                 if (cmd->chanlist_len > 1) {
995                         /* only needed for multi-channel */
996                         timer = rtd_ns_to_timer(&cmd->convert_arg,
997                                                 CMDF_ROUND_NEAREST);
998                         /* setup BURST clock */
999                         writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
1000                 }
1001 
1002                 break;
1003 
1004         case TRIG_EXT:          /* external */
1005                 /* burst trigger source: EXTERNAL */
1006                 writel(2, dev->mmio + LAS0_BURST_START);
1007                 break;
1008         }
1009         /* end configuration */
1010 
1011         /* This doesn't seem to work.  There is no way to clear an interrupt
1012            that the priority controller has queued! */
1013         writew(~0, dev->mmio + LAS0_CLEAR);
1014         readw(dev->mmio + LAS0_CLEAR);
1015 
1016         /* TODO: allow multiple interrupt sources */
1017         if (devpriv->xfer_count > 0)    /* transfer every N samples */
1018                 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
1019         else                            /* 1/2 FIFO transfers */
1020                 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
1021 
1022         /* BUG: start_src is ASSUMED to be TRIG_NOW */
1023         /* BUG? it seems like things are running before the "start" */
1024         readl(dev->mmio + LAS0_PACER);  /* start pacer */
1025         return 0;
1026 }
1027 
1028 /*
1029   Stop a running data acquisition.
1030 */
1031 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1032 {
1033         struct rtd_private *devpriv = dev->private;
1034         u32 overrun;
1035         u16 status;
1036 
1037         /* pacer stop source: SOFTWARE */
1038         writel(0, dev->mmio + LAS0_PACER_STOP);
1039         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
1040         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
1041         writew(0, dev->mmio + LAS0_IT);
1042         devpriv->ai_count = 0;  /* stop and don't transfer any more */
1043         status = readw(dev->mmio + LAS0_IT);
1044         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
1045         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1046         return 0;
1047 }
1048 
1049 static int rtd_ao_eoc(struct comedi_device *dev,
1050                       struct comedi_subdevice *s,
1051                       struct comedi_insn *insn,
1052                       unsigned long context)
1053 {
1054         unsigned int chan = CR_CHAN(insn->chanspec);
1055         unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
1056         unsigned int status;
1057 
1058         status = readl(dev->mmio + LAS0_ADC);
1059         if (status & bit)
1060                 return 0;
1061         return -EBUSY;
1062 }
1063 
1064 static int rtd_ao_winsn(struct comedi_device *dev,
1065                         struct comedi_subdevice *s, struct comedi_insn *insn,
1066                         unsigned int *data)
1067 {
1068         struct rtd_private *devpriv = dev->private;
1069         int i;
1070         int chan = CR_CHAN(insn->chanspec);
1071         int range = CR_RANGE(insn->chanspec);
1072         int ret;
1073 
1074         /* Configure the output range (table index matches the range values) */
1075         writew(range & 7,
1076                dev->mmio + ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
1077 
1078         /* Writing a list of values to an AO channel is probably not
1079          * very useful, but that's how the interface is defined. */
1080         for (i = 0; i < insn->n; ++i) {
1081                 int val = data[i] << 3;
1082 
1083                 /* VERIFY: comedi range and offset conversions */
1084 
1085                 if ((range > 1) /* bipolar */
1086                     && (data[i] < 2048)) {
1087                         /* offset and sign extend */
1088                         val = (((int)data[i]) - 2048) << 3;
1089                 } else {        /* unipolor */
1090                         val = data[i] << 3;
1091                 }
1092 
1093                 /* a typical programming sequence */
1094                 writew(val, devpriv->las1 +
1095                         ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
1096                 writew(0, dev->mmio + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
1097 
1098                 s->readback[chan] = data[i];
1099 
1100                 ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
1101                 if (ret)
1102                         return ret;
1103         }
1104 
1105         /* return the number of samples read/written */
1106         return i;
1107 }
1108 
1109 static int rtd_dio_insn_bits(struct comedi_device *dev,
1110                              struct comedi_subdevice *s,
1111                              struct comedi_insn *insn,
1112                              unsigned int *data)
1113 {
1114         if (comedi_dio_update_state(s, data))
1115                 writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
1116 
1117         data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
1118 
1119         return insn->n;
1120 }
1121 
1122 static int rtd_dio_insn_config(struct comedi_device *dev,
1123                                struct comedi_subdevice *s,
1124                                struct comedi_insn *insn,
1125                                unsigned int *data)
1126 {
1127         int ret;
1128 
1129         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1130         if (ret)
1131                 return ret;
1132 
1133         /* TODO support digital match interrupts and strobes */
1134 
1135         /* set direction */
1136         writew(0x01, dev->mmio + LAS0_DIO_STATUS);
1137         writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
1138 
1139         /* clear interrupts */
1140         writew(0x00, dev->mmio + LAS0_DIO_STATUS);
1141 
1142         /* port1 can only be all input or all output */
1143 
1144         /* there are also 2 user input lines and 2 user output lines */
1145 
1146         return insn->n;
1147 }
1148 
1149 static void rtd_reset(struct comedi_device *dev)
1150 {
1151         struct rtd_private *devpriv = dev->private;
1152 
1153         writel(0, dev->mmio + LAS0_BOARD_RESET);
1154         udelay(100);            /* needed? */
1155         writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1156         writew(0, dev->mmio + LAS0_IT);
1157         writew(~0, dev->mmio + LAS0_CLEAR);
1158         readw(dev->mmio + LAS0_CLEAR);
1159 }
1160 
1161 /*
1162  * initialize board, per RTD spec
1163  * also, initialize shadow registers
1164  */
1165 static void rtd_init_board(struct comedi_device *dev)
1166 {
1167         rtd_reset(dev);
1168 
1169         writel(0, dev->mmio + LAS0_OVERRUN);
1170         writel(0, dev->mmio + LAS0_CGT_CLEAR);
1171         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1172         writel(0, dev->mmio + LAS0_DAC1_RESET);
1173         writel(0, dev->mmio + LAS0_DAC2_RESET);
1174         /* clear digital IO fifo */
1175         writew(0, dev->mmio + LAS0_DIO_STATUS);
1176         writeb((0 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1177         writeb((1 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1178         writeb((2 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1179         writeb((3 << 6) | 0x00, dev->mmio + LAS0_UTC_CTRL);
1180         /* TODO: set user out source ??? */
1181 }
1182 
1183 /* The RTD driver does this */
1184 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1185                                   struct pci_dev *pcidev)
1186 {
1187         unsigned char pci_latency;
1188 
1189         pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1190         if (pci_latency < 32) {
1191                 dev_info(dev->class_dev,
1192                         "PCI latency changed from %d to %d\n",
1193                         pci_latency, 32);
1194                 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1195         }
1196 }
1197 
1198 static int rtd_auto_attach(struct comedi_device *dev,
1199                            unsigned long context)
1200 {
1201         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1202         const struct rtd_boardinfo *board = NULL;
1203         struct rtd_private *devpriv;
1204         struct comedi_subdevice *s;
1205         int ret;
1206 
1207         if (context < ARRAY_SIZE(rtd520Boards))
1208                 board = &rtd520Boards[context];
1209         if (!board)
1210                 return -ENODEV;
1211         dev->board_ptr = board;
1212         dev->board_name = board->name;
1213 
1214         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1215         if (!devpriv)
1216                 return -ENOMEM;
1217 
1218         ret = comedi_pci_enable(dev);
1219         if (ret)
1220                 return ret;
1221 
1222         dev->mmio = pci_ioremap_bar(pcidev, 2);
1223         devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1224         devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1225         if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
1226                 return -ENOMEM;
1227 
1228         rtd_pci_latency_quirk(dev, pcidev);
1229 
1230         if (pcidev->irq) {
1231                 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1232                                   dev->board_name, dev);
1233                 if (ret == 0)
1234                         dev->irq = pcidev->irq;
1235         }
1236 
1237         ret = comedi_alloc_subdevices(dev, 4);
1238         if (ret)
1239                 return ret;
1240 
1241         s = &dev->subdevices[0];
1242         /* analog input subdevice */
1243         s->type         = COMEDI_SUBD_AI;
1244         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1245         s->n_chan       = 16;
1246         s->maxdata      = 0x0fff;
1247         s->range_table  = board->ai_range;
1248         s->len_chanlist = RTD_MAX_CHANLIST;
1249         s->insn_read    = rtd_ai_rinsn;
1250         if (dev->irq) {
1251                 dev->read_subdev = s;
1252                 s->subdev_flags |= SDF_CMD_READ;
1253                 s->do_cmd       = rtd_ai_cmd;
1254                 s->do_cmdtest   = rtd_ai_cmdtest;
1255                 s->cancel       = rtd_ai_cancel;
1256         }
1257 
1258         s = &dev->subdevices[1];
1259         /* analog output subdevice */
1260         s->type         = COMEDI_SUBD_AO;
1261         s->subdev_flags = SDF_WRITABLE;
1262         s->n_chan       = 2;
1263         s->maxdata      = 0x0fff;
1264         s->range_table  = &rtd_ao_range;
1265         s->insn_write   = rtd_ao_winsn;
1266 
1267         ret = comedi_alloc_subdev_readback(s);
1268         if (ret)
1269                 return ret;
1270 
1271         s = &dev->subdevices[2];
1272         /* digital i/o subdevice */
1273         s->type         = COMEDI_SUBD_DIO;
1274         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1275         /* we only support port 0 right now.  Ignoring port 1 and user IO */
1276         s->n_chan       = 8;
1277         s->maxdata      = 1;
1278         s->range_table  = &range_digital;
1279         s->insn_bits    = rtd_dio_insn_bits;
1280         s->insn_config  = rtd_dio_insn_config;
1281 
1282         /* timer/counter subdevices (not currently supported) */
1283         s = &dev->subdevices[3];
1284         s->type         = COMEDI_SUBD_COUNTER;
1285         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1286         s->n_chan       = 3;
1287         s->maxdata      = 0xffff;
1288 
1289         rtd_init_board(dev);
1290 
1291         ret = rtd520_probe_fifo_depth(dev);
1292         if (ret < 0)
1293                 return ret;
1294         devpriv->fifosz = ret;
1295 
1296         if (dev->irq)
1297                 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1298 
1299         return 0;
1300 }
1301 
1302 static void rtd_detach(struct comedi_device *dev)
1303 {
1304         struct rtd_private *devpriv = dev->private;
1305 
1306         if (devpriv) {
1307                 /* Shut down any board ops by resetting it */
1308                 if (dev->mmio && devpriv->lcfg)
1309                         rtd_reset(dev);
1310                 if (dev->irq) {
1311                         writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
1312                                 ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
1313                                 devpriv->lcfg + PLX_INTRCS_REG);
1314                         free_irq(dev->irq, dev);
1315                 }
1316                 if (dev->mmio)
1317                         iounmap(dev->mmio);
1318                 if (devpriv->las1)
1319                         iounmap(devpriv->las1);
1320                 if (devpriv->lcfg)
1321                         iounmap(devpriv->lcfg);
1322         }
1323         comedi_pci_disable(dev);
1324 }
1325 
1326 static struct comedi_driver rtd520_driver = {
1327         .driver_name    = "rtd520",
1328         .module         = THIS_MODULE,
1329         .auto_attach    = rtd_auto_attach,
1330         .detach         = rtd_detach,
1331 };
1332 
1333 static int rtd520_pci_probe(struct pci_dev *dev,
1334                             const struct pci_device_id *id)
1335 {
1336         return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1337 }
1338 
1339 static const struct pci_device_id rtd520_pci_table[] = {
1340         { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1341         { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1342         { 0 }
1343 };
1344 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1345 
1346 static struct pci_driver rtd520_pci_driver = {
1347         .name           = "rtd520",
1348         .id_table       = rtd520_pci_table,
1349         .probe          = rtd520_pci_probe,
1350         .remove         = comedi_pci_auto_unconfig,
1351 };
1352 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1353 
1354 MODULE_AUTHOR("Comedi http://www.comedi.org");
1355 MODULE_DESCRIPTION("Comedi low-level driver");
1356 MODULE_LICENSE("GPL");
1357 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us