Version:  2.0.40 2.2.26 2.4.37 3.2 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

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         DECLARE_BITMAP(chan_is_bipolar, RTD_MAX_CHANLIST);
383         unsigned fifosz;
384 };
385 
386 /* bit defines for "flags" */
387 #define SEND_EOS        0x01    /* send End Of Scan events */
388 #define DMA0_ACTIVE     0x02    /* DMA0 is active */
389 #define DMA1_ACTIVE     0x04    /* DMA1 is active */
390 
391 /*
392   Given a desired period and the clock period (both in ns),
393   return the proper counter value (divider-1).
394   Sets the original period to be the true value.
395   Note: you have to check if the value is larger than the counter range!
396 */
397 static int rtd_ns_to_timer_base(unsigned int *nanosec,
398                                 unsigned int flags, int base)
399 {
400         int divider;
401 
402         switch (flags & CMDF_ROUND_MASK) {
403         case CMDF_ROUND_NEAREST:
404         default:
405                 divider = (*nanosec + base / 2) / base;
406                 break;
407         case CMDF_ROUND_DOWN:
408                 divider = (*nanosec) / base;
409                 break;
410         case CMDF_ROUND_UP:
411                 divider = (*nanosec + base - 1) / base;
412                 break;
413         }
414         if (divider < 2)
415                 divider = 2;    /* min is divide by 2 */
416 
417         /* Note: we don't check for max, because different timers
418            have different ranges */
419 
420         *nanosec = base * divider;
421         return divider - 1;     /* countdown is divisor+1 */
422 }
423 
424 /*
425   Given a desired period (in ns),
426   return the proper counter value (divider-1) for the internal clock.
427   Sets the original period to be the true value.
428 */
429 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
430 {
431         return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
432 }
433 
434 /*
435   Convert a single comedi channel-gain entry to a RTD520 table entry
436 */
437 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
438                                             unsigned int chanspec, int index)
439 {
440         const struct rtd_boardinfo *board = dev->board_ptr;
441         struct rtd_private *devpriv = dev->private;
442         unsigned int chan = CR_CHAN(chanspec);
443         unsigned int range = CR_RANGE(chanspec);
444         unsigned int aref = CR_AREF(chanspec);
445         unsigned short r = 0;
446 
447         r |= chan & 0xf;
448 
449         /* Note: we also setup the channel list bipolar flag array */
450         if (range < board->range_bip10) {
451                 /* +-5 range */
452                 r |= 0x000;
453                 r |= (range & 0x7) << 4;
454                 __set_bit(index, devpriv->chan_is_bipolar);
455         } else if (range < board->range_uni10) {
456                 /* +-10 range */
457                 r |= 0x100;
458                 r |= ((range - board->range_bip10) & 0x7) << 4;
459                 __set_bit(index, devpriv->chan_is_bipolar);
460         } else {
461                 /* +10 range */
462                 r |= 0x200;
463                 r |= ((range - board->range_uni10) & 0x7) << 4;
464                 __clear_bit(index, devpriv->chan_is_bipolar);
465         }
466 
467         switch (aref) {
468         case AREF_GROUND:       /* on-board ground */
469                 break;
470 
471         case AREF_COMMON:
472                 r |= 0x80;      /* ref external analog common */
473                 break;
474 
475         case AREF_DIFF:
476                 r |= 0x400;     /* differential inputs */
477                 break;
478 
479         case AREF_OTHER:        /* ??? */
480                 break;
481         }
482         return r;
483 }
484 
485 /*
486   Setup the channel-gain table from a comedi list
487 */
488 static void rtd_load_channelgain_list(struct comedi_device *dev,
489                                       unsigned int n_chan, unsigned int *list)
490 {
491         if (n_chan > 1) {       /* setup channel gain table */
492                 int ii;
493 
494                 writel(0, dev->mmio + LAS0_CGT_CLEAR);
495                 writel(1, dev->mmio + LAS0_CGT_ENABLE);
496                 for (ii = 0; ii < n_chan; ii++) {
497                         writel(rtd_convert_chan_gain(dev, list[ii], ii),
498                                dev->mmio + LAS0_CGT_WRITE);
499                 }
500         } else {                /* just use the channel gain latch */
501                 writel(0, dev->mmio + LAS0_CGT_ENABLE);
502                 writel(rtd_convert_chan_gain(dev, list[0], 0),
503                        dev->mmio + LAS0_CGL_WRITE);
504         }
505 }
506 
507 /* determine fifo size by doing adc conversions until the fifo half
508 empty status flag clears */
509 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
510 {
511         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
512         unsigned i;
513         static const unsigned limit = 0x2000;
514         unsigned fifo_size = 0;
515 
516         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
517         rtd_load_channelgain_list(dev, 1, &chanspec);
518         /* ADC conversion trigger source: SOFTWARE */
519         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
520         /* convert  samples */
521         for (i = 0; i < limit; ++i) {
522                 unsigned fifo_status;
523                 /* trigger conversion */
524                 writew(0, dev->mmio + LAS0_ADC);
525                 udelay(1);
526                 fifo_status = readl(dev->mmio + LAS0_ADC);
527                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
528                         fifo_size = 2 * i;
529                         break;
530                 }
531         }
532         if (i == limit) {
533                 dev_info(dev->class_dev, "failed to probe fifo size.\n");
534                 return -EIO;
535         }
536         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
537         if (fifo_size != 0x400 && fifo_size != 0x2000) {
538                 dev_info(dev->class_dev,
539                          "unexpected fifo size of %i, expected 1024 or 8192.\n",
540                          fifo_size);
541                 return -EIO;
542         }
543         return fifo_size;
544 }
545 
546 static int rtd_ai_eoc(struct comedi_device *dev,
547                       struct comedi_subdevice *s,
548                       struct comedi_insn *insn,
549                       unsigned long context)
550 {
551         unsigned int status;
552 
553         status = readl(dev->mmio + LAS0_ADC);
554         if (status & FS_ADC_NOT_EMPTY)
555                 return 0;
556         return -EBUSY;
557 }
558 
559 static int rtd_ai_rinsn(struct comedi_device *dev,
560                         struct comedi_subdevice *s, struct comedi_insn *insn,
561                         unsigned int *data)
562 {
563         struct rtd_private *devpriv = dev->private;
564         int ret;
565         int n;
566 
567         /* clear any old fifo data */
568         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
569 
570         /* write channel to multiplexer and clear channel gain table */
571         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
572 
573         /* ADC conversion trigger source: SOFTWARE */
574         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
575 
576         /* convert n samples */
577         for (n = 0; n < insn->n; n++) {
578                 unsigned short d;
579                 /* trigger conversion */
580                 writew(0, dev->mmio + LAS0_ADC);
581 
582                 ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
583                 if (ret)
584                         return ret;
585 
586                 /* read data */
587                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
588                 d = d >> 3;     /* low 3 bits are marker lines */
589                 if (test_bit(0, devpriv->chan_is_bipolar))
590                         /* convert to comedi unsigned data */
591                         d = comedi_offset_munge(s, d);
592                 data[n] = d & s->maxdata;
593         }
594 
595         /* return the number of samples read/written */
596         return n;
597 }
598 
599 /*
600   Get what we know is there.... Fast!
601   This uses 1/2 the bus cycles of read_dregs (below).
602 
603   The manual claims that we can do a lword read, but it doesn't work here.
604 */
605 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
606                      int count)
607 {
608         struct rtd_private *devpriv = dev->private;
609         int ii;
610 
611         for (ii = 0; ii < count; ii++) {
612                 unsigned short d;
613 
614                 if (0 == devpriv->ai_count) {   /* done */
615                         d = readw(devpriv->las1 + LAS1_ADC_FIFO);
616                         continue;
617                 }
618 
619                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
620                 d = d >> 3;     /* low 3 bits are marker lines */
621                 if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar))
622                         /* convert to comedi unsigned data */
623                         d = comedi_offset_munge(s, d);
624                 d &= s->maxdata;
625 
626                 if (!comedi_buf_put(s, d))
627                         return -1;
628 
629                 if (devpriv->ai_count > 0)      /* < 0, means read forever */
630                         devpriv->ai_count--;
631         }
632         return 0;
633 }
634 
635 /*
636   unknown amout of data is waiting in fifo.
637 */
638 static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
639 {
640         struct rtd_private *devpriv = dev->private;
641 
642         while (readl(dev->mmio + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
643                 unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO);
644 
645                 if (0 == devpriv->ai_count) {   /* done */
646                         continue;       /* read rest */
647                 }
648 
649                 d = d >> 3;     /* low 3 bits are marker lines */
650                 if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar))
651                         /* convert to comedi unsigned data */
652                         d = comedi_offset_munge(s, d);
653                 d &= s->maxdata;
654 
655                 if (!comedi_buf_put(s, d))
656                         return -1;
657 
658                 if (devpriv->ai_count > 0)      /* < 0, means read forever */
659                         devpriv->ai_count--;
660         }
661         return 0;
662 }
663 
664 /*
665   Handle all rtd520 interrupts.
666   Runs atomically and is never re-entered.
667   This is a "slow handler";  other interrupts may be active.
668   The data conversion may someday happen in a "bottom half".
669 */
670 static irqreturn_t rtd_interrupt(int irq, void *d)
671 {
672         struct comedi_device *dev = d;
673         struct comedi_subdevice *s = dev->read_subdev;
674         struct rtd_private *devpriv = dev->private;
675         u32 overrun;
676         u16 status;
677         u16 fifo_status;
678 
679         if (!dev->attached)
680                 return IRQ_NONE;
681 
682         fifo_status = readl(dev->mmio + LAS0_ADC);
683         /* check for FIFO full, this automatically halts the ADC! */
684         if (!(fifo_status & FS_ADC_NOT_FULL))   /* 0 -> full */
685                 goto xfer_abort;
686 
687         status = readw(dev->mmio + LAS0_IT);
688         /* if interrupt was not caused by our board, or handled above */
689         if (0 == status)
690                 return IRQ_HANDLED;
691 
692         if (status & IRQM_ADC_ABOUT_CNT) {      /* sample count -> read FIFO */
693                 /*
694                  * since the priority interrupt controller may have queued
695                  * a sample counter interrupt, even though we have already
696                  * finished, we must handle the possibility that there is
697                  * no data here
698                  */
699                 if (!(fifo_status & FS_ADC_HEMPTY)) {
700                         /* FIFO half full */
701                         if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
702                                 goto xfer_abort;
703 
704                         if (0 == devpriv->ai_count)
705                                 goto xfer_done;
706 
707                         comedi_event(dev, s);
708                 } else if (devpriv->xfer_count > 0) {
709                         if (fifo_status & FS_ADC_NOT_EMPTY) {
710                                 /* FIFO not empty */
711                                 if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
712                                         goto xfer_abort;
713 
714                                 if (0 == devpriv->ai_count)
715                                         goto xfer_done;
716 
717                                 comedi_event(dev, s);
718                         }
719                 }
720         }
721 
722         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
723         if (overrun)
724                 goto xfer_abort;
725 
726         /* clear the interrupt */
727         writew(status, dev->mmio + LAS0_CLEAR);
728         readw(dev->mmio + LAS0_CLEAR);
729         return IRQ_HANDLED;
730 
731 xfer_abort:
732         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
733         s->async->events |= COMEDI_CB_ERROR;
734         devpriv->ai_count = 0;  /* stop and don't transfer any more */
735         /* fall into xfer_done */
736 
737 xfer_done:
738         /* pacer stop source: SOFTWARE */
739         writel(0, dev->mmio + LAS0_PACER_STOP);
740         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
741         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
742         writew(0, dev->mmio + LAS0_IT);
743 
744         if (devpriv->ai_count > 0) {    /* there shouldn't be anything left */
745                 fifo_status = readl(dev->mmio + LAS0_ADC);
746                 ai_read_dregs(dev, s);  /* read anything left in FIFO */
747         }
748 
749         s->async->events |= COMEDI_CB_EOA;      /* signal end to comedi */
750         comedi_event(dev, s);
751 
752         /* clear the interrupt */
753         status = readw(dev->mmio + LAS0_IT);
754         writew(status, dev->mmio + LAS0_CLEAR);
755         readw(dev->mmio + LAS0_CLEAR);
756 
757         fifo_status = readl(dev->mmio + LAS0_ADC);
758         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
759 
760         return IRQ_HANDLED;
761 }
762 
763 /*
764   cmdtest tests a particular command to see if it is valid.
765   Using the cmdtest ioctl, a user can create a valid cmd
766   and then have it executed by the cmd ioctl (asynchronously).
767 
768   cmdtest returns 1,2,3,4 or 0, depending on which tests
769   the command passes.
770 */
771 
772 static int rtd_ai_cmdtest(struct comedi_device *dev,
773                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
774 {
775         int err = 0;
776         unsigned int arg;
777 
778         /* Step 1 : check if triggers are trivially valid */
779 
780         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
781         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
782                                         TRIG_TIMER | TRIG_EXT);
783         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
784         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
785         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
786 
787         if (err)
788                 return 1;
789 
790         /* Step 2a : make sure trigger sources are unique */
791 
792         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
793         err |= cfc_check_trigger_is_unique(cmd->convert_src);
794         err |= cfc_check_trigger_is_unique(cmd->stop_src);
795 
796         /* Step 2b : and mutually compatible */
797 
798         if (err)
799                 return 2;
800 
801         /* Step 3: check if arguments are trivially valid */
802 
803         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
804 
805         if (cmd->scan_begin_src == TRIG_TIMER) {
806                 /* Note: these are time periods, not actual rates */
807                 if (1 == cmd->chanlist_len) {   /* no scanning */
808                         if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
809                                                       RTD_MAX_SPEED_1)) {
810                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
811                                                 CMDF_ROUND_UP);
812                                 err |= -EINVAL;
813                         }
814                         if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
815                                                       RTD_MIN_SPEED_1)) {
816                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
817                                                 CMDF_ROUND_DOWN);
818                                 err |= -EINVAL;
819                         }
820                 } else {
821                         if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
822                                                       RTD_MAX_SPEED)) {
823                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
824                                                 CMDF_ROUND_UP);
825                                 err |= -EINVAL;
826                         }
827                         if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
828                                                       RTD_MIN_SPEED)) {
829                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
830                                                 CMDF_ROUND_DOWN);
831                                 err |= -EINVAL;
832                         }
833                 }
834         } else {
835                 /* external trigger */
836                 /* should be level/edge, hi/lo specification here */
837                 /* should specify multiple external triggers */
838                 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
839         }
840 
841         if (cmd->convert_src == TRIG_TIMER) {
842                 if (1 == cmd->chanlist_len) {   /* no scanning */
843                         if (cfc_check_trigger_arg_min(&cmd->convert_arg,
844                                                       RTD_MAX_SPEED_1)) {
845                                 rtd_ns_to_timer(&cmd->convert_arg,
846                                                 CMDF_ROUND_UP);
847                                 err |= -EINVAL;
848                         }
849                         if (cfc_check_trigger_arg_max(&cmd->convert_arg,
850                                                       RTD_MIN_SPEED_1)) {
851                                 rtd_ns_to_timer(&cmd->convert_arg,
852                                                 CMDF_ROUND_DOWN);
853                                 err |= -EINVAL;
854                         }
855                 } else {
856                         if (cfc_check_trigger_arg_min(&cmd->convert_arg,
857                                                       RTD_MAX_SPEED)) {
858                                 rtd_ns_to_timer(&cmd->convert_arg,
859                                                 CMDF_ROUND_UP);
860                                 err |= -EINVAL;
861                         }
862                         if (cfc_check_trigger_arg_max(&cmd->convert_arg,
863                                                       RTD_MIN_SPEED)) {
864                                 rtd_ns_to_timer(&cmd->convert_arg,
865                                                 CMDF_ROUND_DOWN);
866                                 err |= -EINVAL;
867                         }
868                 }
869         } else {
870                 /* external trigger */
871                 /* see above */
872                 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
873         }
874 
875         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
876 
877         if (cmd->stop_src == TRIG_COUNT)
878                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
879         else    /* TRIG_NONE */
880                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
881 
882         if (err)
883                 return 3;
884 
885 
886         /* step 4: fix up any arguments */
887 
888         if (cmd->scan_begin_src == TRIG_TIMER) {
889                 arg = cmd->scan_begin_arg;
890                 rtd_ns_to_timer(&arg, cmd->flags);
891                 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
892         }
893 
894         if (cmd->convert_src == TRIG_TIMER) {
895                 arg = cmd->convert_arg;
896                 rtd_ns_to_timer(&arg, cmd->flags);
897                 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
898 
899                 if (cmd->scan_begin_src == TRIG_TIMER) {
900                         arg = cmd->convert_arg * cmd->scan_end_arg;
901                         err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
902                                                          arg);
903                 }
904         }
905 
906         if (err)
907                 return 4;
908 
909         return 0;
910 }
911 
912 /*
913   Execute a analog in command with many possible triggering options.
914   The data get stored in the async structure of the subdevice.
915   This is usually done by an interrupt handler.
916   Userland gets to the data using read calls.
917 */
918 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
919 {
920         struct rtd_private *devpriv = dev->private;
921         struct comedi_cmd *cmd = &s->async->cmd;
922         int timer;
923 
924         /* stop anything currently running */
925         /* pacer stop source: SOFTWARE */
926         writel(0, dev->mmio + LAS0_PACER_STOP);
927         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
928         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
929         writew(0, dev->mmio + LAS0_IT);
930         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
931         writel(0, dev->mmio + LAS0_OVERRUN);
932 
933         /* start configuration */
934         /* load channel list and reset CGT */
935         rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
936 
937         /* setup the common case and override if needed */
938         if (cmd->chanlist_len > 1) {
939                 /* pacer start source: SOFTWARE */
940                 writel(0, dev->mmio + LAS0_PACER_START);
941                 /* burst trigger source: PACER */
942                 writel(1, dev->mmio + LAS0_BURST_START);
943                 /* ADC conversion trigger source: BURST */
944                 writel(2, dev->mmio + LAS0_ADC_CONVERSION);
945         } else {                /* single channel */
946                 /* pacer start source: SOFTWARE */
947                 writel(0, dev->mmio + LAS0_PACER_START);
948                 /* ADC conversion trigger source: PACER */
949                 writel(1, dev->mmio + LAS0_ADC_CONVERSION);
950         }
951         writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
952 
953         if (TRIG_TIMER == cmd->scan_begin_src) {
954                 /* scan_begin_arg is in nanoseconds */
955                 /* find out how many samples to wait before transferring */
956                 if (cmd->flags & CMDF_WAKE_EOS) {
957                         /*
958                          * this may generate un-sustainable interrupt rates
959                          * the application is responsible for doing the
960                          * right thing
961                          */
962                         devpriv->xfer_count = cmd->chanlist_len;
963                         devpriv->flags |= SEND_EOS;
964                 } else {
965                         /* arrange to transfer data periodically */
966                         devpriv->xfer_count =
967                             (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
968                             cmd->scan_begin_arg;
969                         if (devpriv->xfer_count < cmd->chanlist_len) {
970                                 /* transfer after each scan (and avoid 0) */
971                                 devpriv->xfer_count = cmd->chanlist_len;
972                         } else {        /* make a multiple of scan length */
973                                 devpriv->xfer_count =
974                                     (devpriv->xfer_count +
975                                      cmd->chanlist_len - 1)
976                                     / cmd->chanlist_len;
977                                 devpriv->xfer_count *= cmd->chanlist_len;
978                         }
979                         devpriv->flags |= SEND_EOS;
980                 }
981                 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
982                         /* out of counter range, use 1/2 fifo instead */
983                         devpriv->xfer_count = 0;
984                         devpriv->flags &= ~SEND_EOS;
985                 } else {
986                         /* interrupt for each transfer */
987                         writel((devpriv->xfer_count - 1) & 0xffff,
988                                dev->mmio + LAS0_ACNT);
989                 }
990         } else {                /* unknown timing, just use 1/2 FIFO */
991                 devpriv->xfer_count = 0;
992                 devpriv->flags &= ~SEND_EOS;
993         }
994         /* pacer clock source: INTERNAL 8MHz */
995         writel(1, dev->mmio + LAS0_PACER_SELECT);
996         /* just interrupt, don't stop */
997         writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
998 
999         /* BUG??? these look like enumerated values, but they are bit fields */
1000 
1001         /* First, setup when to stop */
1002         switch (cmd->stop_src) {
1003         case TRIG_COUNT:        /* stop after N scans */
1004                 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
1005                 if ((devpriv->xfer_count > 0)
1006                     && (devpriv->xfer_count > devpriv->ai_count)) {
1007                         devpriv->xfer_count = devpriv->ai_count;
1008                 }
1009                 break;
1010 
1011         case TRIG_NONE: /* stop when cancel is called */
1012                 devpriv->ai_count = -1; /* read forever */
1013                 break;
1014         }
1015 
1016         /* Scan timing */
1017         switch (cmd->scan_begin_src) {
1018         case TRIG_TIMER:        /* periodic scanning */
1019                 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
1020                                         CMDF_ROUND_NEAREST);
1021                 /* set PACER clock */
1022                 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
1023 
1024                 break;
1025 
1026         case TRIG_EXT:
1027                 /* pacer start source: EXTERNAL */
1028                 writel(1, dev->mmio + LAS0_PACER_START);
1029                 break;
1030         }
1031 
1032         /* Sample timing within a scan */
1033         switch (cmd->convert_src) {
1034         case TRIG_TIMER:        /* periodic */
1035                 if (cmd->chanlist_len > 1) {
1036                         /* only needed for multi-channel */
1037                         timer = rtd_ns_to_timer(&cmd->convert_arg,
1038                                                 CMDF_ROUND_NEAREST);
1039                         /* setup BURST clock */
1040                         writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
1041                 }
1042 
1043                 break;
1044 
1045         case TRIG_EXT:          /* external */
1046                 /* burst trigger source: EXTERNAL */
1047                 writel(2, dev->mmio + LAS0_BURST_START);
1048                 break;
1049         }
1050         /* end configuration */
1051 
1052         /* This doesn't seem to work.  There is no way to clear an interrupt
1053            that the priority controller has queued! */
1054         writew(~0, dev->mmio + LAS0_CLEAR);
1055         readw(dev->mmio + LAS0_CLEAR);
1056 
1057         /* TODO: allow multiple interrupt sources */
1058         if (devpriv->xfer_count > 0)    /* transfer every N samples */
1059                 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
1060         else                            /* 1/2 FIFO transfers */
1061                 writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
1062 
1063         /* BUG: start_src is ASSUMED to be TRIG_NOW */
1064         /* BUG? it seems like things are running before the "start" */
1065         readl(dev->mmio + LAS0_PACER);  /* start pacer */
1066         return 0;
1067 }
1068 
1069 /*
1070   Stop a running data acquisition.
1071 */
1072 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1073 {
1074         struct rtd_private *devpriv = dev->private;
1075         u32 overrun;
1076         u16 status;
1077 
1078         /* pacer stop source: SOFTWARE */
1079         writel(0, dev->mmio + LAS0_PACER_STOP);
1080         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
1081         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
1082         writew(0, dev->mmio + LAS0_IT);
1083         devpriv->ai_count = 0;  /* stop and don't transfer any more */
1084         status = readw(dev->mmio + LAS0_IT);
1085         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
1086         return 0;
1087 }
1088 
1089 static int rtd_ao_eoc(struct comedi_device *dev,
1090                       struct comedi_subdevice *s,
1091                       struct comedi_insn *insn,
1092                       unsigned long context)
1093 {
1094         unsigned int chan = CR_CHAN(insn->chanspec);
1095         unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
1096         unsigned int status;
1097 
1098         status = readl(dev->mmio + LAS0_ADC);
1099         if (status & bit)
1100                 return 0;
1101         return -EBUSY;
1102 }
1103 
1104 static int rtd_ao_winsn(struct comedi_device *dev,
1105                         struct comedi_subdevice *s, struct comedi_insn *insn,
1106                         unsigned int *data)
1107 {
1108         struct rtd_private *devpriv = dev->private;
1109         int i;
1110         int chan = CR_CHAN(insn->chanspec);
1111         int range = CR_RANGE(insn->chanspec);
1112         int ret;
1113 
1114         /* Configure the output range (table index matches the range values) */
1115         writew(range & 7,
1116                dev->mmio + ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
1117 
1118         /* Writing a list of values to an AO channel is probably not
1119          * very useful, but that's how the interface is defined. */
1120         for (i = 0; i < insn->n; ++i) {
1121                 int val = data[i] << 3;
1122 
1123                 /* VERIFY: comedi range and offset conversions */
1124 
1125                 if ((range > 1) /* bipolar */
1126                     && (data[i] < 2048)) {
1127                         /* offset and sign extend */
1128                         val = (((int)data[i]) - 2048) << 3;
1129                 } else {        /* unipolor */
1130                         val = data[i] << 3;
1131                 }
1132 
1133                 /* a typical programming sequence */
1134                 writew(val, devpriv->las1 +
1135                         ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
1136                 writew(0, dev->mmio + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
1137 
1138                 s->readback[chan] = data[i];
1139 
1140                 ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
1141                 if (ret)
1142                         return ret;
1143         }
1144 
1145         /* return the number of samples read/written */
1146         return i;
1147 }
1148 
1149 static int rtd_dio_insn_bits(struct comedi_device *dev,
1150                              struct comedi_subdevice *s,
1151                              struct comedi_insn *insn,
1152                              unsigned int *data)
1153 {
1154         if (comedi_dio_update_state(s, data))
1155                 writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
1156 
1157         data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
1158 
1159         return insn->n;
1160 }
1161 
1162 static int rtd_dio_insn_config(struct comedi_device *dev,
1163                                struct comedi_subdevice *s,
1164                                struct comedi_insn *insn,
1165                                unsigned int *data)
1166 {
1167         int ret;
1168 
1169         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1170         if (ret)
1171                 return ret;
1172 
1173         /* TODO support digital match interrupts and strobes */
1174 
1175         /* set direction */
1176         writew(0x01, dev->mmio + LAS0_DIO_STATUS);
1177         writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
1178 
1179         /* clear interrupts */
1180         writew(0x00, dev->mmio + LAS0_DIO_STATUS);
1181 
1182         /* port1 can only be all input or all output */
1183 
1184         /* there are also 2 user input lines and 2 user output lines */
1185 
1186         return insn->n;
1187 }
1188 
1189 static void rtd_reset(struct comedi_device *dev)
1190 {
1191         struct rtd_private *devpriv = dev->private;
1192 
1193         writel(0, dev->mmio + LAS0_BOARD_RESET);
1194         udelay(100);            /* needed? */
1195         writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1196         writew(0, dev->mmio + LAS0_IT);
1197         writew(~0, dev->mmio + LAS0_CLEAR);
1198         readw(dev->mmio + LAS0_CLEAR);
1199 }
1200 
1201 /*
1202  * initialize board, per RTD spec
1203  * also, initialize shadow registers
1204  */
1205 static void rtd_init_board(struct comedi_device *dev)
1206 {
1207         rtd_reset(dev);
1208 
1209         writel(0, dev->mmio + LAS0_OVERRUN);
1210         writel(0, dev->mmio + LAS0_CGT_CLEAR);
1211         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1212         writel(0, dev->mmio + LAS0_DAC1_RESET);
1213         writel(0, dev->mmio + LAS0_DAC2_RESET);
1214         /* clear digital IO fifo */
1215         writew(0, dev->mmio + LAS0_DIO_STATUS);
1216         writeb((0 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1217         writeb((1 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1218         writeb((2 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1219         writeb((3 << 6) | 0x00, dev->mmio + LAS0_UTC_CTRL);
1220         /* TODO: set user out source ??? */
1221 }
1222 
1223 /* The RTD driver does this */
1224 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1225                                   struct pci_dev *pcidev)
1226 {
1227         unsigned char pci_latency;
1228 
1229         pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1230         if (pci_latency < 32) {
1231                 dev_info(dev->class_dev,
1232                         "PCI latency changed from %d to %d\n",
1233                         pci_latency, 32);
1234                 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1235         }
1236 }
1237 
1238 static int rtd_auto_attach(struct comedi_device *dev,
1239                            unsigned long context)
1240 {
1241         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1242         const struct rtd_boardinfo *board = NULL;
1243         struct rtd_private *devpriv;
1244         struct comedi_subdevice *s;
1245         int ret;
1246 
1247         if (context < ARRAY_SIZE(rtd520Boards))
1248                 board = &rtd520Boards[context];
1249         if (!board)
1250                 return -ENODEV;
1251         dev->board_ptr = board;
1252         dev->board_name = board->name;
1253 
1254         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1255         if (!devpriv)
1256                 return -ENOMEM;
1257 
1258         ret = comedi_pci_enable(dev);
1259         if (ret)
1260                 return ret;
1261 
1262         dev->mmio = pci_ioremap_bar(pcidev, 2);
1263         devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1264         devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1265         if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
1266                 return -ENOMEM;
1267 
1268         rtd_pci_latency_quirk(dev, pcidev);
1269 
1270         if (pcidev->irq) {
1271                 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1272                                   dev->board_name, dev);
1273                 if (ret == 0)
1274                         dev->irq = pcidev->irq;
1275         }
1276 
1277         ret = comedi_alloc_subdevices(dev, 4);
1278         if (ret)
1279                 return ret;
1280 
1281         s = &dev->subdevices[0];
1282         /* analog input subdevice */
1283         s->type         = COMEDI_SUBD_AI;
1284         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1285         s->n_chan       = 16;
1286         s->maxdata      = 0x0fff;
1287         s->range_table  = board->ai_range;
1288         s->len_chanlist = RTD_MAX_CHANLIST;
1289         s->insn_read    = rtd_ai_rinsn;
1290         if (dev->irq) {
1291                 dev->read_subdev = s;
1292                 s->subdev_flags |= SDF_CMD_READ;
1293                 s->do_cmd       = rtd_ai_cmd;
1294                 s->do_cmdtest   = rtd_ai_cmdtest;
1295                 s->cancel       = rtd_ai_cancel;
1296         }
1297 
1298         s = &dev->subdevices[1];
1299         /* analog output subdevice */
1300         s->type         = COMEDI_SUBD_AO;
1301         s->subdev_flags = SDF_WRITABLE;
1302         s->n_chan       = 2;
1303         s->maxdata      = 0x0fff;
1304         s->range_table  = &rtd_ao_range;
1305         s->insn_write   = rtd_ao_winsn;
1306         s->insn_read    = comedi_readback_insn_read;
1307 
1308         ret = comedi_alloc_subdev_readback(s);
1309         if (ret)
1310                 return ret;
1311 
1312         s = &dev->subdevices[2];
1313         /* digital i/o subdevice */
1314         s->type         = COMEDI_SUBD_DIO;
1315         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1316         /* we only support port 0 right now.  Ignoring port 1 and user IO */
1317         s->n_chan       = 8;
1318         s->maxdata      = 1;
1319         s->range_table  = &range_digital;
1320         s->insn_bits    = rtd_dio_insn_bits;
1321         s->insn_config  = rtd_dio_insn_config;
1322 
1323         /* timer/counter subdevices (not currently supported) */
1324         s = &dev->subdevices[3];
1325         s->type         = COMEDI_SUBD_COUNTER;
1326         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1327         s->n_chan       = 3;
1328         s->maxdata      = 0xffff;
1329 
1330         rtd_init_board(dev);
1331 
1332         ret = rtd520_probe_fifo_depth(dev);
1333         if (ret < 0)
1334                 return ret;
1335         devpriv->fifosz = ret;
1336 
1337         if (dev->irq)
1338                 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1339 
1340         return 0;
1341 }
1342 
1343 static void rtd_detach(struct comedi_device *dev)
1344 {
1345         struct rtd_private *devpriv = dev->private;
1346 
1347         if (devpriv) {
1348                 /* Shut down any board ops by resetting it */
1349                 if (dev->mmio && devpriv->lcfg)
1350                         rtd_reset(dev);
1351                 if (dev->irq) {
1352                         writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
1353                                 ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
1354                                 devpriv->lcfg + PLX_INTRCS_REG);
1355                         free_irq(dev->irq, dev);
1356                 }
1357                 if (dev->mmio)
1358                         iounmap(dev->mmio);
1359                 if (devpriv->las1)
1360                         iounmap(devpriv->las1);
1361                 if (devpriv->lcfg)
1362                         iounmap(devpriv->lcfg);
1363         }
1364         comedi_pci_disable(dev);
1365 }
1366 
1367 static struct comedi_driver rtd520_driver = {
1368         .driver_name    = "rtd520",
1369         .module         = THIS_MODULE,
1370         .auto_attach    = rtd_auto_attach,
1371         .detach         = rtd_detach,
1372 };
1373 
1374 static int rtd520_pci_probe(struct pci_dev *dev,
1375                             const struct pci_device_id *id)
1376 {
1377         return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1378 }
1379 
1380 static const struct pci_device_id rtd520_pci_table[] = {
1381         { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1382         { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1383         { 0 }
1384 };
1385 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1386 
1387 static struct pci_driver rtd520_pci_driver = {
1388         .name           = "rtd520",
1389         .id_table       = rtd520_pci_table,
1390         .probe          = rtd520_pci_probe,
1391         .remove         = comedi_pci_auto_unconfig,
1392 };
1393 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1394 
1395 MODULE_AUTHOR("Comedi http://www.comedi.org");
1396 MODULE_DESCRIPTION("Comedi low-level driver");
1397 MODULE_LICENSE("GPL");
1398 

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