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