Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
[linux-2.6.git] / drivers / staging / comedi / drivers / rtd520.c
blob9b93a1fc4a599856e9957ee3fd3727d90b9da7dd
1 /*
2 * comedi/drivers/rtd520.c
3 * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
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.
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.
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.
29 * Configuration options: not applicable, uses PCI auto config
33 * Created by Dan Christian, NASA Ames Research Center.
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
49 * The DM7520 has slightly fewer features (fewer gain steps).
51 * These boards can support external multiplexors and multi-board
52 * synchronization, but this driver doesn't support that.
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
60 * Notes:
61 * This board is memory mapped. There is some IO stuff, but it isn't needed.
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).
68 * This board is somewhat related to the RTD PCI4400 board.
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.
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.
78 * There was some timer/counter code, but it didn't follow the right API.
82 * driver status:
84 * Analog-In supports instruction and command mode.
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.
92 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
93 * (with a 256K read buffer).
95 * Digital-IO and Analog-Out only support instruction mode.
98 #include <linux/pci.h>
99 #include <linux/delay.h>
100 #include <linux/interrupt.h>
102 #include "../comedidev.h"
104 #include "comedi_fc.h"
105 #include "plx9080.h"
108 * Local Address Space 0 Offsets
110 #define LAS0_USER_IO 0x0008 /* User I/O */
111 #define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */
112 #define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */
113 #define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */
114 #define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */
115 #define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */
116 #define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */
117 #define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */
118 #define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */
119 #define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */
120 #define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */
121 #define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */
122 #define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */
123 #define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */
124 #define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */
125 #define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */
126 #define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */
127 #define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */
128 #define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */
129 #define LAS0_IT 0x0030 /* Interrupt Status/Enable */
130 #define IRQM_ADC_FIFO_WRITE (1 << 0) /* ADC FIFO Write */
131 #define IRQM_CGT_RESET (1 << 1) /* Reset CGT */
132 #define IRQM_CGT_PAUSE (1 << 3) /* Pause CGT */
133 #define IRQM_ADC_ABOUT_CNT (1 << 4) /* About Counter out */
134 #define IRQM_ADC_DELAY_CNT (1 << 5) /* Delay Counter out */
135 #define IRQM_ADC_SAMPLE_CNT (1 << 6) /* ADC Sample Counter */
136 #define IRQM_DAC1_UCNT (1 << 7) /* DAC1 Update Counter */
137 #define IRQM_DAC2_UCNT (1 << 8) /* DAC2 Update Counter */
138 #define IRQM_UTC1 (1 << 9) /* User TC1 out */
139 #define IRQM_UTC1_INV (1 << 10) /* User TC1 out, inverted */
140 #define IRQM_UTC2 (1 << 11) /* User TC2 out */
141 #define IRQM_DIGITAL_IT (1 << 12) /* Digital Interrupt */
142 #define IRQM_EXTERNAL_IT (1 << 13) /* External Interrupt */
143 #define IRQM_ETRIG_RISING (1 << 14) /* Ext Trigger rising-edge */
144 #define IRQM_ETRIG_FALLING (1 << 15) /* Ext Trigger falling-edge */
145 #define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */
146 #define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */
147 #define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */
148 #define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */
149 #define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */
150 #define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */
151 #define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */
152 #define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */
153 #define LAS0_ACNT 0x0058 /* About counter (16 bit) */
154 #define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */
155 #define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */
156 #define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */
157 #define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */
158 #define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */
159 #define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */
160 #define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */
161 #define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */
162 #define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */
163 #define LAS0_BOARD_RESET 0x0100 /* Board reset */
164 #define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
165 #define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
166 #define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */
167 #define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
168 #define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
169 #define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
170 #define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */
171 #define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
172 #define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */
173 #define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
174 #define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */
175 #define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
176 #define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
177 #define LAS0_CG_DATA 0x0138 /* Digital Table Write */
178 #define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */
179 #define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
180 #define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
181 #define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
182 #define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */
183 #define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
184 #define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
185 #define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
186 #define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */
187 #define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
188 #define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
189 #define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
190 #define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */
191 #define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
192 #define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
193 #define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
194 #define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
195 #define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
196 #define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
197 #define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */
198 #define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
199 #define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
200 #define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */
201 #define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */
202 #define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */
203 #define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */
204 #define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */
205 #define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */
206 #define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */
207 #define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */
208 #define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */
209 #define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */
210 #define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */
211 #define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */
212 #define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */
215 * Local Address Space 1 Offsets
217 #define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */
218 #define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */
219 #define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */
220 #define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */
222 /*======================================================================
223 Driver specific stuff (tunable)
224 ======================================================================*/
226 /* We really only need 2 buffers. More than that means being much
227 smarter about knowing which ones are full. */
228 #define DMA_CHAIN_COUNT 2 /* max DMA segments/buffers in a ring (min 2) */
230 /* Target period for periodic transfers. This sets the user read latency. */
231 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
232 /* If this is too low, efficiency is poor */
233 #define TRANS_TARGET_PERIOD 10000000 /* 10 ms (in nanoseconds) */
235 /* Set a practical limit on how long a list to support (affects memory use) */
236 /* The board support a channel list up to the FIFO length (1K or 8K) */
237 #define RTD_MAX_CHANLIST 128 /* max channel list that we allow */
239 /* tuning for ai/ao instruction done polling */
240 #ifdef FAST_SPIN
241 #define WAIT_QUIETLY /* as nothing, spin on done bit */
242 #define RTD_ADC_TIMEOUT 66000 /* 2 msec at 33mhz bus rate */
243 #define RTD_DAC_TIMEOUT 66000
244 #define RTD_DMA_TIMEOUT 33000 /* 1 msec */
245 #else
246 /* by delaying, power and electrical noise are reduced somewhat */
247 #define WAIT_QUIETLY udelay(1)
248 #define RTD_ADC_TIMEOUT 2000 /* in usec */
249 #define RTD_DAC_TIMEOUT 2000 /* in usec */
250 #define RTD_DMA_TIMEOUT 1000 /* in usec */
251 #endif
253 /*======================================================================
254 Board specific stuff
255 ======================================================================*/
257 #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */
258 #define RTD_CLOCK_BASE 125 /* clock period in ns */
260 /* Note: these speed are slower than the spec, but fit the counter resolution*/
261 #define RTD_MAX_SPEED 1625 /* when sampling, in nanoseconds */
262 /* max speed if we don't have to wait for settling */
263 #define RTD_MAX_SPEED_1 875 /* if single channel, in nanoseconds */
265 #define RTD_MIN_SPEED 2097151875 /* (24bit counter) in nanoseconds */
266 /* min speed when only 1 channel (no burst counter) */
267 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
269 /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */
270 #define DMA_MODE_BITS (\
271 PLX_LOCAL_BUS_16_WIDE_BITS \
272 | PLX_DMA_EN_READYIN_BIT \
273 | PLX_DMA_LOCAL_BURST_EN_BIT \
274 | PLX_EN_CHAIN_BIT \
275 | PLX_DMA_INTR_PCI_BIT \
276 | PLX_LOCAL_ADDR_CONST_BIT \
277 | PLX_DEMAND_MODE_BIT)
279 #define DMA_TRANSFER_BITS (\
280 /* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \
281 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
282 /* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI)
284 /*======================================================================
285 Comedi specific stuff
286 ======================================================================*/
289 * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
291 static const struct comedi_lrange rtd_ai_7520_range = {
292 18, {
293 /* +-5V input range gain steps */
294 BIP_RANGE(5.0),
295 BIP_RANGE(5.0 / 2),
296 BIP_RANGE(5.0 / 4),
297 BIP_RANGE(5.0 / 8),
298 BIP_RANGE(5.0 / 16),
299 BIP_RANGE(5.0 / 32),
300 /* +-10V input range gain steps */
301 BIP_RANGE(10.0),
302 BIP_RANGE(10.0 / 2),
303 BIP_RANGE(10.0 / 4),
304 BIP_RANGE(10.0 / 8),
305 BIP_RANGE(10.0 / 16),
306 BIP_RANGE(10.0 / 32),
307 /* +10V input range gain steps */
308 UNI_RANGE(10.0),
309 UNI_RANGE(10.0 / 2),
310 UNI_RANGE(10.0 / 4),
311 UNI_RANGE(10.0 / 8),
312 UNI_RANGE(10.0 / 16),
313 UNI_RANGE(10.0 / 32),
317 /* PCI4520 has two more gains (6 more entries) */
318 static const struct comedi_lrange rtd_ai_4520_range = {
319 24, {
320 /* +-5V input range gain steps */
321 BIP_RANGE(5.0),
322 BIP_RANGE(5.0 / 2),
323 BIP_RANGE(5.0 / 4),
324 BIP_RANGE(5.0 / 8),
325 BIP_RANGE(5.0 / 16),
326 BIP_RANGE(5.0 / 32),
327 BIP_RANGE(5.0 / 64),
328 BIP_RANGE(5.0 / 128),
329 /* +-10V input range gain steps */
330 BIP_RANGE(10.0),
331 BIP_RANGE(10.0 / 2),
332 BIP_RANGE(10.0 / 4),
333 BIP_RANGE(10.0 / 8),
334 BIP_RANGE(10.0 / 16),
335 BIP_RANGE(10.0 / 32),
336 BIP_RANGE(10.0 / 64),
337 BIP_RANGE(10.0 / 128),
338 /* +10V input range gain steps */
339 UNI_RANGE(10.0),
340 UNI_RANGE(10.0 / 2),
341 UNI_RANGE(10.0 / 4),
342 UNI_RANGE(10.0 / 8),
343 UNI_RANGE(10.0 / 16),
344 UNI_RANGE(10.0 / 32),
345 UNI_RANGE(10.0 / 64),
346 UNI_RANGE(10.0 / 128),
350 /* Table order matches range values */
351 static const struct comedi_lrange rtd_ao_range = {
352 4, {
353 UNI_RANGE(5),
354 UNI_RANGE(10),
355 BIP_RANGE(5),
356 BIP_RANGE(10),
360 enum rtd_boardid {
361 BOARD_DM7520,
362 BOARD_PCI4520,
365 struct rtd_boardinfo {
366 const char *name;
367 int range_bip10; /* start of +-10V range */
368 int range_uni10; /* start of +10V range */
369 const struct comedi_lrange *ai_range;
372 static const struct rtd_boardinfo rtd520Boards[] = {
373 [BOARD_DM7520] = {
374 .name = "DM7520",
375 .range_bip10 = 6,
376 .range_uni10 = 12,
377 .ai_range = &rtd_ai_7520_range,
379 [BOARD_PCI4520] = {
380 .name = "PCI4520",
381 .range_bip10 = 8,
382 .range_uni10 = 16,
383 .ai_range = &rtd_ai_4520_range,
387 struct rtd_private {
388 /* memory mapped board structures */
389 void __iomem *las0;
390 void __iomem *las1;
391 void __iomem *lcfg;
393 long ai_count; /* total transfer size (samples) */
394 int xfer_count; /* # to transfer data. 0->1/2FIFO */
395 int flags; /* flag event modes */
397 unsigned char chan_is_bipolar[RTD_MAX_CHANLIST / 8]; /* bit array */
399 unsigned int ao_readback[2];
401 unsigned fifosz;
404 /* bit defines for "flags" */
405 #define SEND_EOS 0x01 /* send End Of Scan events */
406 #define DMA0_ACTIVE 0x02 /* DMA0 is active */
407 #define DMA1_ACTIVE 0x04 /* DMA1 is active */
409 /* Macros for accessing channel list bit array */
410 #define CHAN_ARRAY_TEST(array, index) \
411 (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
412 #define CHAN_ARRAY_SET(array, index) \
413 (((array)[(index)/8] |= 1 << ((index) & 0x7)))
414 #define CHAN_ARRAY_CLEAR(array, index) \
415 (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
418 Given a desired period and the clock period (both in ns),
419 return the proper counter value (divider-1).
420 Sets the original period to be the true value.
421 Note: you have to check if the value is larger than the counter range!
423 static int rtd_ns_to_timer_base(unsigned int *nanosec,
424 int round_mode, int base)
426 int divider;
428 switch (round_mode) {
429 case TRIG_ROUND_NEAREST:
430 default:
431 divider = (*nanosec + base / 2) / base;
432 break;
433 case TRIG_ROUND_DOWN:
434 divider = (*nanosec) / base;
435 break;
436 case TRIG_ROUND_UP:
437 divider = (*nanosec + base - 1) / base;
438 break;
440 if (divider < 2)
441 divider = 2; /* min is divide by 2 */
443 /* Note: we don't check for max, because different timers
444 have different ranges */
446 *nanosec = base * divider;
447 return divider - 1; /* countdown is divisor+1 */
451 Given a desired period (in ns),
452 return the proper counter value (divider-1) for the internal clock.
453 Sets the original period to be the true value.
455 static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
457 return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
461 Convert a single comedi channel-gain entry to a RTD520 table entry
463 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
464 unsigned int chanspec, int index)
466 const struct rtd_boardinfo *board = comedi_board(dev);
467 struct rtd_private *devpriv = dev->private;
468 unsigned int chan = CR_CHAN(chanspec);
469 unsigned int range = CR_RANGE(chanspec);
470 unsigned int aref = CR_AREF(chanspec);
471 unsigned short r = 0;
473 r |= chan & 0xf;
475 /* Note: we also setup the channel list bipolar flag array */
476 if (range < board->range_bip10) {
477 /* +-5 range */
478 r |= 0x000;
479 r |= (range & 0x7) << 4;
480 CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
481 } else if (range < board->range_uni10) {
482 /* +-10 range */
483 r |= 0x100;
484 r |= ((range - board->range_bip10) & 0x7) << 4;
485 CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
486 } else {
487 /* +10 range */
488 r |= 0x200;
489 r |= ((range - board->range_uni10) & 0x7) << 4;
490 CHAN_ARRAY_CLEAR(devpriv->chan_is_bipolar, index);
493 switch (aref) {
494 case AREF_GROUND: /* on-board ground */
495 break;
497 case AREF_COMMON:
498 r |= 0x80; /* ref external analog common */
499 break;
501 case AREF_DIFF:
502 r |= 0x400; /* differential inputs */
503 break;
505 case AREF_OTHER: /* ??? */
506 break;
508 /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
509 chan, range, aref, r); */
510 return r;
514 Setup the channel-gain table from a comedi list
516 static void rtd_load_channelgain_list(struct comedi_device *dev,
517 unsigned int n_chan, unsigned int *list)
519 struct rtd_private *devpriv = dev->private;
521 if (n_chan > 1) { /* setup channel gain table */
522 int ii;
524 writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
525 writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
526 for (ii = 0; ii < n_chan; ii++) {
527 writel(rtd_convert_chan_gain(dev, list[ii], ii),
528 devpriv->las0 + LAS0_CGT_WRITE);
530 } else { /* just use the channel gain latch */
531 writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
532 writel(rtd_convert_chan_gain(dev, list[0], 0),
533 devpriv->las0 + LAS0_CGL_WRITE);
537 /* determine fifo size by doing adc conversions until the fifo half
538 empty status flag clears */
539 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
541 struct rtd_private *devpriv = dev->private;
542 unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
543 unsigned i;
544 static const unsigned limit = 0x2000;
545 unsigned fifo_size = 0;
547 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
548 rtd_load_channelgain_list(dev, 1, &chanspec);
549 /* ADC conversion trigger source: SOFTWARE */
550 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
551 /* convert samples */
552 for (i = 0; i < limit; ++i) {
553 unsigned fifo_status;
554 /* trigger conversion */
555 writew(0, devpriv->las0 + LAS0_ADC);
556 udelay(1);
557 fifo_status = readl(devpriv->las0 + LAS0_ADC);
558 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
559 fifo_size = 2 * i;
560 break;
563 if (i == limit) {
564 dev_info(dev->class_dev, "failed to probe fifo size.\n");
565 return -EIO;
567 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
568 if (fifo_size != 0x400 && fifo_size != 0x2000) {
569 dev_info(dev->class_dev,
570 "unexpected fifo size of %i, expected 1024 or 8192.\n",
571 fifo_size);
572 return -EIO;
574 return fifo_size;
578 "instructions" read/write data in "one-shot" or "software-triggered"
579 mode (simplest case).
580 This doesn't use interrupts.
582 Note, we don't do any settling delays. Use a instruction list to
583 select, delay, then read.
585 static int rtd_ai_rinsn(struct comedi_device *dev,
586 struct comedi_subdevice *s, struct comedi_insn *insn,
587 unsigned int *data)
589 struct rtd_private *devpriv = dev->private;
590 int n, ii;
591 int stat;
593 /* clear any old fifo data */
594 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
596 /* write channel to multiplexer and clear channel gain table */
597 rtd_load_channelgain_list(dev, 1, &insn->chanspec);
599 /* ADC conversion trigger source: SOFTWARE */
600 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
602 /* convert n samples */
603 for (n = 0; n < insn->n; n++) {
604 s16 d;
605 /* trigger conversion */
606 writew(0, devpriv->las0 + LAS0_ADC);
608 for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
609 stat = readl(devpriv->las0 + LAS0_ADC);
610 if (stat & FS_ADC_NOT_EMPTY) /* 1 -> not empty */
611 break;
612 WAIT_QUIETLY;
614 if (ii >= RTD_ADC_TIMEOUT)
615 return -ETIMEDOUT;
617 /* read data */
618 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
619 /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
620 d = d >> 3; /* low 3 bits are marker lines */
621 if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar, 0))
622 /* convert to comedi unsigned data */
623 data[n] = d + 2048;
624 else
625 data[n] = d;
628 /* return the number of samples read/written */
629 return n;
633 Get what we know is there.... Fast!
634 This uses 1/2 the bus cycles of read_dregs (below).
636 The manual claims that we can do a lword read, but it doesn't work here.
638 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
639 int count)
641 struct rtd_private *devpriv = dev->private;
642 int ii;
644 for (ii = 0; ii < count; ii++) {
645 short sample;
646 s16 d;
648 if (0 == devpriv->ai_count) { /* done */
649 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
650 continue;
653 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
654 d = d >> 3; /* low 3 bits are marker lines */
655 if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
656 s->async->cur_chan)) {
657 /* convert to comedi unsigned data */
658 sample = d + 2048;
659 } else
660 sample = d;
662 if (!comedi_buf_put(s->async, sample))
663 return -1;
665 if (devpriv->ai_count > 0) /* < 0, means read forever */
666 devpriv->ai_count--;
668 return 0;
672 unknown amout of data is waiting in fifo.
674 static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
676 struct rtd_private *devpriv = dev->private;
678 while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
679 short sample;
680 s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
682 if (0 == devpriv->ai_count) { /* done */
683 continue; /* read rest */
686 d = d >> 3; /* low 3 bits are marker lines */
687 if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
688 s->async->cur_chan)) {
689 /* convert to comedi unsigned data */
690 sample = d + 2048;
691 } else
692 sample = d;
694 if (!comedi_buf_put(s->async, sample))
695 return -1;
697 if (devpriv->ai_count > 0) /* < 0, means read forever */
698 devpriv->ai_count--;
700 return 0;
704 Handle all rtd520 interrupts.
705 Runs atomically and is never re-entered.
706 This is a "slow handler"; other interrupts may be active.
707 The data conversion may someday happen in a "bottom half".
709 static irqreturn_t rtd_interrupt(int irq, void *d)
711 struct comedi_device *dev = d;
712 struct comedi_subdevice *s = &dev->subdevices[0];
713 struct rtd_private *devpriv = dev->private;
714 u32 overrun;
715 u16 status;
716 u16 fifo_status;
718 if (!dev->attached)
719 return IRQ_NONE;
721 fifo_status = readl(devpriv->las0 + LAS0_ADC);
722 /* check for FIFO full, this automatically halts the ADC! */
723 if (!(fifo_status & FS_ADC_NOT_FULL)) /* 0 -> full */
724 goto xfer_abort;
726 status = readw(devpriv->las0 + LAS0_IT);
727 /* if interrupt was not caused by our board, or handled above */
728 if (0 == status)
729 return IRQ_HANDLED;
731 if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */
733 * since the priority interrupt controller may have queued
734 * a sample counter interrupt, even though we have already
735 * finished, we must handle the possibility that there is
736 * no data here
738 if (!(fifo_status & FS_ADC_HEMPTY)) {
739 /* FIFO half full */
740 if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
741 goto xfer_abort;
743 if (0 == devpriv->ai_count)
744 goto xfer_done;
746 comedi_event(dev, s);
747 } else if (devpriv->xfer_count > 0) {
748 if (fifo_status & FS_ADC_NOT_EMPTY) {
749 /* FIFO not empty */
750 if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
751 goto xfer_abort;
753 if (0 == devpriv->ai_count)
754 goto xfer_done;
756 comedi_event(dev, s);
761 overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
762 if (overrun)
763 goto xfer_abort;
765 /* clear the interrupt */
766 writew(status, devpriv->las0 + LAS0_CLEAR);
767 readw(devpriv->las0 + LAS0_CLEAR);
768 return IRQ_HANDLED;
770 xfer_abort:
771 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
772 s->async->events |= COMEDI_CB_ERROR;
773 devpriv->ai_count = 0; /* stop and don't transfer any more */
774 /* fall into xfer_done */
776 xfer_done:
777 /* pacer stop source: SOFTWARE */
778 writel(0, devpriv->las0 + LAS0_PACER_STOP);
779 writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
780 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
781 writew(0, devpriv->las0 + LAS0_IT);
783 if (devpriv->ai_count > 0) { /* there shouldn't be anything left */
784 fifo_status = readl(devpriv->las0 + LAS0_ADC);
785 ai_read_dregs(dev, s); /* read anything left in FIFO */
788 s->async->events |= COMEDI_CB_EOA; /* signal end to comedi */
789 comedi_event(dev, s);
791 /* clear the interrupt */
792 status = readw(devpriv->las0 + LAS0_IT);
793 writew(status, devpriv->las0 + LAS0_CLEAR);
794 readw(devpriv->las0 + LAS0_CLEAR);
796 fifo_status = readl(devpriv->las0 + LAS0_ADC);
797 overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
799 return IRQ_HANDLED;
803 cmdtest tests a particular command to see if it is valid.
804 Using the cmdtest ioctl, a user can create a valid cmd
805 and then have it executed by the cmd ioctl (asynchronously).
807 cmdtest returns 1,2,3,4 or 0, depending on which tests
808 the command passes.
811 static int rtd_ai_cmdtest(struct comedi_device *dev,
812 struct comedi_subdevice *s, struct comedi_cmd *cmd)
814 int err = 0;
815 int tmp;
817 /* Step 1 : check if triggers are trivially valid */
819 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
820 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
821 TRIG_TIMER | TRIG_EXT);
822 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
823 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
824 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
826 if (err)
827 return 1;
829 /* Step 2a : make sure trigger sources are unique */
831 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
832 err |= cfc_check_trigger_is_unique(cmd->convert_src);
833 err |= cfc_check_trigger_is_unique(cmd->stop_src);
835 /* Step 2b : and mutually compatible */
837 if (err)
838 return 2;
840 /* Step 3: check if arguments are trivially valid */
842 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
844 if (cmd->scan_begin_src == TRIG_TIMER) {
845 /* Note: these are time periods, not actual rates */
846 if (1 == cmd->chanlist_len) { /* no scanning */
847 if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
848 RTD_MAX_SPEED_1)) {
849 rtd_ns_to_timer(&cmd->scan_begin_arg,
850 TRIG_ROUND_UP);
851 err |= -EINVAL;
853 if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
854 RTD_MIN_SPEED_1)) {
855 rtd_ns_to_timer(&cmd->scan_begin_arg,
856 TRIG_ROUND_DOWN);
857 err |= -EINVAL;
859 } else {
860 if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
861 RTD_MAX_SPEED)) {
862 rtd_ns_to_timer(&cmd->scan_begin_arg,
863 TRIG_ROUND_UP);
864 err |= -EINVAL;
866 if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
867 RTD_MIN_SPEED)) {
868 rtd_ns_to_timer(&cmd->scan_begin_arg,
869 TRIG_ROUND_DOWN);
870 err |= -EINVAL;
873 } else {
874 /* external trigger */
875 /* should be level/edge, hi/lo specification here */
876 /* should specify multiple external triggers */
877 err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
880 if (cmd->convert_src == TRIG_TIMER) {
881 if (1 == cmd->chanlist_len) { /* no scanning */
882 if (cfc_check_trigger_arg_min(&cmd->convert_arg,
883 RTD_MAX_SPEED_1)) {
884 rtd_ns_to_timer(&cmd->convert_arg,
885 TRIG_ROUND_UP);
886 err |= -EINVAL;
888 if (cfc_check_trigger_arg_max(&cmd->convert_arg,
889 RTD_MIN_SPEED_1)) {
890 rtd_ns_to_timer(&cmd->convert_arg,
891 TRIG_ROUND_DOWN);
892 err |= -EINVAL;
894 } else {
895 if (cfc_check_trigger_arg_min(&cmd->convert_arg,
896 RTD_MAX_SPEED)) {
897 rtd_ns_to_timer(&cmd->convert_arg,
898 TRIG_ROUND_UP);
899 err |= -EINVAL;
901 if (cfc_check_trigger_arg_max(&cmd->convert_arg,
902 RTD_MIN_SPEED)) {
903 rtd_ns_to_timer(&cmd->convert_arg,
904 TRIG_ROUND_DOWN);
905 err |= -EINVAL;
908 } else {
909 /* external trigger */
910 /* see above */
911 err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
914 if (cmd->stop_src == TRIG_COUNT) {
915 /* TODO check for rounding error due to counter wrap */
916 } else {
917 /* TRIG_NONE */
918 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
921 if (err)
922 return 3;
925 /* step 4: fix up any arguments */
927 if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
928 cmd->chanlist_len = RTD_MAX_CHANLIST;
929 err++;
931 if (cmd->scan_begin_src == TRIG_TIMER) {
932 tmp = cmd->scan_begin_arg;
933 rtd_ns_to_timer(&cmd->scan_begin_arg,
934 cmd->flags & TRIG_ROUND_MASK);
935 if (tmp != cmd->scan_begin_arg)
936 err++;
939 if (cmd->convert_src == TRIG_TIMER) {
940 tmp = cmd->convert_arg;
941 rtd_ns_to_timer(&cmd->convert_arg,
942 cmd->flags & TRIG_ROUND_MASK);
943 if (tmp != cmd->convert_arg)
944 err++;
946 if (cmd->scan_begin_src == TRIG_TIMER
947 && (cmd->scan_begin_arg
948 < (cmd->convert_arg * cmd->scan_end_arg))) {
949 cmd->scan_begin_arg =
950 cmd->convert_arg * cmd->scan_end_arg;
951 err++;
955 if (err)
956 return 4;
958 return 0;
962 Execute a analog in command with many possible triggering options.
963 The data get stored in the async structure of the subdevice.
964 This is usually done by an interrupt handler.
965 Userland gets to the data using read calls.
967 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
969 struct rtd_private *devpriv = dev->private;
970 struct comedi_cmd *cmd = &s->async->cmd;
971 int timer;
973 /* stop anything currently running */
974 /* pacer stop source: SOFTWARE */
975 writel(0, devpriv->las0 + LAS0_PACER_STOP);
976 writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
977 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
978 writew(0, devpriv->las0 + LAS0_IT);
979 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
980 writel(0, devpriv->las0 + LAS0_OVERRUN);
982 /* start configuration */
983 /* load channel list and reset CGT */
984 rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
986 /* setup the common case and override if needed */
987 if (cmd->chanlist_len > 1) {
988 /* pacer start source: SOFTWARE */
989 writel(0, devpriv->las0 + LAS0_PACER_START);
990 /* burst trigger source: PACER */
991 writel(1, devpriv->las0 + LAS0_BURST_START);
992 /* ADC conversion trigger source: BURST */
993 writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
994 } else { /* single channel */
995 /* pacer start source: SOFTWARE */
996 writel(0, devpriv->las0 + LAS0_PACER_START);
997 /* ADC conversion trigger source: PACER */
998 writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
1000 writel((devpriv->fifosz / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
1002 if (TRIG_TIMER == cmd->scan_begin_src) {
1003 /* scan_begin_arg is in nanoseconds */
1004 /* find out how many samples to wait before transferring */
1005 if (cmd->flags & TRIG_WAKE_EOS) {
1007 * this may generate un-sustainable interrupt rates
1008 * the application is responsible for doing the
1009 * right thing
1011 devpriv->xfer_count = cmd->chanlist_len;
1012 devpriv->flags |= SEND_EOS;
1013 } else {
1014 /* arrange to transfer data periodically */
1015 devpriv->xfer_count =
1016 (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
1017 cmd->scan_begin_arg;
1018 if (devpriv->xfer_count < cmd->chanlist_len) {
1019 /* transfer after each scan (and avoid 0) */
1020 devpriv->xfer_count = cmd->chanlist_len;
1021 } else { /* make a multiple of scan length */
1022 devpriv->xfer_count =
1023 (devpriv->xfer_count +
1024 cmd->chanlist_len - 1)
1025 / cmd->chanlist_len;
1026 devpriv->xfer_count *= cmd->chanlist_len;
1028 devpriv->flags |= SEND_EOS;
1030 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
1031 /* out of counter range, use 1/2 fifo instead */
1032 devpriv->xfer_count = 0;
1033 devpriv->flags &= ~SEND_EOS;
1034 } else {
1035 /* interrupt for each transfer */
1036 writel((devpriv->xfer_count - 1) & 0xffff,
1037 devpriv->las0 + LAS0_ACNT);
1039 } else { /* unknown timing, just use 1/2 FIFO */
1040 devpriv->xfer_count = 0;
1041 devpriv->flags &= ~SEND_EOS;
1043 /* pacer clock source: INTERNAL 8MHz */
1044 writel(1, devpriv->las0 + LAS0_PACER_SELECT);
1045 /* just interrupt, don't stop */
1046 writel(1, devpriv->las0 + LAS0_ACNT_STOP_ENABLE);
1048 /* BUG??? these look like enumerated values, but they are bit fields */
1050 /* First, setup when to stop */
1051 switch (cmd->stop_src) {
1052 case TRIG_COUNT: /* stop after N scans */
1053 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
1054 if ((devpriv->xfer_count > 0)
1055 && (devpriv->xfer_count > devpriv->ai_count)) {
1056 devpriv->xfer_count = devpriv->ai_count;
1058 break;
1060 case TRIG_NONE: /* stop when cancel is called */
1061 devpriv->ai_count = -1; /* read forever */
1062 break;
1065 /* Scan timing */
1066 switch (cmd->scan_begin_src) {
1067 case TRIG_TIMER: /* periodic scanning */
1068 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
1069 TRIG_ROUND_NEAREST);
1070 /* set PACER clock */
1071 writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
1073 break;
1075 case TRIG_EXT:
1076 /* pacer start source: EXTERNAL */
1077 writel(1, devpriv->las0 + LAS0_PACER_START);
1078 break;
1081 /* Sample timing within a scan */
1082 switch (cmd->convert_src) {
1083 case TRIG_TIMER: /* periodic */
1084 if (cmd->chanlist_len > 1) {
1085 /* only needed for multi-channel */
1086 timer = rtd_ns_to_timer(&cmd->convert_arg,
1087 TRIG_ROUND_NEAREST);
1088 /* setup BURST clock */
1089 writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
1092 break;
1094 case TRIG_EXT: /* external */
1095 /* burst trigger source: EXTERNAL */
1096 writel(2, devpriv->las0 + LAS0_BURST_START);
1097 break;
1099 /* end configuration */
1101 /* This doesn't seem to work. There is no way to clear an interrupt
1102 that the priority controller has queued! */
1103 writew(~0, devpriv->las0 + LAS0_CLEAR);
1104 readw(devpriv->las0 + LAS0_CLEAR);
1106 /* TODO: allow multiple interrupt sources */
1107 if (devpriv->xfer_count > 0) { /* transfer every N samples */
1108 writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
1109 } else { /* 1/2 FIFO transfers */
1110 writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
1113 /* BUG: start_src is ASSUMED to be TRIG_NOW */
1114 /* BUG? it seems like things are running before the "start" */
1115 readl(devpriv->las0 + LAS0_PACER); /* start pacer */
1116 return 0;
1120 Stop a running data acquisition.
1122 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1124 struct rtd_private *devpriv = dev->private;
1125 u32 overrun;
1126 u16 status;
1128 /* pacer stop source: SOFTWARE */
1129 writel(0, devpriv->las0 + LAS0_PACER_STOP);
1130 writel(0, devpriv->las0 + LAS0_PACER); /* stop pacer */
1131 writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
1132 writew(0, devpriv->las0 + LAS0_IT);
1133 devpriv->ai_count = 0; /* stop and don't transfer any more */
1134 status = readw(devpriv->las0 + LAS0_IT);
1135 overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
1136 return 0;
1140 Output one (or more) analog values to a single port as fast as possible.
1142 static int rtd_ao_winsn(struct comedi_device *dev,
1143 struct comedi_subdevice *s, struct comedi_insn *insn,
1144 unsigned int *data)
1146 struct rtd_private *devpriv = dev->private;
1147 int i;
1148 int chan = CR_CHAN(insn->chanspec);
1149 int range = CR_RANGE(insn->chanspec);
1151 /* Configure the output range (table index matches the range values) */
1152 writew(range & 7, devpriv->las0 +
1153 ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
1155 /* Writing a list of values to an AO channel is probably not
1156 * very useful, but that's how the interface is defined. */
1157 for (i = 0; i < insn->n; ++i) {
1158 int val = data[i] << 3;
1159 int stat = 0; /* initialize to avoid bogus warning */
1160 int ii;
1162 /* VERIFY: comedi range and offset conversions */
1164 if ((range > 1) /* bipolar */
1165 && (data[i] < 2048)) {
1166 /* offset and sign extend */
1167 val = (((int)data[i]) - 2048) << 3;
1168 } else { /* unipolor */
1169 val = data[i] << 3;
1172 /* a typical programming sequence */
1173 writew(val, devpriv->las1 +
1174 ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
1175 writew(0, devpriv->las0 +
1176 ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
1178 devpriv->ao_readback[chan] = data[i];
1180 for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
1181 stat = readl(devpriv->las0 + LAS0_ADC);
1182 /* 1 -> not empty */
1183 if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
1184 FS_DAC2_NOT_EMPTY))
1185 break;
1186 WAIT_QUIETLY;
1188 if (ii >= RTD_DAC_TIMEOUT)
1189 return -ETIMEDOUT;
1192 /* return the number of samples read/written */
1193 return i;
1196 /* AO subdevices should have a read insn as well as a write insn.
1197 * Usually this means copying a value stored in devpriv. */
1198 static int rtd_ao_rinsn(struct comedi_device *dev,
1199 struct comedi_subdevice *s, struct comedi_insn *insn,
1200 unsigned int *data)
1202 struct rtd_private *devpriv = dev->private;
1203 int i;
1204 int chan = CR_CHAN(insn->chanspec);
1206 for (i = 0; i < insn->n; i++)
1207 data[i] = devpriv->ao_readback[chan];
1210 return i;
1213 static int rtd_dio_insn_bits(struct comedi_device *dev,
1214 struct comedi_subdevice *s,
1215 struct comedi_insn *insn,
1216 unsigned int *data)
1218 struct rtd_private *devpriv = dev->private;
1219 unsigned int mask = data[0];
1220 unsigned int bits = data[1];
1222 if (mask) {
1223 s->state &= ~mask;
1224 s->state |= (bits & mask);
1226 writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
1229 data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
1231 return insn->n;
1234 static int rtd_dio_insn_config(struct comedi_device *dev,
1235 struct comedi_subdevice *s,
1236 struct comedi_insn *insn,
1237 unsigned int *data)
1239 struct rtd_private *devpriv = dev->private;
1240 unsigned int chan = CR_CHAN(insn->chanspec);
1241 unsigned int mask = 1 << chan;
1243 switch (data[0]) {
1244 case INSN_CONFIG_DIO_OUTPUT:
1245 s->io_bits |= mask;
1246 break;
1247 case INSN_CONFIG_DIO_INPUT:
1248 s->io_bits &= ~mask;
1249 break;
1250 case INSN_CONFIG_DIO_QUERY:
1251 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
1252 return insn->n;
1253 break;
1254 default:
1255 return -EINVAL;
1258 /* TODO support digital match interrupts and strobes */
1260 /* set direction */
1261 writew(0x01, devpriv->las0 + LAS0_DIO_STATUS);
1262 writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
1264 /* clear interrupts */
1265 writew(0x00, devpriv->las0 + LAS0_DIO_STATUS);
1267 /* port1 can only be all input or all output */
1269 /* there are also 2 user input lines and 2 user output lines */
1271 return insn->n;
1274 static void rtd_reset(struct comedi_device *dev)
1276 struct rtd_private *devpriv = dev->private;
1278 writel(0, devpriv->las0 + LAS0_BOARD_RESET);
1279 udelay(100); /* needed? */
1280 writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1281 writew(0, devpriv->las0 + LAS0_IT);
1282 writew(~0, devpriv->las0 + LAS0_CLEAR);
1283 readw(devpriv->las0 + LAS0_CLEAR);
1287 * initialize board, per RTD spec
1288 * also, initialize shadow registers
1290 static void rtd_init_board(struct comedi_device *dev)
1292 struct rtd_private *devpriv = dev->private;
1294 rtd_reset(dev);
1296 writel(0, devpriv->las0 + LAS0_OVERRUN);
1297 writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
1298 writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
1299 writel(0, devpriv->las0 + LAS0_DAC1_RESET);
1300 writel(0, devpriv->las0 + LAS0_DAC2_RESET);
1301 /* clear digital IO fifo */
1302 writew(0, devpriv->las0 + LAS0_DIO_STATUS);
1303 writeb((0 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1304 writeb((1 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1305 writeb((2 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1306 writeb((3 << 6) | 0x00, devpriv->las0 + LAS0_UTC_CTRL);
1307 /* TODO: set user out source ??? */
1310 /* The RTD driver does this */
1311 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1312 struct pci_dev *pcidev)
1314 unsigned char pci_latency;
1316 pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1317 if (pci_latency < 32) {
1318 dev_info(dev->class_dev,
1319 "PCI latency changed from %d to %d\n",
1320 pci_latency, 32);
1321 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1325 static int rtd_auto_attach(struct comedi_device *dev,
1326 unsigned long context)
1328 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1329 const struct rtd_boardinfo *board = NULL;
1330 struct rtd_private *devpriv;
1331 struct comedi_subdevice *s;
1332 int ret;
1334 if (context < ARRAY_SIZE(rtd520Boards))
1335 board = &rtd520Boards[context];
1336 if (!board)
1337 return -ENODEV;
1338 dev->board_ptr = board;
1339 dev->board_name = board->name;
1341 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1342 if (!devpriv)
1343 return -ENOMEM;
1344 dev->private = devpriv;
1346 ret = comedi_pci_enable(dev);
1347 if (ret)
1348 return ret;
1350 devpriv->las0 = pci_ioremap_bar(pcidev, 2);
1351 devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1352 devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1353 if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
1354 return -ENOMEM;
1356 rtd_pci_latency_quirk(dev, pcidev);
1358 if (pcidev->irq) {
1359 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1360 dev->board_name, dev);
1361 if (ret == 0)
1362 dev->irq = pcidev->irq;
1365 ret = comedi_alloc_subdevices(dev, 4);
1366 if (ret)
1367 return ret;
1369 s = &dev->subdevices[0];
1370 /* analog input subdevice */
1371 s->type = COMEDI_SUBD_AI;
1372 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1373 s->n_chan = 16;
1374 s->maxdata = 0x0fff;
1375 s->range_table = board->ai_range;
1376 s->len_chanlist = RTD_MAX_CHANLIST;
1377 s->insn_read = rtd_ai_rinsn;
1378 if (dev->irq) {
1379 dev->read_subdev = s;
1380 s->subdev_flags |= SDF_CMD_READ;
1381 s->do_cmd = rtd_ai_cmd;
1382 s->do_cmdtest = rtd_ai_cmdtest;
1383 s->cancel = rtd_ai_cancel;
1386 s = &dev->subdevices[1];
1387 /* analog output subdevice */
1388 s->type = COMEDI_SUBD_AO;
1389 s->subdev_flags = SDF_WRITABLE;
1390 s->n_chan = 2;
1391 s->maxdata = 0x0fff;
1392 s->range_table = &rtd_ao_range;
1393 s->insn_write = rtd_ao_winsn;
1394 s->insn_read = rtd_ao_rinsn;
1396 s = &dev->subdevices[2];
1397 /* digital i/o subdevice */
1398 s->type = COMEDI_SUBD_DIO;
1399 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1400 /* we only support port 0 right now. Ignoring port 1 and user IO */
1401 s->n_chan = 8;
1402 s->maxdata = 1;
1403 s->range_table = &range_digital;
1404 s->insn_bits = rtd_dio_insn_bits;
1405 s->insn_config = rtd_dio_insn_config;
1407 /* timer/counter subdevices (not currently supported) */
1408 s = &dev->subdevices[3];
1409 s->type = COMEDI_SUBD_COUNTER;
1410 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1411 s->n_chan = 3;
1412 s->maxdata = 0xffff;
1414 rtd_init_board(dev);
1416 ret = rtd520_probe_fifo_depth(dev);
1417 if (ret < 0)
1418 return ret;
1419 devpriv->fifosz = ret;
1421 if (dev->irq)
1422 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1424 dev_info(dev->class_dev, "%s attached\n", dev->board_name);
1426 return 0;
1429 static void rtd_detach(struct comedi_device *dev)
1431 struct rtd_private *devpriv = dev->private;
1433 if (devpriv) {
1434 /* Shut down any board ops by resetting it */
1435 if (devpriv->las0 && devpriv->lcfg)
1436 rtd_reset(dev);
1437 if (dev->irq) {
1438 writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
1439 ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
1440 devpriv->lcfg + PLX_INTRCS_REG);
1441 free_irq(dev->irq, dev);
1443 if (devpriv->las0)
1444 iounmap(devpriv->las0);
1445 if (devpriv->las1)
1446 iounmap(devpriv->las1);
1447 if (devpriv->lcfg)
1448 iounmap(devpriv->lcfg);
1450 comedi_pci_disable(dev);
1453 static struct comedi_driver rtd520_driver = {
1454 .driver_name = "rtd520",
1455 .module = THIS_MODULE,
1456 .auto_attach = rtd_auto_attach,
1457 .detach = rtd_detach,
1460 static int rtd520_pci_probe(struct pci_dev *dev,
1461 const struct pci_device_id *id)
1463 return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1466 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
1467 { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1468 { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1469 { 0 }
1471 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1473 static struct pci_driver rtd520_pci_driver = {
1474 .name = "rtd520",
1475 .id_table = rtd520_pci_table,
1476 .probe = rtd520_pci_probe,
1477 .remove = comedi_pci_auto_unconfig,
1479 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1481 MODULE_AUTHOR("Comedi http://www.comedi.org");
1482 MODULE_DESCRIPTION("Comedi low-level driver");
1483 MODULE_LICENSE("GPL");