Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[deliverable/linux.git] / drivers / staging / comedi / drivers / cb_pcidas64.c
CommitLineData
88b12a9a
FMH
1/*
2 comedi/drivers/cb_pcidas64.c
3 This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
4 64xx, 60xx, and 4020 cards.
5
6 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
7 Copyright (C) 2001, 2002 Frank Mori Hess
8
9 Thanks also go to the following people:
10
11 Steve Rosenbluth, for providing the source code for
12 his pci-das6402 driver, and source code for working QNX pci-6402
13 drivers by Greg Laird and Mariusz Bogacz. None of the code was
14 used directly here, but it was useful as an additional source of
15 documentation on how to program the boards.
16
17 John Sims, for much testing and feedback on pcidas-4020 support.
18
19 COMEDI - Linux Control and Measurement Device Interface
20 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
21
22 This program is free software; you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation; either version 2 of the License, or
25 (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
641f064e 31*/
88b12a9a
FMH
32
33/*
11aade26
IA
34 * Driver: cb_pcidas64
35 * Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series
36 * with the PLX 9080 PCI controller
37 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
38 * Status: works
39 * Updated: Fri, 02 Nov 2012 18:58:55 +0000
40 * Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
41 * PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
42 * PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
43 * PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
44 * PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
45 * PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
46 * PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
47 * PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
48 * PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
49 *
50 * Configuration options:
51 * None.
52 *
53 * Manual attachment of PCI cards with the comedi_config utility is not
54 * supported by this driver; they are attached automatically.
55 *
56 * These boards may be autocalibrated with the comedi_calibrate utility.
57 *
58 * To select the bnc trigger input on the 4020 (instead of the dio input),
59 * specify a nonzero channel in the chanspec. If you wish to use an external
60 * master clock on the 4020, you may do so by setting the scan_begin_src
61 * to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
62 * to configure the divisor to use for the external clock.
63 *
64 * Some devices are not identified because the PCI device IDs are not yet
65 * known. If you have such a board, please let the maintainers know.
66 */
88b12a9a
FMH
67
68/*
69
70TODO:
71 make it return error if user attempts an ai command that uses the
46ca84c4 72 external queue, and an ao command simultaneously user counter subdevice
88b12a9a 73 there are a number of boards this driver will support when they are
46ca84c4
IA
74 fully released, but does not yet since the pci device id numbers
75 are not yet available.
76
77 support prescaled 100khz clock for slow pacing (not available on 6000
78 series?)
79
88b12a9a
FMH
80 make ao fifo size adjustable like ai fifo
81*/
82
ce157f80 83#include <linux/module.h>
33782dd5 84#include <linux/pci.h>
88b12a9a 85#include <linux/delay.h>
70265d24 86#include <linux/interrupt.h>
88b12a9a 87
33782dd5
HS
88#include "../comedidev.h"
89
88b12a9a
FMH
90#include "8253.h"
91#include "8255.h"
92#include "plx9080.h"
93#include "comedi_fc.h"
94
9ef4dea6 95#define TIMER_BASE 25 /* 40MHz master clock */
46ca84c4
IA
96/* 100kHz 'prescaled' clock for slow acquisition,
97 * maybe I'll support this someday */
98#define PRESCALED_TIMER_BASE 10000
88b12a9a
FMH
99#define DMA_BUFFER_SIZE 0x1000
100
101/* maximum value that can be loaded into board's 24-bit counters*/
102static const int max_counter_value = 0xffffff;
103
104/* PCI-DAS64xxx base addresses */
105
681d335a 106/* devpriv->main_iobase registers */
88b12a9a 107enum write_only_registers {
9ef4dea6
BP
108 INTR_ENABLE_REG = 0x0, /* interrupt enable register */
109 HW_CONFIG_REG = 0x2, /* hardware config register */
88b12a9a
FMH
110 DAQ_SYNC_REG = 0xc,
111 DAQ_ATRIG_LOW_4020_REG = 0xc,
9ef4dea6
BP
112 ADC_CONTROL0_REG = 0x10, /* adc control register 0 */
113 ADC_CONTROL1_REG = 0x12, /* adc control register 1 */
88b12a9a 114 CALIBRATION_REG = 0x14,
46ca84c4
IA
115 /* lower 16 bits of adc sample interval counter */
116 ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16,
117 /* upper 8 bits of adc sample interval counter */
118 ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18,
119 /* lower 16 bits of delay interval counter */
120 ADC_DELAY_INTERVAL_LOWER_REG = 0x1a,
121 /* upper 8 bits of delay interval counter */
122 ADC_DELAY_INTERVAL_UPPER_REG = 0x1c,
123 /* lower 16 bits of hardware conversion/scan counter */
124 ADC_COUNT_LOWER_REG = 0x1e,
125 /* upper 8 bits of hardware conversion/scan counter */
126 ADC_COUNT_UPPER_REG = 0x20,
25985edc 127 ADC_START_REG = 0x22, /* software trigger to start acquisition */
9ef4dea6
BP
128 ADC_CONVERT_REG = 0x24, /* initiates single conversion */
129 ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */
130 ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */
88b12a9a 131 ADC_BUFFER_CLEAR_REG = 0x2a,
46ca84c4
IA
132 /* high channel for internal queue, use adc_chan_bits() inline above */
133 ADC_QUEUE_HIGH_REG = 0x2c,
9ef4dea6
BP
134 DAC_CONTROL0_REG = 0x50, /* dac control register 0 */
135 DAC_CONTROL1_REG = 0x52, /* dac control register 0 */
46ca84c4
IA
136 /* lower 16 bits of dac sample interval counter */
137 DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54,
138 /* upper 8 bits of dac sample interval counter */
139 DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56,
88b12a9a
FMH
140 DAC_SELECT_REG = 0x60,
141 DAC_START_REG = 0x64,
9ef4dea6 142 DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */
88b12a9a 143};
46ca84c4 144
88b12a9a
FMH
145static inline unsigned int dac_convert_reg(unsigned int channel)
146{
147 return 0x70 + (2 * (channel & 0x1));
148}
0a85b6f0 149
88b12a9a
FMH
150static inline unsigned int dac_lsb_4020_reg(unsigned int channel)
151{
152 return 0x70 + (4 * (channel & 0x1));
153}
0a85b6f0 154
88b12a9a
FMH
155static inline unsigned int dac_msb_4020_reg(unsigned int channel)
156{
157 return 0x72 + (4 * (channel & 0x1));
158}
159
160enum read_only_registers {
46ca84c4
IA
161 /* hardware status register,
162 * reading this apparently clears pending interrupts as well */
163 HW_STATUS_REG = 0x0,
88b12a9a
FMH
164 PIPE1_READ_REG = 0x4,
165 ADC_READ_PNTR_REG = 0x8,
166 LOWER_XFER_REG = 0x10,
167 ADC_WRITE_PNTR_REG = 0xc,
168 PREPOST_REG = 0x14,
169};
170
171enum read_write_registers {
9ef4dea6 172 I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */
46ca84c4
IA
173 /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */
174 ADC_QUEUE_FIFO_REG = 0x100,
88b12a9a 175 ADC_FIFO_REG = 0x200, /* adc data fifo */
46ca84c4
IA
176 /* dac data fifo, has weird interactions with external channel queue */
177 DAC_FIFO_REG = 0x300,
88b12a9a
FMH
178};
179
9ebd1028 180/* dev->mmio registers */
88b12a9a
FMH
181enum dio_counter_registers {
182 DIO_8255_OFFSET = 0x0,
183 DO_REG = 0x20,
184 DI_REG = 0x28,
185 DIO_DIRECTION_60XX_REG = 0x40,
186 DIO_DATA_60XX_REG = 0x48,
187};
188
9ef4dea6 189/* bit definitions for write-only registers */
88b12a9a
FMH
190
191enum intr_enable_contents {
46ca84c4
IA
192 ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */
193 ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */
9ef4dea6
BP
194 ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */
195 ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */
46ca84c4 196 ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */
9ef4dea6 197 EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */
46ca84c4 198 EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */
88b12a9a
FMH
199 DAC_INTR_SRC_MASK = 0x30,
200 DAC_INTR_QEMPTY_BITS = 0x0,
201 DAC_INTR_HIGH_CHAN_BITS = 0x10,
9ef4dea6 202 EN_DAC_INTR_SRC_BIT = 0x40, /* enable dac interrupt source */
88b12a9a 203 EN_DAC_DONE_INTR_BIT = 0x80,
9ef4dea6
BP
204 EN_ADC_ACTIVE_INTR_BIT = 0x200, /* enable adc active interrupt */
205 EN_ADC_STOP_INTR_BIT = 0x400, /* enable adc stop trigger interrupt */
206 EN_DAC_ACTIVE_INTR_BIT = 0x800, /* enable dac active interrupt */
207 EN_DAC_UNDERRUN_BIT = 0x4000, /* enable dac underrun status bit */
208 EN_ADC_OVERRUN_BIT = 0x8000, /* enable adc overrun status bit */
88b12a9a
FMH
209};
210
211enum hw_config_contents {
46ca84c4
IA
212 MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */
213 INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */
9ef4dea6
BP
214 BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */
215 EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */
46ca84c4
IA
216 EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */
217 /* use 225 nanosec strobe when loading dac instead of 50 nanosec */
218 SLOW_DAC_BIT = 0x400,
219 /* bit with unknown function yet given as default value in pci-das64
220 * manual */
221 HW_CONFIG_DUMMY_BITS = 0x2000,
222 /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */
223 DMA_CH_SELECT_BIT = 0x8000,
224 FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */
9ef4dea6 225 DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */
46ca84c4 226 DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
88b12a9a
FMH
227};
228#define DAC_FIFO_SIZE 0x2000
229
230enum daq_atrig_low_4020_contents {
46ca84c4
IA
231 /* use trig/ext clk bnc input for analog gate signal */
232 EXT_AGATE_BNC_BIT = 0x8000,
233 /* use trig/ext clk bnc input for external stop trigger signal */
234 EXT_STOP_TRIG_BNC_BIT = 0x4000,
235 /* use trig/ext clk bnc input for external start trigger signal */
236 EXT_START_TRIG_BNC_BIT = 0x2000,
88b12a9a 237};
46ca84c4 238
88b12a9a
FMH
239static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
240{
241 return threshold & 0xfff;
242}
243
244enum adc_control0_contents {
9ef4dea6
BP
245 ADC_GATE_SRC_MASK = 0x3, /* bits that select gate */
246 ADC_SOFT_GATE_BITS = 0x1, /* software gate */
247 ADC_EXT_GATE_BITS = 0x2, /* external digital gate */
248 ADC_ANALOG_GATE_BITS = 0x3, /* analog level gate */
249 ADC_GATE_LEVEL_BIT = 0x4, /* level-sensitive gate (for digital) */
250 ADC_GATE_POLARITY_BIT = 0x8, /* gate active low */
88b12a9a
FMH
251 ADC_START_TRIG_SOFT_BITS = 0x10,
252 ADC_START_TRIG_EXT_BITS = 0x20,
253 ADC_START_TRIG_ANALOG_BITS = 0x30,
254 ADC_START_TRIG_MASK = 0x30,
9ef4dea6 255 ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */
46ca84c4
IA
256 /* external pacing uses falling edge */
257 ADC_EXT_CONV_FALLING_BIT = 0x800,
258 /* enable hardware scan counter */
259 ADC_SAMPLE_COUNTER_EN_BIT = 0x1000,
9ef4dea6
BP
260 ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */
261 ADC_ENABLE_BIT = 0x8000, /* master adc enable */
88b12a9a
FMH
262};
263
264enum adc_control1_contents {
46ca84c4
IA
265 /* should be set for boards with > 16 channels */
266 ADC_QUEUE_CONFIG_BIT = 0x1,
88b12a9a
FMH
267 CONVERT_POLARITY_BIT = 0x10,
268 EOC_POLARITY_BIT = 0x20,
9ef4dea6
BP
269 ADC_SW_GATE_BIT = 0x40, /* software gate of adc */
270 ADC_DITHER_BIT = 0x200, /* turn on extra noise for dithering */
88b12a9a
FMH
271 RETRIGGER_BIT = 0x800,
272 ADC_LO_CHANNEL_4020_MASK = 0x300,
273 ADC_HI_CHANNEL_4020_MASK = 0xc00,
9ef4dea6 274 TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */
46ca84c4 275 FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */
88b12a9a
FMH
276 CHANNEL_MODE_4020_MASK = 0x3000,
277 ADC_MODE_MASK = 0xf000,
278};
46ca84c4 279
88b12a9a
FMH
280static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
281{
282 return (channel & 0x3) << 8;
283};
0a85b6f0 284
88b12a9a
FMH
285static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel)
286{
287 return (channel & 0x3) << 10;
288};
0a85b6f0 289
88b12a9a
FMH
290static inline uint16_t adc_mode_bits(unsigned int mode)
291{
292 return (mode & 0xf) << 12;
293};
294
295enum calibration_contents {
296 SELECT_8800_BIT = 0x1,
297 SELECT_8402_64XX_BIT = 0x2,
298 SELECT_1590_60XX_BIT = 0x2,
9ef4dea6 299 CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */
88b12a9a
FMH
300 SERIAL_DATA_IN_BIT = 0x80,
301 SERIAL_CLOCK_BIT = 0x100,
46ca84c4 302 CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */
88b12a9a
FMH
303 CAL_GAIN_BIT = 0x800,
304};
46ca84c4 305
88b12a9a
FMH
306/* calibration sources for 6025 are:
307 * 0 : ground
308 * 1 : 10V
309 * 2 : 5V
310 * 3 : 0.5V
311 * 4 : 0.05V
312 * 5 : ground
313 * 6 : dac channel 0
314 * 7 : dac channel 1
315 */
46ca84c4 316
88b12a9a
FMH
317static inline uint16_t adc_src_bits(unsigned int source)
318{
319 return (source & 0xf) << 3;
320};
321
322static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
323{
324 return (channel & 0x3) << 8;
325};
326
327enum adc_queue_load_contents {
9ef4dea6
BP
328 UNIP_BIT = 0x800, /* unipolar/bipolar bit */
329 ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */
46ca84c4
IA
330 /* non-referenced single-ended (common-mode input) */
331 ADC_COMMON_BIT = 0x2000,
9ef4dea6
BP
332 QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */
333 QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
88b12a9a 334};
46ca84c4 335
88b12a9a
FMH
336static inline uint16_t adc_chan_bits(unsigned int channel)
337{
338 return channel & 0x3f;
339};
340
341enum dac_control0_contents {
9ef4dea6 342 DAC_ENABLE_BIT = 0x8000, /* dac controller enable bit */
88b12a9a
FMH
343 DAC_CYCLIC_STOP_BIT = 0x4000,
344 DAC_WAVEFORM_MODE_BIT = 0x100,
345 DAC_EXT_UPDATE_FALLING_BIT = 0x80,
346 DAC_EXT_UPDATE_ENABLE_BIT = 0x40,
347 WAVEFORM_TRIG_MASK = 0x30,
348 WAVEFORM_TRIG_DISABLED_BITS = 0x0,
349 WAVEFORM_TRIG_SOFT_BITS = 0x10,
350 WAVEFORM_TRIG_EXT_BITS = 0x20,
351 WAVEFORM_TRIG_ADC1_BITS = 0x30,
352 WAVEFORM_TRIG_FALLING_BIT = 0x8,
353 WAVEFORM_GATE_LEVEL_BIT = 0x4,
354 WAVEFORM_GATE_ENABLE_BIT = 0x2,
355 WAVEFORM_GATE_SELECT_BIT = 0x1,
356};
357
358enum dac_control1_contents {
359 DAC_WRITE_POLARITY_BIT = 0x800, /* board-dependent setting */
360 DAC1_EXT_REF_BIT = 0x200,
361 DAC0_EXT_REF_BIT = 0x100,
9ef4dea6 362 DAC_OUTPUT_ENABLE_BIT = 0x80, /* dac output enable bit */
88b12a9a
FMH
363 DAC_UPDATE_POLARITY_BIT = 0x40, /* board-dependent setting */
364 DAC_SW_GATE_BIT = 0x20,
365 DAC1_UNIPOLAR_BIT = 0x8,
366 DAC0_UNIPOLAR_BIT = 0x2,
367};
368
9ef4dea6 369/* bit definitions for read-only registers */
88b12a9a
FMH
370enum hw_status_contents {
371 DAC_UNDERRUN_BIT = 0x1,
372 ADC_OVERRUN_BIT = 0x2,
373 DAC_ACTIVE_BIT = 0x4,
374 ADC_ACTIVE_BIT = 0x8,
375 DAC_INTR_PENDING_BIT = 0x10,
376 ADC_INTR_PENDING_BIT = 0x20,
377 DAC_DONE_BIT = 0x40,
378 ADC_DONE_BIT = 0x80,
379 EXT_INTR_PENDING_BIT = 0x100,
380 ADC_STOP_BIT = 0x200,
381};
46ca84c4 382
88b12a9a
FMH
383static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
384{
385 return (hw_status_bits >> 10) & 0x3;
386};
387
388static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits)
389{
390 return (prepost_bits >> 6) & 0x3;
391}
0a85b6f0 392
88b12a9a
FMH
393static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits)
394{
395 return (prepost_bits >> 12) & 0x3;
396}
0a85b6f0 397
88b12a9a
FMH
398static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits)
399{
400 return (prepost_bits >> 14) & 0x3;
401}
402
9ef4dea6 403/* I2C addresses for 4020 */
88b12a9a
FMH
404enum i2c_addresses {
405 RANGE_CAL_I2C_ADDR = 0x20,
406 CALDAC0_I2C_ADDR = 0xc,
407 CALDAC1_I2C_ADDR = 0xd,
408};
409
410enum range_cal_i2c_contents {
46ca84c4
IA
411 /* bits that set what source the adc converter measures */
412 ADC_SRC_4020_MASK = 0x70,
413 /* make bnc trig/ext clock threshold 0V instead of 2.5V */
414 BNC_TRIG_THRESHOLD_0V_BIT = 0x80,
88b12a9a 415};
46ca84c4 416
88b12a9a
FMH
417static inline uint8_t adc_src_4020_bits(unsigned int source)
418{
419 return (source << 4) & ADC_SRC_4020_MASK;
420};
0a85b6f0 421
88b12a9a
FMH
422static inline uint8_t attenuate_bit(unsigned int channel)
423{
9ef4dea6 424 /* attenuate channel (+-5V input range) */
88b12a9a
FMH
425 return 1 << (channel & 0x3);
426};
427
9ef4dea6 428/* analog input ranges for 64xx boards */
9ced1de6 429static const struct comedi_lrange ai_ranges_64xx = {
82dc1255
HS
430 8, {
431 BIP_RANGE(10),
432 BIP_RANGE(5),
433 BIP_RANGE(2.5),
434 BIP_RANGE(1.25),
435 UNI_RANGE(10),
436 UNI_RANGE(5),
437 UNI_RANGE(2.5),
438 UNI_RANGE(1.25)
439 }
88b12a9a
FMH
440};
441
442/* analog input ranges for 60xx boards */
9ced1de6 443static const struct comedi_lrange ai_ranges_60xx = {
82dc1255
HS
444 4, {
445 BIP_RANGE(10),
446 BIP_RANGE(5),
447 BIP_RANGE(0.5),
448 BIP_RANGE(0.05)
449 }
88b12a9a
FMH
450};
451
452/* analog input ranges for 6030, etc boards */
9ced1de6 453static const struct comedi_lrange ai_ranges_6030 = {
82dc1255
HS
454 14, {
455 BIP_RANGE(10),
456 BIP_RANGE(5),
457 BIP_RANGE(2),
458 BIP_RANGE(1),
459 BIP_RANGE(0.5),
460 BIP_RANGE(0.2),
461 BIP_RANGE(0.1),
462 UNI_RANGE(10),
463 UNI_RANGE(5),
464 UNI_RANGE(2),
465 UNI_RANGE(1),
466 UNI_RANGE(0.5),
467 UNI_RANGE(0.2),
468 UNI_RANGE(0.1)
469 }
88b12a9a
FMH
470};
471
472/* analog input ranges for 6052, etc boards */
9ced1de6 473static const struct comedi_lrange ai_ranges_6052 = {
82dc1255
HS
474 15, {
475 BIP_RANGE(10),
476 BIP_RANGE(5),
477 BIP_RANGE(2.5),
478 BIP_RANGE(1),
479 BIP_RANGE(0.5),
480 BIP_RANGE(0.25),
481 BIP_RANGE(0.1),
482 BIP_RANGE(0.05),
483 UNI_RANGE(10),
484 UNI_RANGE(5),
485 UNI_RANGE(2),
486 UNI_RANGE(1),
487 UNI_RANGE(0.5),
488 UNI_RANGE(0.2),
489 UNI_RANGE(0.1)
490 }
88b12a9a
FMH
491};
492
9ef4dea6 493/* analog input ranges for 4020 board */
9ced1de6 494static const struct comedi_lrange ai_ranges_4020 = {
82dc1255
HS
495 2, {
496 BIP_RANGE(5),
497 BIP_RANGE(1)
498 }
88b12a9a
FMH
499};
500
9ef4dea6 501/* analog output ranges */
9ced1de6 502static const struct comedi_lrange ao_ranges_64xx = {
82dc1255
HS
503 4, {
504 BIP_RANGE(5),
505 BIP_RANGE(10),
506 UNI_RANGE(5),
507 UNI_RANGE(10)
508 }
88b12a9a 509};
0a85b6f0 510
88b12a9a
FMH
511static const int ao_range_code_64xx[] = {
512 0x0,
513 0x1,
514 0x2,
515 0x3,
516};
517
88b12a9a
FMH
518static const int ao_range_code_60xx[] = {
519 0x0,
520};
521
9ced1de6 522static const struct comedi_lrange ao_ranges_6030 = {
82dc1255
HS
523 2, {
524 BIP_RANGE(10),
525 UNI_RANGE(10)
526 }
88b12a9a 527};
0a85b6f0 528
88b12a9a
FMH
529static const int ao_range_code_6030[] = {
530 0x0,
531 0x2,
532};
533
9ced1de6 534static const struct comedi_lrange ao_ranges_4020 = {
82dc1255
HS
535 2, {
536 BIP_RANGE(5),
537 BIP_RANGE(10)
538 }
88b12a9a 539};
0a85b6f0 540
88b12a9a
FMH
541static const int ao_range_code_4020[] = {
542 0x1,
543 0x0,
544};
545
546enum register_layout {
547 LAYOUT_60XX,
548 LAYOUT_64XX,
549 LAYOUT_4020,
550};
551
675935dd 552struct hw_fifo_info {
88b12a9a
FMH
553 unsigned int num_segments;
554 unsigned int max_segment_length;
555 unsigned int sample_packing_ratio;
556 uint16_t fifo_size_reg_mask;
675935dd 557};
88b12a9a 558
463740d4
HS
559enum pcidas64_boardid {
560 BOARD_PCIDAS6402_16,
561 BOARD_PCIDAS6402_12,
562 BOARD_PCIDAS64_M1_16,
563 BOARD_PCIDAS64_M2_16,
564 BOARD_PCIDAS64_M3_16,
565 BOARD_PCIDAS6013,
566 BOARD_PCIDAS6014,
567 BOARD_PCIDAS6023,
568 BOARD_PCIDAS6025,
569 BOARD_PCIDAS6030,
570 BOARD_PCIDAS6031,
571 BOARD_PCIDAS6032,
572 BOARD_PCIDAS6033,
573 BOARD_PCIDAS6034,
574 BOARD_PCIDAS6035,
575 BOARD_PCIDAS6036,
576 BOARD_PCIDAS6040,
577 BOARD_PCIDAS6052,
578 BOARD_PCIDAS6070,
579 BOARD_PCIDAS6071,
580 BOARD_PCIDAS4020_12,
581 BOARD_PCIDAS6402_16_JR,
582 BOARD_PCIDAS64_M1_16_JR,
583 BOARD_PCIDAS64_M2_16_JR,
584 BOARD_PCIDAS64_M3_16_JR,
585 BOARD_PCIDAS64_M1_14,
586 BOARD_PCIDAS64_M2_14,
587 BOARD_PCIDAS64_M3_14,
588};
589
222ab1bc 590struct pcidas64_board {
88b12a9a 591 const char *name;
9ef4dea6
BP
592 int ai_se_chans; /* number of ai inputs in single-ended mode */
593 int ai_bits; /* analog input resolution */
594 int ai_speed; /* fastest conversion period in ns */
9ced1de6 595 const struct comedi_lrange *ai_range_table;
9ef4dea6
BP
596 int ao_nchan; /* number of analog out channels */
597 int ao_bits; /* analog output resolution */
46ca84c4 598 int ao_scan_speed; /* analog output scan speed */
9ced1de6 599 const struct comedi_lrange *ao_range_table;
88b12a9a 600 const int *ao_range_code;
675935dd 601 const struct hw_fifo_info *const ai_fifo;
46ca84c4
IA
602 /* different board families have slightly different registers */
603 enum register_layout layout;
88b12a9a 604 unsigned has_8255:1;
222ab1bc 605};
88b12a9a 606
675935dd 607static const struct hw_fifo_info ai_fifo_4020 = {
68c3dbff
BP
608 .num_segments = 2,
609 .max_segment_length = 0x8000,
610 .sample_packing_ratio = 2,
611 .fifo_size_reg_mask = 0x7f,
88b12a9a
FMH
612};
613
675935dd 614static const struct hw_fifo_info ai_fifo_64xx = {
68c3dbff
BP
615 .num_segments = 4,
616 .max_segment_length = 0x800,
617 .sample_packing_ratio = 1,
618 .fifo_size_reg_mask = 0x3f,
88b12a9a
FMH
619};
620
675935dd 621static const struct hw_fifo_info ai_fifo_60xx = {
68c3dbff
BP
622 .num_segments = 4,
623 .max_segment_length = 0x800,
624 .sample_packing_ratio = 1,
625 .fifo_size_reg_mask = 0x7f,
88b12a9a
FMH
626};
627
628/* maximum number of dma transfers we will chain together into a ring
629 * (and the maximum number of dma buffers we maintain) */
630#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
631#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
632#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
b07244ce 633static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board)
88b12a9a
FMH
634{
635 if (board->layout == LAYOUT_4020)
636 return MAX_AI_DMA_RING_COUNT;
4ffeead3
HS
637
638 return MIN_AI_DMA_RING_COUNT;
88b12a9a
FMH
639}
640
641static const int bytes_in_sample = 2;
642
222ab1bc 643static const struct pcidas64_board pcidas64_boards[] = {
463740d4 644 [BOARD_PCIDAS6402_16] = {
2ccdb964
HS
645 .name = "pci-das6402/16",
646 .ai_se_chans = 64,
647 .ai_bits = 16,
648 .ai_speed = 5000,
649 .ao_nchan = 2,
650 .ao_bits = 16,
651 .ao_scan_speed = 10000,
652 .layout = LAYOUT_64XX,
653 .ai_range_table = &ai_ranges_64xx,
654 .ao_range_table = &ao_ranges_64xx,
655 .ao_range_code = ao_range_code_64xx,
656 .ai_fifo = &ai_fifo_64xx,
657 .has_8255 = 1,
658 },
463740d4 659 [BOARD_PCIDAS6402_12] = {
2ccdb964
HS
660 .name = "pci-das6402/12", /* XXX check */
661 .ai_se_chans = 64,
662 .ai_bits = 12,
663 .ai_speed = 5000,
664 .ao_nchan = 2,
665 .ao_bits = 12,
666 .ao_scan_speed = 10000,
667 .layout = LAYOUT_64XX,
668 .ai_range_table = &ai_ranges_64xx,
669 .ao_range_table = &ao_ranges_64xx,
670 .ao_range_code = ao_range_code_64xx,
671 .ai_fifo = &ai_fifo_64xx,
672 .has_8255 = 1,
673 },
463740d4 674 [BOARD_PCIDAS64_M1_16] = {
2ccdb964
HS
675 .name = "pci-das64/m1/16",
676 .ai_se_chans = 64,
677 .ai_bits = 16,
678 .ai_speed = 1000,
679 .ao_nchan = 2,
680 .ao_bits = 16,
681 .ao_scan_speed = 10000,
682 .layout = LAYOUT_64XX,
683 .ai_range_table = &ai_ranges_64xx,
684 .ao_range_table = &ao_ranges_64xx,
685 .ao_range_code = ao_range_code_64xx,
686 .ai_fifo = &ai_fifo_64xx,
687 .has_8255 = 1,
688 },
463740d4 689 [BOARD_PCIDAS64_M2_16] = {
2ccdb964
HS
690 .name = "pci-das64/m2/16",
691 .ai_se_chans = 64,
692 .ai_bits = 16,
693 .ai_speed = 500,
694 .ao_nchan = 2,
695 .ao_bits = 16,
696 .ao_scan_speed = 10000,
697 .layout = LAYOUT_64XX,
698 .ai_range_table = &ai_ranges_64xx,
699 .ao_range_table = &ao_ranges_64xx,
700 .ao_range_code = ao_range_code_64xx,
701 .ai_fifo = &ai_fifo_64xx,
702 .has_8255 = 1,
703 },
463740d4 704 [BOARD_PCIDAS64_M3_16] = {
2ccdb964
HS
705 .name = "pci-das64/m3/16",
706 .ai_se_chans = 64,
707 .ai_bits = 16,
708 .ai_speed = 333,
709 .ao_nchan = 2,
710 .ao_bits = 16,
711 .ao_scan_speed = 10000,
712 .layout = LAYOUT_64XX,
713 .ai_range_table = &ai_ranges_64xx,
714 .ao_range_table = &ao_ranges_64xx,
715 .ao_range_code = ao_range_code_64xx,
716 .ai_fifo = &ai_fifo_64xx,
717 .has_8255 = 1,
718 },
463740d4 719 [BOARD_PCIDAS6013] = {
2ccdb964
HS
720 .name = "pci-das6013",
721 .ai_se_chans = 16,
722 .ai_bits = 16,
723 .ai_speed = 5000,
724 .ao_nchan = 0,
725 .ao_bits = 16,
726 .layout = LAYOUT_60XX,
727 .ai_range_table = &ai_ranges_60xx,
7cf24bb4 728 .ao_range_table = &range_bipolar10,
2ccdb964
HS
729 .ao_range_code = ao_range_code_60xx,
730 .ai_fifo = &ai_fifo_60xx,
731 .has_8255 = 0,
732 },
463740d4 733 [BOARD_PCIDAS6014] = {
2ccdb964
HS
734 .name = "pci-das6014",
735 .ai_se_chans = 16,
736 .ai_bits = 16,
737 .ai_speed = 5000,
738 .ao_nchan = 2,
739 .ao_bits = 16,
740 .ao_scan_speed = 100000,
741 .layout = LAYOUT_60XX,
742 .ai_range_table = &ai_ranges_60xx,
7cf24bb4 743 .ao_range_table = &range_bipolar10,
2ccdb964
HS
744 .ao_range_code = ao_range_code_60xx,
745 .ai_fifo = &ai_fifo_60xx,
746 .has_8255 = 0,
747 },
463740d4 748 [BOARD_PCIDAS6023] = {
2ccdb964
HS
749 .name = "pci-das6023",
750 .ai_se_chans = 16,
751 .ai_bits = 12,
752 .ai_speed = 5000,
753 .ao_nchan = 0,
754 .ao_scan_speed = 100000,
755 .layout = LAYOUT_60XX,
756 .ai_range_table = &ai_ranges_60xx,
7cf24bb4 757 .ao_range_table = &range_bipolar10,
2ccdb964
HS
758 .ao_range_code = ao_range_code_60xx,
759 .ai_fifo = &ai_fifo_60xx,
760 .has_8255 = 1,
761 },
463740d4 762 [BOARD_PCIDAS6025] = {
2ccdb964
HS
763 .name = "pci-das6025",
764 .ai_se_chans = 16,
765 .ai_bits = 12,
766 .ai_speed = 5000,
767 .ao_nchan = 2,
768 .ao_bits = 12,
769 .ao_scan_speed = 100000,
770 .layout = LAYOUT_60XX,
771 .ai_range_table = &ai_ranges_60xx,
7cf24bb4 772 .ao_range_table = &range_bipolar10,
2ccdb964
HS
773 .ao_range_code = ao_range_code_60xx,
774 .ai_fifo = &ai_fifo_60xx,
775 .has_8255 = 1,
776 },
463740d4 777 [BOARD_PCIDAS6030] = {
2ccdb964
HS
778 .name = "pci-das6030",
779 .ai_se_chans = 16,
780 .ai_bits = 16,
781 .ai_speed = 10000,
782 .ao_nchan = 2,
783 .ao_bits = 16,
784 .ao_scan_speed = 10000,
785 .layout = LAYOUT_60XX,
786 .ai_range_table = &ai_ranges_6030,
787 .ao_range_table = &ao_ranges_6030,
788 .ao_range_code = ao_range_code_6030,
789 .ai_fifo = &ai_fifo_60xx,
790 .has_8255 = 0,
791 },
463740d4 792 [BOARD_PCIDAS6031] = {
2ccdb964
HS
793 .name = "pci-das6031",
794 .ai_se_chans = 64,
795 .ai_bits = 16,
796 .ai_speed = 10000,
797 .ao_nchan = 2,
798 .ao_bits = 16,
799 .ao_scan_speed = 10000,
800 .layout = LAYOUT_60XX,
801 .ai_range_table = &ai_ranges_6030,
802 .ao_range_table = &ao_ranges_6030,
803 .ao_range_code = ao_range_code_6030,
804 .ai_fifo = &ai_fifo_60xx,
805 .has_8255 = 0,
806 },
463740d4 807 [BOARD_PCIDAS6032] = {
2ccdb964
HS
808 .name = "pci-das6032",
809 .ai_se_chans = 16,
810 .ai_bits = 16,
811 .ai_speed = 10000,
812 .ao_nchan = 0,
813 .layout = LAYOUT_60XX,
814 .ai_range_table = &ai_ranges_6030,
815 .ai_fifo = &ai_fifo_60xx,
816 .has_8255 = 0,
817 },
463740d4 818 [BOARD_PCIDAS6033] = {
2ccdb964
HS
819 .name = "pci-das6033",
820 .ai_se_chans = 64,
821 .ai_bits = 16,
822 .ai_speed = 10000,
823 .ao_nchan = 0,
824 .layout = LAYOUT_60XX,
825 .ai_range_table = &ai_ranges_6030,
826 .ai_fifo = &ai_fifo_60xx,
827 .has_8255 = 0,
828 },
463740d4 829 [BOARD_PCIDAS6034] = {
2ccdb964
HS
830 .name = "pci-das6034",
831 .ai_se_chans = 16,
832 .ai_bits = 16,
833 .ai_speed = 5000,
834 .ao_nchan = 0,
835 .ao_scan_speed = 0,
836 .layout = LAYOUT_60XX,
837 .ai_range_table = &ai_ranges_60xx,
838 .ai_fifo = &ai_fifo_60xx,
839 .has_8255 = 0,
840 },
463740d4 841 [BOARD_PCIDAS6035] = {
2ccdb964
HS
842 .name = "pci-das6035",
843 .ai_se_chans = 16,
844 .ai_bits = 16,
845 .ai_speed = 5000,
846 .ao_nchan = 2,
847 .ao_bits = 12,
848 .ao_scan_speed = 100000,
849 .layout = LAYOUT_60XX,
850 .ai_range_table = &ai_ranges_60xx,
7cf24bb4 851 .ao_range_table = &range_bipolar10,
2ccdb964
HS
852 .ao_range_code = ao_range_code_60xx,
853 .ai_fifo = &ai_fifo_60xx,
854 .has_8255 = 0,
855 },
463740d4 856 [BOARD_PCIDAS6036] = {
2ccdb964
HS
857 .name = "pci-das6036",
858 .ai_se_chans = 16,
859 .ai_bits = 16,
860 .ai_speed = 5000,
861 .ao_nchan = 2,
862 .ao_bits = 16,
863 .ao_scan_speed = 100000,
864 .layout = LAYOUT_60XX,
865 .ai_range_table = &ai_ranges_60xx,
7cf24bb4 866 .ao_range_table = &range_bipolar10,
2ccdb964
HS
867 .ao_range_code = ao_range_code_60xx,
868 .ai_fifo = &ai_fifo_60xx,
869 .has_8255 = 0,
870 },
463740d4 871 [BOARD_PCIDAS6040] = {
2ccdb964
HS
872 .name = "pci-das6040",
873 .ai_se_chans = 16,
874 .ai_bits = 12,
875 .ai_speed = 2000,
876 .ao_nchan = 2,
877 .ao_bits = 12,
878 .ao_scan_speed = 1000,
879 .layout = LAYOUT_60XX,
880 .ai_range_table = &ai_ranges_6052,
881 .ao_range_table = &ao_ranges_6030,
882 .ao_range_code = ao_range_code_6030,
883 .ai_fifo = &ai_fifo_60xx,
884 .has_8255 = 0,
885 },
463740d4 886 [BOARD_PCIDAS6052] = {
2ccdb964
HS
887 .name = "pci-das6052",
888 .ai_se_chans = 16,
889 .ai_bits = 16,
890 .ai_speed = 3333,
891 .ao_nchan = 2,
892 .ao_bits = 16,
893 .ao_scan_speed = 3333,
894 .layout = LAYOUT_60XX,
895 .ai_range_table = &ai_ranges_6052,
896 .ao_range_table = &ao_ranges_6030,
897 .ao_range_code = ao_range_code_6030,
898 .ai_fifo = &ai_fifo_60xx,
899 .has_8255 = 0,
900 },
463740d4 901 [BOARD_PCIDAS6070] = {
2ccdb964
HS
902 .name = "pci-das6070",
903 .ai_se_chans = 16,
904 .ai_bits = 12,
905 .ai_speed = 800,
906 .ao_nchan = 2,
907 .ao_bits = 12,
908 .ao_scan_speed = 1000,
909 .layout = LAYOUT_60XX,
910 .ai_range_table = &ai_ranges_6052,
911 .ao_range_table = &ao_ranges_6030,
912 .ao_range_code = ao_range_code_6030,
913 .ai_fifo = &ai_fifo_60xx,
914 .has_8255 = 0,
915 },
463740d4 916 [BOARD_PCIDAS6071] = {
2ccdb964
HS
917 .name = "pci-das6071",
918 .ai_se_chans = 64,
919 .ai_bits = 12,
920 .ai_speed = 800,
921 .ao_nchan = 2,
922 .ao_bits = 12,
923 .ao_scan_speed = 1000,
924 .layout = LAYOUT_60XX,
925 .ai_range_table = &ai_ranges_6052,
926 .ao_range_table = &ao_ranges_6030,
927 .ao_range_code = ao_range_code_6030,
928 .ai_fifo = &ai_fifo_60xx,
929 .has_8255 = 0,
930 },
463740d4 931 [BOARD_PCIDAS4020_12] = {
2ccdb964
HS
932 .name = "pci-das4020/12",
933 .ai_se_chans = 4,
934 .ai_bits = 12,
935 .ai_speed = 50,
936 .ao_bits = 12,
937 .ao_nchan = 2,
938 .ao_scan_speed = 0, /* no hardware pacing on ao */
939 .layout = LAYOUT_4020,
940 .ai_range_table = &ai_ranges_4020,
941 .ao_range_table = &ao_ranges_4020,
942 .ao_range_code = ao_range_code_4020,
943 .ai_fifo = &ai_fifo_4020,
944 .has_8255 = 1,
945 },
88b12a9a 946#if 0
463740d4
HS
947 /*
948 * The device id for these boards is unknown
949 */
950
951 [BOARD_PCIDAS6402_16_JR] = {
2ccdb964
HS
952 .name = "pci-das6402/16/jr",
953 .ai_se_chans = 64,
954 .ai_bits = 16,
955 .ai_speed = 5000,
956 .ao_nchan = 0,
957 .ao_scan_speed = 10000,
958 .layout = LAYOUT_64XX,
959 .ai_range_table = &ai_ranges_64xx,
960 .ai_fifo = ai_fifo_64xx,
961 .has_8255 = 1,
962 },
463740d4 963 [BOARD_PCIDAS64_M1_16_JR] = {
2ccdb964
HS
964 .name = "pci-das64/m1/16/jr",
965 .ai_se_chans = 64,
966 .ai_bits = 16,
967 .ai_speed = 1000,
968 .ao_nchan = 0,
969 .ao_scan_speed = 10000,
970 .layout = LAYOUT_64XX,
971 .ai_range_table = &ai_ranges_64xx,
972 .ai_fifo = ai_fifo_64xx,
973 .has_8255 = 1,
974 },
463740d4 975 [BOARD_PCIDAS64_M2_16_JR] = {
2ccdb964
HS
976 .name = "pci-das64/m2/16/jr",
977 .ai_se_chans = 64,
978 .ai_bits = 16,
979 .ai_speed = 500,
980 .ao_nchan = 0,
981 .ao_scan_speed = 10000,
982 .layout = LAYOUT_64XX,
983 .ai_range_table = &ai_ranges_64xx,
984 .ai_fifo = ai_fifo_64xx,
985 .has_8255 = 1,
986 },
463740d4 987 [BOARD_PCIDAS64_M3_16_JR] = {
2ccdb964
HS
988 .name = "pci-das64/m3/16/jr",
989 .ai_se_chans = 64,
990 .ai_bits = 16,
991 .ai_speed = 333,
992 .ao_nchan = 0,
993 .ao_scan_speed = 10000,
994 .layout = LAYOUT_64XX,
995 .ai_range_table = &ai_ranges_64xx,
996 .ai_fifo = ai_fifo_64xx,
997 .has_8255 = 1,
998 },
463740d4 999 [BOARD_PCIDAS64_M1_14] = {
2ccdb964
HS
1000 .name = "pci-das64/m1/14",
1001 .ai_se_chans = 64,
1002 .ai_bits = 14,
1003 .ai_speed = 1000,
1004 .ao_nchan = 2,
1005 .ao_scan_speed = 10000,
1006 .layout = LAYOUT_64XX,
1007 .ai_range_table = &ai_ranges_64xx,
1008 .ai_fifo = ai_fifo_64xx,
1009 .has_8255 = 1,
1010 },
463740d4 1011 [BOARD_PCIDAS64_M2_14] = {
2ccdb964
HS
1012 .name = "pci-das64/m2/14",
1013 .ai_se_chans = 64,
1014 .ai_bits = 14,
1015 .ai_speed = 500,
1016 .ao_nchan = 2,
1017 .ao_scan_speed = 10000,
1018 .layout = LAYOUT_64XX,
1019 .ai_range_table = &ai_ranges_64xx,
1020 .ai_fifo = ai_fifo_64xx,
1021 .has_8255 = 1,
1022 },
463740d4 1023 [BOARD_PCIDAS64_M3_14] = {
2ccdb964
HS
1024 .name = "pci-das64/m3/14",
1025 .ai_se_chans = 64,
1026 .ai_bits = 14,
1027 .ai_speed = 333,
1028 .ao_nchan = 2,
1029 .ao_scan_speed = 10000,
1030 .layout = LAYOUT_64XX,
1031 .ai_range_table = &ai_ranges_64xx,
1032 .ai_fifo = ai_fifo_64xx,
1033 .has_8255 = 1,
1034 },
88b12a9a
FMH
1035#endif
1036};
1037
da91b269 1038static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
0a85b6f0 1039 int use_differential)
88b12a9a 1040{
3bc86feb 1041 const struct pcidas64_board *thisboard = dev->board_ptr;
b07244ce
IA
1042
1043 if ((thisboard->layout == LAYOUT_64XX && !use_differential) ||
1044 (thisboard->layout == LAYOUT_60XX && use_differential))
88b12a9a 1045 return ADC_SE_DIFF_BIT;
4ffeead3
HS
1046
1047 return 0;
1048}
88b12a9a
FMH
1049
1050struct ext_clock_info {
46ca84c4
IA
1051 /* master clock divisor to use for scans with external master clock */
1052 unsigned int divisor;
1053 /* chanspec for master clock input when used as scan begin src */
1054 unsigned int chanspec;
88b12a9a
FMH
1055};
1056
1057/* this structure is for data unique to this hardware driver. */
450032a3 1058struct pcidas64_private {
9ef4dea6 1059 /* base addresses (physical) */
88b12a9a
FMH
1060 resource_size_t main_phys_iobase;
1061 resource_size_t dio_counter_phys_iobase;
9ef4dea6 1062 /* base addresses (ioremapped) */
f31d0008
GKH
1063 void __iomem *plx9080_iobase;
1064 void __iomem *main_iobase;
9ef4dea6 1065 /* local address (used by dma controller) */
88b12a9a
FMH
1066 uint32_t local0_iobase;
1067 uint32_t local1_iobase;
46ca84c4 1068 /* number of analog input samples remaining */
0f99981a 1069 unsigned int ai_count;
46ca84c4
IA
1070 /* dma buffers for analog input */
1071 uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
1072 /* physical addresses of ai dma buffers */
1073 dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT];
1074 /* array of ai dma descriptors read by plx9080,
1075 * allocated to get proper alignment */
1076 struct plx_dma_desc *ai_dma_desc;
1077 /* physical address of ai dma descriptor array */
1078 dma_addr_t ai_dma_desc_bus_addr;
1079 /* index of the ai dma descriptor/buffer
1080 * that is currently being used */
0f99981a 1081 unsigned int ai_dma_index;
46ca84c4
IA
1082 /* dma buffers for analog output */
1083 uint16_t *ao_buffer[AO_DMA_RING_COUNT];
1084 /* physical addresses of ao dma buffers */
1085 dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT];
88b12a9a
FMH
1086 struct plx_dma_desc *ao_dma_desc;
1087 dma_addr_t ao_dma_desc_bus_addr;
46ca84c4 1088 /* keeps track of buffer where the next ao sample should go */
0f99981a 1089 unsigned int ao_dma_index;
46ca84c4 1090 /* number of analog output samples remaining */
0f99981a 1091 unsigned long ao_count;
9ef4dea6 1092 unsigned int hw_revision; /* stc chip hardware revision number */
46ca84c4 1093 /* last bits sent to INTR_ENABLE_REG register */
0f99981a 1094 unsigned int intr_enable_bits;
46ca84c4 1095 /* last bits sent to ADC_CONTROL1_REG register */
0f99981a 1096 uint16_t adc_control1_bits;
46ca84c4 1097 /* last bits sent to FIFO_SIZE_REG register */
0f99981a 1098 uint16_t fifo_size_bits;
46ca84c4 1099 /* last bits sent to HW_CONFIG_REG register */
0f99981a
HS
1100 uint16_t hw_config_bits;
1101 uint16_t dac_control1_bits;
46ca84c4 1102 /* last bits written to plx9080 control register */
0f99981a 1103 uint32_t plx_control_bits;
46ca84c4 1104 /* last bits written to plx interrupt control and status register */
0f99981a 1105 uint32_t plx_intcsr_bits;
46ca84c4 1106 /* index of calibration source readable through ai ch0 */
0f99981a 1107 int calibration_source;
46ca84c4 1108 /* bits written to i2c calibration/range register */
0f99981a 1109 uint8_t i2c_cal_range_bits;
46ca84c4 1110 /* configure digital triggers to trigger on falling edge */
0f99981a 1111 unsigned int ext_trig_falling;
9ef4dea6 1112 /* states of various devices stored to enable read-back */
88b12a9a
FMH
1113 unsigned int ad8402_state[2];
1114 unsigned int caldac_state[8];
0f99981a 1115 short ai_cmd_running;
88b12a9a
FMH
1116 unsigned int ai_fifo_segment_length;
1117 struct ext_clock_info ext_clock;
05220638 1118 unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
450032a3
BP
1119};
1120
814900c9 1121static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
0a85b6f0 1122 unsigned int range_index)
88b12a9a 1123{
3bc86feb 1124 const struct pcidas64_board *thisboard = dev->board_ptr;
1f6325d6 1125 const struct comedi_krange *range =
b07244ce 1126 &thisboard->ai_range_table->range[range_index];
88b12a9a
FMH
1127 unsigned int bits = 0;
1128
1129 switch (range->max) {
1130 case 10000000:
1131 bits = 0x000;
1132 break;
1133 case 5000000:
1134 bits = 0x100;
1135 break;
1136 case 2000000:
1137 case 2500000:
1138 bits = 0x200;
1139 break;
1140 case 1000000:
1141 case 1250000:
1142 bits = 0x300;
1143 break;
1144 case 500000:
1145 bits = 0x400;
1146 break;
1147 case 200000:
1148 case 250000:
1149 bits = 0x500;
1150 break;
1151 case 100000:
1152 bits = 0x600;
1153 break;
1154 case 50000:
1155 bits = 0x700;
1156 break;
1157 default:
e176d78c 1158 dev_err(dev->class_dev, "bug! in %s\n", __func__);
88b12a9a
FMH
1159 break;
1160 }
1161 if (range->min == 0)
1162 bits += 0x900;
1163 return bits;
1164}
1165
da91b269 1166static unsigned int hw_revision(const struct comedi_device *dev,
0a85b6f0 1167 uint16_t hw_status_bits)
88b12a9a 1168{
3bc86feb 1169 const struct pcidas64_board *thisboard = dev->board_ptr;
b07244ce
IA
1170
1171 if (thisboard->layout == LAYOUT_4020)
88b12a9a
FMH
1172 return (hw_status_bits >> 13) & 0x7;
1173
1174 return (hw_status_bits >> 12) & 0xf;
1175}
1176
0a85b6f0 1177static void set_dac_range_bits(struct comedi_device *dev,
350a3276 1178 uint16_t *bits, unsigned int channel,
0a85b6f0 1179 unsigned int range)
88b12a9a 1180{
3bc86feb 1181 const struct pcidas64_board *thisboard = dev->board_ptr;
b07244ce 1182 unsigned int code = thisboard->ao_range_code[range];
88b12a9a
FMH
1183
1184 if (channel > 1)
e176d78c 1185 dev_err(dev->class_dev, "bug! bad channel?\n");
88b12a9a 1186 if (code & ~0x3)
e176d78c 1187 dev_err(dev->class_dev, "bug! bad range code?\n");
88b12a9a
FMH
1188
1189 *bits &= ~(0x3 << (2 * channel));
1190 *bits |= code << (2 * channel);
1191};
1192
da91b269 1193static inline int ao_cmd_is_supported(const struct pcidas64_board *board)
88b12a9a
FMH
1194{
1195 return board->ao_nchan && board->layout != LAYOUT_4020;
1196}
1197
012e642c
IA
1198static void abort_dma(struct comedi_device *dev, unsigned int channel)
1199{
1200 struct pcidas64_private *devpriv = dev->private;
1201 unsigned long flags;
1202
1203 /* spinlock for plx dma control/status reg */
1204 spin_lock_irqsave(&dev->spinlock, flags);
1205
1206 plx9080_abort_dma(devpriv->plx9080_iobase, channel);
1207
1208 spin_unlock_irqrestore(&dev->spinlock, flags);
1209}
1210
dd379fa2
IA
1211static void disable_plx_interrupts(struct comedi_device *dev)
1212{
1213 struct pcidas64_private *devpriv = dev->private;
1214
1215 devpriv->plx_intcsr_bits = 0;
1216 writel(devpriv->plx_intcsr_bits,
1217 devpriv->plx9080_iobase + PLX_INTRCS_REG);
1218}
1219
1220static void disable_ai_interrupts(struct comedi_device *dev)
1221{
1222 struct pcidas64_private *devpriv = dev->private;
1223 unsigned long flags;
1224
1225 spin_lock_irqsave(&dev->spinlock, flags);
1226 devpriv->intr_enable_bits &=
1227 ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
1228 ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
1229 ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
1230 writew(devpriv->intr_enable_bits,
1231 devpriv->main_iobase + INTR_ENABLE_REG);
1232 spin_unlock_irqrestore(&dev->spinlock, flags);
dd379fa2
IA
1233}
1234
1235static void enable_ai_interrupts(struct comedi_device *dev,
1236 const struct comedi_cmd *cmd)
1237{
3bc86feb 1238 const struct pcidas64_board *thisboard = dev->board_ptr;
dd379fa2
IA
1239 struct pcidas64_private *devpriv = dev->private;
1240 uint32_t bits;
1241 unsigned long flags;
1242
1243 bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
1244 EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
1245 /* Use pio transfer and interrupt on end of conversion
0ad08e4b
IA
1246 * if CMDF_WAKE_EOS flag is set. */
1247 if (cmd->flags & CMDF_WAKE_EOS) {
dd379fa2
IA
1248 /* 4020 doesn't support pio transfers except for fifo dregs */
1249 if (thisboard->layout != LAYOUT_4020)
1250 bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
1251 }
1252 spin_lock_irqsave(&dev->spinlock, flags);
1253 devpriv->intr_enable_bits |= bits;
1254 writew(devpriv->intr_enable_bits,
1255 devpriv->main_iobase + INTR_ENABLE_REG);
dd379fa2
IA
1256 spin_unlock_irqrestore(&dev->spinlock, flags);
1257}
1258
9ef4dea6 1259/* initialize plx9080 chip */
da91b269 1260static void init_plx9080(struct comedi_device *dev)
88b12a9a 1261{
3bc86feb 1262 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 1263 struct pcidas64_private *devpriv = dev->private;
88b12a9a 1264 uint32_t bits;
681d335a 1265 void __iomem *plx_iobase = devpriv->plx9080_iobase;
88b12a9a 1266
681d335a 1267 devpriv->plx_control_bits =
46ca84c4 1268 readl(devpriv->plx9080_iobase + PLX_CONTROL_REG);
88b12a9a 1269
88b12a9a
FMH
1270#ifdef __BIG_ENDIAN
1271 bits = BIGEND_DMA0 | BIGEND_DMA1;
1272#else
1273 bits = 0;
1274#endif
681d335a 1275 writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG);
88b12a9a
FMH
1276
1277 disable_plx_interrupts(dev);
1278
1279 abort_dma(dev, 0);
1280 abort_dma(dev, 1);
1281
9ef4dea6 1282 /* configure dma0 mode */
88b12a9a 1283 bits = 0;
9ef4dea6 1284 /* enable ready input, not sure if this is necessary */
88b12a9a 1285 bits |= PLX_DMA_EN_READYIN_BIT;
9ef4dea6 1286 /* enable bterm, not sure if this is necessary */
88b12a9a 1287 bits |= PLX_EN_BTERM_BIT;
9ef4dea6 1288 /* enable dma chaining */
88b12a9a 1289 bits |= PLX_EN_CHAIN_BIT;
46ca84c4
IA
1290 /* enable interrupt on dma done
1291 * (probably don't need this, since chain never finishes) */
88b12a9a 1292 bits |= PLX_EN_DMA_DONE_INTR_BIT;
46ca84c4
IA
1293 /* don't increment local address during transfers
1294 * (we are transferring from a fixed fifo register) */
88b12a9a 1295 bits |= PLX_LOCAL_ADDR_CONST_BIT;
9ef4dea6 1296 /* route dma interrupt to pci bus */
88b12a9a 1297 bits |= PLX_DMA_INTR_PCI_BIT;
9ef4dea6 1298 /* enable demand mode */
88b12a9a 1299 bits |= PLX_DEMAND_MODE_BIT;
9ef4dea6 1300 /* enable local burst mode */
88b12a9a 1301 bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
9ef4dea6 1302 /* 4020 uses 32 bit dma */
b07244ce 1303 if (thisboard->layout == LAYOUT_4020)
88b12a9a 1304 bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
46ca84c4 1305 else /* localspace0 bus is 16 bits wide */
88b12a9a 1306 bits |= PLX_LOCAL_BUS_16_WIDE_BITS;
88b12a9a 1307 writel(bits, plx_iobase + PLX_DMA1_MODE_REG);
b07244ce 1308 if (ao_cmd_is_supported(thisboard))
88b12a9a
FMH
1309 writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
1310
9ef4dea6 1311 /* enable interrupts on plx 9080 */
681d335a 1312 devpriv->plx_intcsr_bits |=
0a85b6f0
MT
1313 ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
1314 ICS_DMA0_E | ICS_DMA1_E;
681d335a
HS
1315 writel(devpriv->plx_intcsr_bits,
1316 devpriv->plx9080_iobase + PLX_INTRCS_REG);
88b12a9a
FMH
1317}
1318
012e642c
IA
1319static void disable_ai_pacing(struct comedi_device *dev)
1320{
1321 struct pcidas64_private *devpriv = dev->private;
1322 unsigned long flags;
1323
1324 disable_ai_interrupts(dev);
1325
1326 spin_lock_irqsave(&dev->spinlock, flags);
1327 devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT;
1328 writew(devpriv->adc_control1_bits,
1329 devpriv->main_iobase + ADC_CONTROL1_REG);
1330 spin_unlock_irqrestore(&dev->spinlock, flags);
1331
1332 /* disable pacing, triggering, etc */
1333 writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
1334 devpriv->main_iobase + ADC_CONTROL0_REG);
1335}
1336
dd379fa2
IA
1337static int set_ai_fifo_segment_length(struct comedi_device *dev,
1338 unsigned int num_entries)
1339{
3bc86feb 1340 const struct pcidas64_board *thisboard = dev->board_ptr;
dd379fa2
IA
1341 struct pcidas64_private *devpriv = dev->private;
1342 static const int increment_size = 0x100;
1343 const struct hw_fifo_info *const fifo = thisboard->ai_fifo;
1344 unsigned int num_increments;
1345 uint16_t bits;
1346
1347 if (num_entries < increment_size)
1348 num_entries = increment_size;
1349 if (num_entries > fifo->max_segment_length)
1350 num_entries = fifo->max_segment_length;
1351
1352 /* 1 == 256 entries, 2 == 512 entries, etc */
1353 num_increments = (num_entries + increment_size / 2) / increment_size;
1354
1355 bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
1356 devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
1357 devpriv->fifo_size_bits |= bits;
1358 writew(devpriv->fifo_size_bits,
1359 devpriv->main_iobase + FIFO_SIZE_REG);
1360
1361 devpriv->ai_fifo_segment_length = num_increments * increment_size;
1362
dd379fa2
IA
1363 return devpriv->ai_fifo_segment_length;
1364}
1365
1366/* adjusts the size of hardware fifo (which determines block size for dma xfers) */
1367static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
1368{
3bc86feb 1369 const struct pcidas64_board *thisboard = dev->board_ptr;
dd379fa2
IA
1370 unsigned int num_fifo_entries;
1371 int retval;
1372 const struct hw_fifo_info *const fifo = thisboard->ai_fifo;
1373
1374 num_fifo_entries = num_samples / fifo->sample_packing_ratio;
1375
1376 retval = set_ai_fifo_segment_length(dev,
1377 num_fifo_entries /
1378 fifo->num_segments);
1379 if (retval < 0)
1380 return retval;
1381
1382 num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
1383
dd379fa2
IA
1384 return num_samples;
1385}
1386
1387/* query length of fifo */
1388static unsigned int ai_fifo_size(struct comedi_device *dev)
1389{
3bc86feb 1390 const struct pcidas64_board *thisboard = dev->board_ptr;
dd379fa2
IA
1391 struct pcidas64_private *devpriv = dev->private;
1392
1393 return devpriv->ai_fifo_segment_length *
1394 thisboard->ai_fifo->num_segments *
1395 thisboard->ai_fifo->sample_packing_ratio;
1396}
1397
da91b269 1398static void init_stc_registers(struct comedi_device *dev)
88b12a9a 1399{
3bc86feb 1400 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 1401 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
1402 uint16_t bits;
1403 unsigned long flags;
1404
5f74ea14 1405 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 1406
46ca84c4
IA
1407 /* bit should be set for 6025,
1408 * although docs say boards with <= 16 chans should be cleared XXX */
88b12a9a 1409 if (1)
681d335a
HS
1410 devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
1411 writew(devpriv->adc_control1_bits,
1412 devpriv->main_iobase + ADC_CONTROL1_REG);
88b12a9a 1413
9ef4dea6 1414 /* 6402/16 manual says this register must be initialized to 0xff? */
681d335a 1415 writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
88b12a9a
FMH
1416
1417 bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
b07244ce 1418 if (thisboard->layout == LAYOUT_4020)
88b12a9a 1419 bits |= INTERNAL_CLOCK_4020_BITS;
681d335a
HS
1420 devpriv->hw_config_bits |= bits;
1421 writew(devpriv->hw_config_bits,
1422 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a 1423
681d335a
HS
1424 writew(0, devpriv->main_iobase + DAQ_SYNC_REG);
1425 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a 1426
5f74ea14 1427 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 1428
9ef4dea6 1429 /* set fifos to maximum size */
681d335a 1430 devpriv->fifo_size_bits |= DAC_FIFO_BITS;
88b12a9a 1431 set_ai_fifo_segment_length(dev,
b07244ce 1432 thisboard->ai_fifo->max_segment_length);
88b12a9a 1433
681d335a 1434 devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
46ca84c4
IA
1435 devpriv->intr_enable_bits =
1436 /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
1437 EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
681d335a
HS
1438 writew(devpriv->intr_enable_bits,
1439 devpriv->main_iobase + INTR_ENABLE_REG);
88b12a9a
FMH
1440
1441 disable_ai_pacing(dev);
1442};
1443
f31d0008 1444static int alloc_and_init_dma_members(struct comedi_device *dev)
88b12a9a 1445{
3bc86feb 1446 const struct pcidas64_board *thisboard = dev->board_ptr;
000e2635 1447 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
681d335a 1448 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
1449 int i;
1450
20ce161d 1451 /* allocate pci dma buffers */
b07244ce 1452 for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
681d335a 1453 devpriv->ai_buffer[i] =
46ca84c4
IA
1454 pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
1455 &devpriv->ai_buffer_bus_addr[i]);
681d335a 1456 if (devpriv->ai_buffer[i] == NULL)
88b12a9a 1457 return -ENOMEM;
90cae794 1458
88b12a9a
FMH
1459 }
1460 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
b07244ce 1461 if (ao_cmd_is_supported(thisboard)) {
681d335a 1462 devpriv->ao_buffer[i] =
46ca84c4
IA
1463 pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
1464 &devpriv->
1465 ao_buffer_bus_addr[i]);
681d335a 1466 if (devpriv->ao_buffer[i] == NULL)
88b12a9a 1467 return -ENOMEM;
90cae794 1468
88b12a9a
FMH
1469 }
1470 }
9ef4dea6 1471 /* allocate dma descriptors */
681d335a 1472 devpriv->ai_dma_desc =
46ca84c4 1473 pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) *
b07244ce 1474 ai_dma_ring_count(thisboard),
46ca84c4 1475 &devpriv->ai_dma_desc_bus_addr);
681d335a 1476 if (devpriv->ai_dma_desc == NULL)
88b12a9a 1477 return -ENOMEM;
90cae794 1478
b07244ce 1479 if (ao_cmd_is_supported(thisboard)) {
681d335a 1480 devpriv->ao_dma_desc =
46ca84c4
IA
1481 pci_alloc_consistent(pcidev,
1482 sizeof(struct plx_dma_desc) *
1483 AO_DMA_RING_COUNT,
1484 &devpriv->ao_dma_desc_bus_addr);
681d335a 1485 if (devpriv->ao_dma_desc == NULL)
88b12a9a 1486 return -ENOMEM;
88b12a9a 1487 }
9ef4dea6 1488 /* initialize dma descriptors */
b07244ce 1489 for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
681d335a 1490 devpriv->ai_dma_desc[i].pci_start_addr =
46ca84c4 1491 cpu_to_le32(devpriv->ai_buffer_bus_addr[i]);
b07244ce 1492 if (thisboard->layout == LAYOUT_4020)
681d335a 1493 devpriv->ai_dma_desc[i].local_start_addr =
46ca84c4
IA
1494 cpu_to_le32(devpriv->local1_iobase +
1495 ADC_FIFO_REG);
88b12a9a 1496 else
681d335a 1497 devpriv->ai_dma_desc[i].local_start_addr =
46ca84c4
IA
1498 cpu_to_le32(devpriv->local0_iobase +
1499 ADC_FIFO_REG);
681d335a
HS
1500 devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
1501 devpriv->ai_dma_desc[i].next =
46ca84c4 1502 cpu_to_le32((devpriv->ai_dma_desc_bus_addr +
b07244ce 1503 ((i + 1) % ai_dma_ring_count(thisboard)) *
46ca84c4
IA
1504 sizeof(devpriv->ai_dma_desc[0])) |
1505 PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
1506 PLX_XFER_LOCAL_TO_PCI);
88b12a9a 1507 }
b07244ce 1508 if (ao_cmd_is_supported(thisboard)) {
88b12a9a 1509 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
681d335a 1510 devpriv->ao_dma_desc[i].pci_start_addr =
46ca84c4 1511 cpu_to_le32(devpriv->ao_buffer_bus_addr[i]);
681d335a 1512 devpriv->ao_dma_desc[i].local_start_addr =
46ca84c4
IA
1513 cpu_to_le32(devpriv->local0_iobase +
1514 DAC_FIFO_REG);
1515 devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0);
681d335a 1516 devpriv->ao_dma_desc[i].next =
46ca84c4
IA
1517 cpu_to_le32((devpriv->ao_dma_desc_bus_addr +
1518 ((i + 1) % (AO_DMA_RING_COUNT)) *
1519 sizeof(devpriv->ao_dma_desc[0])) |
1520 PLX_DESC_IN_PCI_BIT |
1521 PLX_INTR_TERM_COUNT);
88b12a9a
FMH
1522 }
1523 }
1524 return 0;
1525}
1526
f9804323
HS
1527static void cb_pcidas64_free_dma(struct comedi_device *dev)
1528{
3bc86feb 1529 const struct pcidas64_board *thisboard = dev->board_ptr;
f9804323
HS
1530 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1531 struct pcidas64_private *devpriv = dev->private;
1532 int i;
1533
1534 if (!devpriv)
1535 return;
1536
1537 /* free pci dma buffers */
1538 for (i = 0; i < ai_dma_ring_count(thisboard); i++) {
1539 if (devpriv->ai_buffer[i])
1540 pci_free_consistent(pcidev,
1541 DMA_BUFFER_SIZE,
1542 devpriv->ai_buffer[i],
1543 devpriv->ai_buffer_bus_addr[i]);
1544 }
1545 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
1546 if (devpriv->ao_buffer[i])
1547 pci_free_consistent(pcidev,
1548 DMA_BUFFER_SIZE,
1549 devpriv->ao_buffer[i],
1550 devpriv->ao_buffer_bus_addr[i]);
1551 }
1552 /* free dma descriptors */
1553 if (devpriv->ai_dma_desc)
1554 pci_free_consistent(pcidev,
1555 sizeof(struct plx_dma_desc) *
1556 ai_dma_ring_count(thisboard),
1557 devpriv->ai_dma_desc,
1558 devpriv->ai_dma_desc_bus_addr);
1559 if (devpriv->ao_dma_desc)
1560 pci_free_consistent(pcidev,
1561 sizeof(struct plx_dma_desc) *
1562 AO_DMA_RING_COUNT,
1563 devpriv->ao_dma_desc,
1564 devpriv->ao_dma_desc_bus_addr);
1565}
1566
da91b269 1567static inline void warn_external_queue(struct comedi_device *dev)
88b12a9a 1568{
e176d78c
HS
1569 dev_err(dev->class_dev,
1570 "AO command and AI external channel queue cannot be used simultaneously\n");
1571 dev_err(dev->class_dev,
1572 "Use internal AI channel queue (channels must be consecutive and use same range/aref)\n");
88b12a9a
FMH
1573}
1574
012e642c
IA
1575/* Their i2c requires a huge delay on setting clock or data high for some reason */
1576static const int i2c_high_udelay = 1000;
1577static const int i2c_low_udelay = 10;
1578
1579/* set i2c data line high or low */
1580static void i2c_set_sda(struct comedi_device *dev, int state)
1581{
1582 struct pcidas64_private *devpriv = dev->private;
1583 static const int data_bit = CTL_EE_W;
1584 void __iomem *plx_control_addr = devpriv->plx9080_iobase +
1585 PLX_CONTROL_REG;
1586
1587 if (state) {
1588 /* set data line high */
1589 devpriv->plx_control_bits &= ~data_bit;
1590 writel(devpriv->plx_control_bits, plx_control_addr);
1591 udelay(i2c_high_udelay);
1592 } else { /* set data line low */
1593
1594 devpriv->plx_control_bits |= data_bit;
1595 writel(devpriv->plx_control_bits, plx_control_addr);
1596 udelay(i2c_low_udelay);
1597 }
1598}
1599
1600/* set i2c clock line high or low */
1601static void i2c_set_scl(struct comedi_device *dev, int state)
1602{
1603 struct pcidas64_private *devpriv = dev->private;
1604 static const int clock_bit = CTL_USERO;
1605 void __iomem *plx_control_addr = devpriv->plx9080_iobase +
1606 PLX_CONTROL_REG;
1607
1608 if (state) {
1609 /* set clock line high */
1610 devpriv->plx_control_bits &= ~clock_bit;
1611 writel(devpriv->plx_control_bits, plx_control_addr);
1612 udelay(i2c_high_udelay);
1613 } else { /* set clock line low */
1614
1615 devpriv->plx_control_bits |= clock_bit;
1616 writel(devpriv->plx_control_bits, plx_control_addr);
1617 udelay(i2c_low_udelay);
1618 }
1619}
1620
1621static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
1622{
1623 uint8_t bit;
1624 unsigned int num_bits = 8;
1625
012e642c
IA
1626 for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
1627 i2c_set_scl(dev, 0);
1628 if ((byte & bit))
1629 i2c_set_sda(dev, 1);
1630 else
1631 i2c_set_sda(dev, 0);
1632 i2c_set_scl(dev, 1);
1633 }
1634}
1635
1636/* we can't really read the lines, so fake it */
1637static int i2c_read_ack(struct comedi_device *dev)
1638{
1639 i2c_set_scl(dev, 0);
1640 i2c_set_sda(dev, 1);
1641 i2c_set_scl(dev, 1);
1642
1643 return 0; /* return fake acknowledge bit */
1644}
1645
1646/* send start bit */
1647static void i2c_start(struct comedi_device *dev)
1648{
1649 i2c_set_scl(dev, 1);
1650 i2c_set_sda(dev, 1);
1651 i2c_set_sda(dev, 0);
1652}
1653
1654/* send stop bit */
1655static void i2c_stop(struct comedi_device *dev)
1656{
1657 i2c_set_scl(dev, 0);
1658 i2c_set_sda(dev, 0);
1659 i2c_set_scl(dev, 1);
1660 i2c_set_sda(dev, 1);
1661}
1662
1663static void i2c_write(struct comedi_device *dev, unsigned int address,
1664 const uint8_t *data, unsigned int length)
1665{
1666 struct pcidas64_private *devpriv = dev->private;
1667 unsigned int i;
1668 uint8_t bitstream;
1669 static const int read_bit = 0x1;
1670
1671 /* XXX need mutex to prevent simultaneous attempts to access
1672 * eeprom and i2c bus */
1673
1674 /* make sure we dont send anything to eeprom */
1675 devpriv->plx_control_bits &= ~CTL_EE_CS;
1676
1677 i2c_stop(dev);
1678 i2c_start(dev);
1679
1680 /* send address and write bit */
1681 bitstream = (address << 1) & ~read_bit;
1682 i2c_write_byte(dev, bitstream);
1683
1684 /* get acknowledge */
1685 if (i2c_read_ack(dev) != 0) {
e176d78c
HS
1686 dev_err(dev->class_dev, "%s failed: no acknowledge\n",
1687 __func__);
012e642c
IA
1688 i2c_stop(dev);
1689 return;
1690 }
1691 /* write data bytes */
1692 for (i = 0; i < length; i++) {
1693 i2c_write_byte(dev, data[i]);
1694 if (i2c_read_ack(dev) != 0) {
e176d78c
HS
1695 dev_err(dev->class_dev, "%s failed: no acknowledge\n",
1696 __func__);
012e642c
IA
1697 i2c_stop(dev);
1698 return;
1699 }
1700 }
1701 i2c_stop(dev);
1702}
1703
96ed0850
HS
1704static int cb_pcidas64_ai_eoc(struct comedi_device *dev,
1705 struct comedi_subdevice *s,
1706 struct comedi_insn *insn,
1707 unsigned long context)
1708{
3bc86feb 1709 const struct pcidas64_board *thisboard = dev->board_ptr;
96ed0850
HS
1710 struct pcidas64_private *devpriv = dev->private;
1711 unsigned int status;
1712
1713 status = readw(devpriv->main_iobase + HW_STATUS_REG);
1714 if (thisboard->layout == LAYOUT_4020) {
1715 status = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG);
1716 if (status)
1717 return 0;
1718 } else {
1719 if (pipe_full_bits(status))
1720 return 0;
1721 }
1722 return -EBUSY;
1723}
1724
da91b269 1725static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1726 struct comedi_insn *insn, unsigned int *data)
88b12a9a 1727{
3bc86feb 1728 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 1729 struct pcidas64_private *devpriv = dev->private;
96ed0850 1730 unsigned int bits = 0, n;
88b12a9a
FMH
1731 unsigned int channel, range, aref;
1732 unsigned long flags;
96ed0850 1733 int ret;
88b12a9a 1734
88b12a9a
FMH
1735 channel = CR_CHAN(insn->chanspec);
1736 range = CR_RANGE(insn->chanspec);
1737 aref = CR_AREF(insn->chanspec);
1738
9ef4dea6
BP
1739 /* disable card's analog input interrupt sources and pacing */
1740 /* 4020 generates dac done interrupts even though they are disabled */
88b12a9a
FMH
1741 disable_ai_pacing(dev);
1742
5f74ea14 1743 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 1744 if (insn->chanspec & CR_ALT_FILTER)
681d335a 1745 devpriv->adc_control1_bits |= ADC_DITHER_BIT;
88b12a9a 1746 else
681d335a
HS
1747 devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
1748 writew(devpriv->adc_control1_bits,
1749 devpriv->main_iobase + ADC_CONTROL1_REG);
5f74ea14 1750 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 1751
b07244ce 1752 if (thisboard->layout != LAYOUT_4020) {
9ef4dea6 1753 /* use internal queue */
681d335a
HS
1754 devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
1755 writew(devpriv->hw_config_bits,
1756 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a 1757
9ef4dea6 1758 /* ALT_SOURCE is internal calibration reference */
88b12a9a
FMH
1759 if (insn->chanspec & CR_ALT_SOURCE) {
1760 unsigned int cal_en_bit;
1761
b07244ce 1762 if (thisboard->layout == LAYOUT_60XX)
88b12a9a
FMH
1763 cal_en_bit = CAL_EN_60XX_BIT;
1764 else
1765 cal_en_bit = CAL_EN_64XX_BIT;
46ca84c4
IA
1766 /* select internal reference source to connect
1767 * to channel 0 */
0a85b6f0 1768 writew(cal_en_bit |
681d335a
HS
1769 adc_src_bits(devpriv->calibration_source),
1770 devpriv->main_iobase + CALIBRATION_REG);
88b12a9a 1771 } else {
46ca84c4
IA
1772 /* make sure internal calibration source
1773 * is turned off */
681d335a 1774 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a 1775 }
9ef4dea6 1776 /* load internal queue */
88b12a9a 1777 bits = 0;
9ef4dea6 1778 /* set gain */
88b12a9a 1779 bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
9ef4dea6 1780 /* set single-ended / differential */
88b12a9a
FMH
1781 bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
1782 if (aref == AREF_COMMON)
1783 bits |= ADC_COMMON_BIT;
1784 bits |= adc_chan_bits(channel);
9ef4dea6 1785 /* set stop channel */
88b12a9a 1786 writew(adc_chan_bits(channel),
681d335a 1787 devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
9ef4dea6 1788 /* set start channel, and rest of settings */
681d335a 1789 writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a 1790 } else {
681d335a 1791 uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits;
88b12a9a 1792
681d335a 1793 devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
88b12a9a 1794 if (insn->chanspec & CR_ALT_SOURCE) {
681d335a 1795 devpriv->i2c_cal_range_bits |=
46ca84c4 1796 adc_src_4020_bits(devpriv->calibration_source);
9ef4dea6 1797 } else { /* select BNC inputs */
681d335a 1798 devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
88b12a9a 1799 }
9ef4dea6 1800 /* select range */
88b12a9a 1801 if (range == 0)
681d335a 1802 devpriv->i2c_cal_range_bits |= attenuate_bit(channel);
88b12a9a 1803 else
46ca84c4
IA
1804 devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel);
1805 /* update calibration/range i2c register only if necessary,
1806 * as it is very slow */
681d335a
HS
1807 if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
1808 uint8_t i2c_data = devpriv->i2c_cal_range_bits;
43358ed0 1809
88b12a9a 1810 i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
0a85b6f0 1811 sizeof(i2c_data));
88b12a9a
FMH
1812 }
1813
46ca84c4
IA
1814 /* 4020 manual asks that sample interval register to be set
1815 * before writing to convert register.
1816 * Using somewhat arbitrary setting of 4 master clock ticks
1817 * = 0.1 usec */
1818 writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
1819 writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a
FMH
1820 }
1821
1822 for (n = 0; n < insn->n; n++) {
1823
9ef4dea6 1824 /* clear adc buffer (inside loop for 4020 sake) */
681d335a 1825 writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
88b12a9a
FMH
1826
1827 /* trigger conversion, bits sent only matter for 4020 */
1828 writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
681d335a 1829 devpriv->main_iobase + ADC_CONVERT_REG);
88b12a9a 1830
9ef4dea6 1831 /* wait for data */
96ed0850 1832 ret = comedi_timeout(dev, s, insn, cb_pcidas64_ai_eoc, 0);
22ca19d9 1833 if (ret)
96ed0850 1834 return ret;
96ed0850 1835
b07244ce 1836 if (thisboard->layout == LAYOUT_4020)
9ebd1028 1837 data[n] = readl(dev->mmio + ADC_FIFO_REG) & 0xffff;
88b12a9a 1838 else
46ca84c4 1839 data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG);
88b12a9a
FMH
1840 }
1841
1842 return n;
1843}
1844
0a85b6f0
MT
1845static int ai_config_calibration_source(struct comedi_device *dev,
1846 unsigned int *data)
88b12a9a 1847{
3bc86feb 1848 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 1849 struct pcidas64_private *devpriv = dev->private;
790c5541 1850 unsigned int source = data[1];
88b12a9a
FMH
1851 int num_calibration_sources;
1852
b07244ce 1853 if (thisboard->layout == LAYOUT_60XX)
88b12a9a
FMH
1854 num_calibration_sources = 16;
1855 else
1856 num_calibration_sources = 8;
1857 if (source >= num_calibration_sources) {
f41ad667 1858 dev_dbg(dev->class_dev, "invalid calibration source: %i\n",
6c6c227d 1859 source);
88b12a9a
FMH
1860 return -EINVAL;
1861 }
1862
681d335a 1863 devpriv->calibration_source = source;
88b12a9a
FMH
1864
1865 return 2;
1866}
1867
da91b269 1868static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
88b12a9a 1869{
3bc86feb 1870 const struct pcidas64_board *thisboard = dev->board_ptr;
88b12a9a 1871 int fifo_size;
b07244ce 1872 const struct hw_fifo_info *const fifo = thisboard->ai_fifo;
88b12a9a
FMH
1873 unsigned int block_size, requested_block_size;
1874 int retval;
1875
1876 requested_block_size = data[1];
1877
1878 if (requested_block_size) {
46ca84c4
IA
1879 fifo_size = requested_block_size * fifo->num_segments /
1880 bytes_in_sample;
88b12a9a
FMH
1881
1882 retval = set_ai_fifo_size(dev, fifo_size);
1883 if (retval < 0)
1884 return retval;
1885
1886 }
1887
1888 block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
1889
1890 data[1] = block_size;
1891
1892 return 2;
1893}
1894
0a85b6f0
MT
1895static int ai_config_master_clock_4020(struct comedi_device *dev,
1896 unsigned int *data)
88b12a9a 1897{
681d335a 1898 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
1899 unsigned int divisor = data[4];
1900 int retval = 0;
1901
1902 if (divisor < 2) {
1903 divisor = 2;
1904 retval = -EAGAIN;
1905 }
1906
1907 switch (data[1]) {
1908 case COMEDI_EV_SCAN_BEGIN:
681d335a
HS
1909 devpriv->ext_clock.divisor = divisor;
1910 devpriv->ext_clock.chanspec = data[2];
88b12a9a
FMH
1911 break;
1912 default:
1913 return -EINVAL;
88b12a9a
FMH
1914 }
1915
1916 data[4] = divisor;
1917
1918 return retval ? retval : 5;
1919}
1920
9ef4dea6 1921/* XXX could add support for 60xx series */
da91b269 1922static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
88b12a9a 1923{
3bc86feb 1924 const struct pcidas64_board *thisboard = dev->board_ptr;
88b12a9a 1925
b07244ce 1926 switch (thisboard->layout) {
88b12a9a
FMH
1927 case LAYOUT_4020:
1928 return ai_config_master_clock_4020(dev, data);
88b12a9a
FMH
1929 default:
1930 return -EINVAL;
88b12a9a
FMH
1931 }
1932
1933 return -EINVAL;
1934}
1935
da91b269 1936static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1937 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
1938{
1939 int id = data[0];
1940
1941 switch (id) {
1942 case INSN_CONFIG_ALT_SOURCE:
1943 return ai_config_calibration_source(dev, data);
88b12a9a
FMH
1944 case INSN_CONFIG_BLOCK_SIZE:
1945 return ai_config_block_size(dev, data);
88b12a9a
FMH
1946 case INSN_CONFIG_TIMER_1:
1947 return ai_config_master_clock(dev, data);
88b12a9a
FMH
1948 default:
1949 return -EINVAL;
88b12a9a
FMH
1950 }
1951 return -EINVAL;
1952}
1953
012e642c
IA
1954/* Gets nearest achievable timing given master clock speed, does not
1955 * take into account possible minimum/maximum divisor values. Used
1956 * by other timing checking functions. */
1957static unsigned int get_divisor(unsigned int ns, unsigned int flags)
1958{
1959 unsigned int divisor;
1960
f772bd57
IA
1961 switch (flags & CMDF_ROUND_MASK) {
1962 case CMDF_ROUND_UP:
012e642c
IA
1963 divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
1964 break;
f772bd57 1965 case CMDF_ROUND_DOWN:
012e642c
IA
1966 divisor = ns / TIMER_BASE;
1967 break;
f772bd57 1968 case CMDF_ROUND_NEAREST:
012e642c
IA
1969 default:
1970 divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
1971 break;
1972 }
1973 return divisor;
1974}
1975
1976/* utility function that rounds desired timing to an achievable time, and
1977 * sets cmd members appropriately.
1978 * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
1979 */
1980static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
1981{
3bc86feb 1982 const struct pcidas64_board *thisboard = dev->board_ptr;
012e642c
IA
1983 unsigned int convert_divisor = 0, scan_divisor;
1984 static const int min_convert_divisor = 3;
1985 static const int max_convert_divisor =
1986 max_counter_value + min_convert_divisor;
1987 static const int min_scan_divisor_4020 = 2;
1988 unsigned long long max_scan_divisor, min_scan_divisor;
1989
1990 if (cmd->convert_src == TRIG_TIMER) {
1991 if (thisboard->layout == LAYOUT_4020) {
1992 cmd->convert_arg = 0;
1993 } else {
1994 convert_divisor = get_divisor(cmd->convert_arg,
1995 cmd->flags);
1996 if (convert_divisor > max_convert_divisor)
1997 convert_divisor = max_convert_divisor;
1998 if (convert_divisor < min_convert_divisor)
1999 convert_divisor = min_convert_divisor;
2000 cmd->convert_arg = convert_divisor * TIMER_BASE;
2001 }
2002 } else if (cmd->convert_src == TRIG_NOW) {
2003 cmd->convert_arg = 0;
2004 }
2005
2006 if (cmd->scan_begin_src == TRIG_TIMER) {
2007 scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
2008 if (cmd->convert_src == TRIG_TIMER) {
2009 /* XXX check for integer overflows */
2010 min_scan_divisor = convert_divisor * cmd->chanlist_len;
2011 max_scan_divisor =
2012 (convert_divisor * cmd->chanlist_len - 1) +
2013 max_counter_value;
2014 } else {
2015 min_scan_divisor = min_scan_divisor_4020;
2016 max_scan_divisor = max_counter_value + min_scan_divisor;
2017 }
2018 if (scan_divisor > max_scan_divisor)
2019 scan_divisor = max_scan_divisor;
2020 if (scan_divisor < min_scan_divisor)
2021 scan_divisor = min_scan_divisor;
2022 cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
2023 }
012e642c
IA
2024}
2025
e300e4fb
HS
2026static int cb_pcidas64_ai_check_chanlist(struct comedi_device *dev,
2027 struct comedi_subdevice *s,
2028 struct comedi_cmd *cmd)
2029{
3bc86feb 2030 const struct pcidas64_board *board = dev->board_ptr;
e300e4fb
HS
2031 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
2032 int i;
2033
2034 for (i = 1; i < cmd->chanlist_len; i++) {
2035 unsigned int aref = CR_AREF(cmd->chanlist[i]);
2036
2037 if (aref != aref0) {
2038 dev_dbg(dev->class_dev,
2039 "all elements in chanlist must use the same analog reference\n");
2040 return -EINVAL;
2041 }
2042 }
2043
2044 if (board->layout == LAYOUT_4020) {
2045 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
2046
2047 for (i = 1; i < cmd->chanlist_len; i++) {
2048 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
2049
2050 if (chan != (chan0 + i)) {
2051 dev_dbg(dev->class_dev,
2052 "chanlist must use consecutive channels\n");
2053 return -EINVAL;
2054 }
2055 }
2056 if (cmd->chanlist_len == 3) {
2057 dev_dbg(dev->class_dev,
2058 "chanlist cannot be 3 channels long, use 1, 2, or 4 channels\n");
2059 return -EINVAL;
2060 }
2061 }
2062
2063 return 0;
2064}
2065
da91b269 2066static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 2067 struct comedi_cmd *cmd)
88b12a9a 2068{
3bc86feb 2069 const struct pcidas64_board *thisboard = dev->board_ptr;
88b12a9a 2070 int err = 0;
88b12a9a 2071 unsigned int tmp_arg, tmp_arg2;
88b12a9a
FMH
2072 unsigned int triggers;
2073
27020ffe 2074 /* Step 1 : check if triggers are trivially valid */
88b12a9a 2075
27020ffe 2076 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
88b12a9a 2077
88b12a9a 2078 triggers = TRIG_TIMER;
b07244ce 2079 if (thisboard->layout == LAYOUT_4020)
88b12a9a
FMH
2080 triggers |= TRIG_OTHER;
2081 else
2082 triggers |= TRIG_FOLLOW;
27020ffe 2083 err |= cfc_check_trigger_src(&cmd->scan_begin_src, triggers);
88b12a9a 2084
88b12a9a 2085 triggers = TRIG_TIMER;
b07244ce 2086 if (thisboard->layout == LAYOUT_4020)
88b12a9a
FMH
2087 triggers |= TRIG_NOW;
2088 else
2089 triggers |= TRIG_EXT;
27020ffe 2090 err |= cfc_check_trigger_src(&cmd->convert_src, triggers);
27020ffe
HS
2091 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
2092 err |= cfc_check_trigger_src(&cmd->stop_src,
46ca84c4 2093 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
88b12a9a
FMH
2094
2095 if (err)
2096 return 1;
2097
27020ffe 2098 /* Step 2a : make sure trigger sources are unique */
88b12a9a 2099
27020ffe
HS
2100 err |= cfc_check_trigger_is_unique(cmd->start_src);
2101 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
2102 err |= cfc_check_trigger_is_unique(cmd->convert_src);
2103 err |= cfc_check_trigger_is_unique(cmd->stop_src);
2104
2105 /* Step 2b : and mutually compatible */
88b12a9a 2106
88b12a9a 2107 if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
27020ffe 2108 err |= -EINVAL;
88b12a9a
FMH
2109
2110 if (err)
2111 return 2;
2112
dba2939c 2113 /* Step 3: check if arguments are trivially valid */
88b12a9a 2114
020cb120
HS
2115 switch (cmd->start_src) {
2116 case TRIG_NOW:
2117 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
2118 break;
2119 case TRIG_EXT:
2120 /*
2121 * start_arg is the CR_CHAN | CR_INVERT of the
2122 * external trigger.
2123 */
2124 break;
2125 }
2126
88b12a9a 2127 if (cmd->convert_src == TRIG_TIMER) {
b07244ce 2128 if (thisboard->layout == LAYOUT_4020) {
dba2939c 2129 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
88b12a9a 2130 } else {
dba2939c
HS
2131 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
2132 thisboard->ai_speed);
2133 /* if scans are timed faster than conversion rate allows */
2134 if (cmd->scan_begin_src == TRIG_TIMER)
2135 err |= cfc_check_trigger_arg_min(
2136 &cmd->scan_begin_arg,
46ca84c4 2137 cmd->convert_arg *
dba2939c 2138 cmd->chanlist_len);
88b12a9a
FMH
2139 }
2140 }
2141
dba2939c
HS
2142 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
2143 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
88b12a9a
FMH
2144
2145 switch (cmd->stop_src) {
2146 case TRIG_EXT:
2147 break;
2148 case TRIG_COUNT:
dba2939c 2149 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
88b12a9a
FMH
2150 break;
2151 case TRIG_NONE:
dba2939c 2152 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
88b12a9a
FMH
2153 break;
2154 default:
2155 break;
2156 }
2157
2158 if (err)
2159 return 3;
2160
2161 /* step 4: fix up any arguments */
2162
2163 if (cmd->convert_src == TRIG_TIMER) {
2164 tmp_arg = cmd->convert_arg;
2165 tmp_arg2 = cmd->scan_begin_arg;
2166 check_adc_timing(dev, cmd);
2167 if (tmp_arg != cmd->convert_arg)
2168 err++;
2169 if (tmp_arg2 != cmd->scan_begin_arg)
2170 err++;
2171 }
2172
2173 if (err)
2174 return 4;
2175
e300e4fb
HS
2176 /* Step 5: check channel list if it exists */
2177 if (cmd->chanlist && cmd->chanlist_len > 0)
2178 err |= cb_pcidas64_ai_check_chanlist(dev, s, cmd);
88b12a9a
FMH
2179
2180 if (err)
2181 return 5;
2182
2183 return 0;
2184}
2185
da91b269 2186static int use_hw_sample_counter(struct comedi_cmd *cmd)
88b12a9a 2187{
9ef4dea6 2188/* disable for now until I work out a race */
88b12a9a
FMH
2189 return 0;
2190
2191 if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
2192 return 1;
4ffeead3
HS
2193
2194 return 0;
88b12a9a
FMH
2195}
2196
0a85b6f0
MT
2197static void setup_sample_counters(struct comedi_device *dev,
2198 struct comedi_cmd *cmd)
88b12a9a 2199{
681d335a
HS
2200 struct pcidas64_private *devpriv = dev->private;
2201
88b12a9a 2202 if (cmd->stop_src == TRIG_COUNT) {
9ef4dea6 2203 /* set software count */
681d335a 2204 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
88b12a9a 2205 }
9ef4dea6 2206 /* load hardware conversion counter */
88b12a9a
FMH
2207 if (use_hw_sample_counter(cmd)) {
2208 writew(cmd->stop_arg & 0xffff,
681d335a 2209 devpriv->main_iobase + ADC_COUNT_LOWER_REG);
88b12a9a 2210 writew((cmd->stop_arg >> 16) & 0xff,
681d335a 2211 devpriv->main_iobase + ADC_COUNT_UPPER_REG);
88b12a9a 2212 } else {
681d335a 2213 writew(1, devpriv->main_iobase + ADC_COUNT_LOWER_REG);
88b12a9a
FMH
2214 }
2215}
2216
da91b269 2217static inline unsigned int dma_transfer_size(struct comedi_device *dev)
88b12a9a 2218{
3bc86feb 2219 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 2220 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2221 unsigned int num_samples;
2222
46ca84c4 2223 num_samples = devpriv->ai_fifo_segment_length *
b07244ce 2224 thisboard->ai_fifo->sample_packing_ratio;
88b12a9a
FMH
2225 if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
2226 num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
2227
2228 return num_samples;
2229}
2230
da91b269 2231static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
0a85b6f0 2232 const struct comedi_cmd *cmd)
88b12a9a 2233{
9ef4dea6 2234 /* supposed to load counter with desired divisor minus 3 */
88b12a9a
FMH
2235 return cmd->convert_arg / TIMER_BASE - 3;
2236}
2237
0a85b6f0
MT
2238static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
2239 struct comedi_cmd *cmd)
88b12a9a
FMH
2240{
2241 uint32_t count;
46ca84c4 2242
9ef4dea6 2243 /* figure out how long we need to delay at end of scan */
88b12a9a
FMH
2244 switch (cmd->scan_begin_src) {
2245 case TRIG_TIMER:
2246 count = (cmd->scan_begin_arg -
46ca84c4
IA
2247 (cmd->convert_arg * (cmd->chanlist_len - 1))) /
2248 TIMER_BASE;
88b12a9a
FMH
2249 break;
2250 case TRIG_FOLLOW:
2251 count = cmd->convert_arg / TIMER_BASE;
2252 break;
2253 default:
2254 return 0;
88b12a9a
FMH
2255 }
2256 return count - 3;
2257}
2258
0a85b6f0
MT
2259static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
2260 struct comedi_cmd *cmd)
88b12a9a 2261{
681d335a 2262 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2263 unsigned int divisor;
2264
2265 switch (cmd->scan_begin_src) {
2266 case TRIG_TIMER:
2267 divisor = cmd->scan_begin_arg / TIMER_BASE;
2268 break;
2269 case TRIG_OTHER:
681d335a 2270 divisor = devpriv->ext_clock.divisor;
88b12a9a 2271 break;
9ef4dea6 2272 default: /* should never happen */
e176d78c 2273 dev_err(dev->class_dev, "bug! failed to set ai pacing!\n");
88b12a9a
FMH
2274 divisor = 1000;
2275 break;
2276 }
2277
9ef4dea6 2278 /* supposed to load counter with desired divisor minus 2 for 4020 */
88b12a9a
FMH
2279 return divisor - 2;
2280}
2281
da91b269 2282static void select_master_clock_4020(struct comedi_device *dev,
0a85b6f0 2283 const struct comedi_cmd *cmd)
88b12a9a 2284{
681d335a
HS
2285 struct pcidas64_private *devpriv = dev->private;
2286
9ef4dea6 2287 /* select internal/external master clock */
681d335a 2288 devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
88b12a9a 2289 if (cmd->scan_begin_src == TRIG_OTHER) {
681d335a 2290 int chanspec = devpriv->ext_clock.chanspec;
88b12a9a
FMH
2291
2292 if (CR_CHAN(chanspec))
681d335a 2293 devpriv->hw_config_bits |= BNC_CLOCK_4020_BITS;
88b12a9a 2294 else
681d335a 2295 devpriv->hw_config_bits |= EXT_CLOCK_4020_BITS;
88b12a9a 2296 } else {
681d335a 2297 devpriv->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
88b12a9a 2298 }
681d335a
HS
2299 writew(devpriv->hw_config_bits,
2300 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a
FMH
2301}
2302
0a85b6f0
MT
2303static void select_master_clock(struct comedi_device *dev,
2304 const struct comedi_cmd *cmd)
88b12a9a 2305{
3bc86feb 2306 const struct pcidas64_board *thisboard = dev->board_ptr;
b07244ce
IA
2307
2308 switch (thisboard->layout) {
88b12a9a
FMH
2309 case LAYOUT_4020:
2310 select_master_clock_4020(dev, cmd);
2311 break;
2312 default:
2313 break;
2314 }
2315}
2316
0a85b6f0
MT
2317static inline void dma_start_sync(struct comedi_device *dev,
2318 unsigned int channel)
88b12a9a 2319{
681d335a 2320 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2321 unsigned long flags;
2322
9ef4dea6 2323 /* spinlock for plx dma control/status reg */
5f74ea14 2324 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2325 if (channel)
2326 writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
0a85b6f0 2327 PLX_CLEAR_DMA_INTR_BIT,
681d335a 2328 devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
88b12a9a
FMH
2329 else
2330 writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
0a85b6f0 2331 PLX_CLEAR_DMA_INTR_BIT,
681d335a 2332 devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
5f74ea14 2333 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2334}
2335
da91b269 2336static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
88b12a9a 2337{
3bc86feb 2338 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 2339 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2340 uint32_t convert_counter = 0, scan_counter = 0;
2341
2342 check_adc_timing(dev, cmd);
2343
2344 select_master_clock(dev, cmd);
2345
b07244ce 2346 if (thisboard->layout == LAYOUT_4020) {
88b12a9a
FMH
2347 convert_counter = ai_convert_counter_4020(dev, cmd);
2348 } else {
2349 convert_counter = ai_convert_counter_6xxx(dev, cmd);
2350 scan_counter = ai_scan_counter_6xxx(dev, cmd);
2351 }
2352
9ef4dea6 2353 /* load lower 16 bits of convert interval */
88b12a9a 2354 writew(convert_counter & 0xffff,
681d335a 2355 devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
9ef4dea6 2356 /* load upper 8 bits of convert interval */
88b12a9a 2357 writew((convert_counter >> 16) & 0xff,
681d335a 2358 devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
9ef4dea6 2359 /* load lower 16 bits of scan delay */
88b12a9a 2360 writew(scan_counter & 0xffff,
681d335a 2361 devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
9ef4dea6 2362 /* load upper 8 bits of scan delay */
88b12a9a 2363 writew((scan_counter >> 16) & 0xff,
681d335a 2364 devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
88b12a9a
FMH
2365}
2366
da91b269 2367static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
88b12a9a
FMH
2368{
2369 int i;
46ca84c4 2370
88b12a9a
FMH
2371 for (i = 0; i + 1 < cmd->chanlist_len; i++) {
2372 if (CR_CHAN(cmd->chanlist[i + 1]) !=
0a85b6f0 2373 CR_CHAN(cmd->chanlist[i]) + 1)
88b12a9a
FMH
2374 return 0;
2375 if (CR_RANGE(cmd->chanlist[i + 1]) !=
0a85b6f0 2376 CR_RANGE(cmd->chanlist[i]))
88b12a9a
FMH
2377 return 0;
2378 if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
2379 return 0;
2380 }
2381 return 1;
2382}
2383
0a85b6f0
MT
2384static int setup_channel_queue(struct comedi_device *dev,
2385 const struct comedi_cmd *cmd)
88b12a9a 2386{
3bc86feb 2387 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 2388 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2389 unsigned short bits;
2390 int i;
2391
b07244ce 2392 if (thisboard->layout != LAYOUT_4020) {
88b12a9a 2393 if (use_internal_queue_6xxx(cmd)) {
681d335a
HS
2394 devpriv->hw_config_bits &= ~EXT_QUEUE_BIT;
2395 writew(devpriv->hw_config_bits,
2396 devpriv->main_iobase + HW_CONFIG_REG);
88b12a9a 2397 bits = 0;
9ef4dea6 2398 /* set channel */
88b12a9a 2399 bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
9ef4dea6 2400 /* set gain */
88b12a9a 2401 bits |= ai_range_bits_6xxx(dev,
0a85b6f0 2402 CR_RANGE(cmd->chanlist[0]));
9ef4dea6 2403 /* set single-ended / differential */
88b12a9a 2404 bits |= se_diff_bit_6xxx(dev,
0a85b6f0
MT
2405 CR_AREF(cmd->chanlist[0]) ==
2406 AREF_DIFF);
88b12a9a
FMH
2407 if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
2408 bits |= ADC_COMMON_BIT;
9ef4dea6 2409 /* set stop channel */
0a85b6f0
MT
2410 writew(adc_chan_bits
2411 (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
681d335a 2412 devpriv->main_iobase + ADC_QUEUE_HIGH_REG);
9ef4dea6 2413 /* set start channel, and rest of settings */
88b12a9a 2414 writew(bits,
681d335a 2415 devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a 2416 } else {
9ef4dea6 2417 /* use external queue */
88b12a9a
FMH
2418 if (dev->write_subdev && dev->write_subdev->busy) {
2419 warn_external_queue(dev);
2420 return -EBUSY;
2421 }
681d335a
HS
2422 devpriv->hw_config_bits |= EXT_QUEUE_BIT;
2423 writew(devpriv->hw_config_bits,
2424 devpriv->main_iobase + HW_CONFIG_REG);
9ef4dea6 2425 /* clear DAC buffer to prevent weird interactions */
88b12a9a 2426 writew(0,
681d335a 2427 devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
9ef4dea6 2428 /* clear queue pointer */
681d335a 2429 writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
9ef4dea6 2430 /* load external queue */
88b12a9a
FMH
2431 for (i = 0; i < cmd->chanlist_len; i++) {
2432 bits = 0;
9ef4dea6 2433 /* set channel */
46ca84c4
IA
2434 bits |= adc_chan_bits(CR_CHAN(cmd->
2435 chanlist[i]));
9ef4dea6 2436 /* set gain */
88b12a9a 2437 bits |= ai_range_bits_6xxx(dev,
0a85b6f0
MT
2438 CR_RANGE(cmd->
2439 chanlist
2440 [i]));
9ef4dea6 2441 /* set single-ended / differential */
88b12a9a 2442 bits |= se_diff_bit_6xxx(dev,
0a85b6f0
MT
2443 CR_AREF(cmd->
2444 chanlist[i]) ==
2445 AREF_DIFF);
88b12a9a
FMH
2446 if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
2447 bits |= ADC_COMMON_BIT;
9ef4dea6 2448 /* mark end of queue */
88b12a9a
FMH
2449 if (i == cmd->chanlist_len - 1)
2450 bits |= QUEUE_EOSCAN_BIT |
46ca84c4 2451 QUEUE_EOSEQ_BIT;
88b12a9a 2452 writew(bits,
681d335a 2453 devpriv->main_iobase +
0a85b6f0 2454 ADC_QUEUE_FIFO_REG);
88b12a9a
FMH
2455 }
2456 /* doing a queue clear is not specified in board docs,
2457 * but required for reliable operation */
681d335a 2458 writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
9ef4dea6 2459 /* prime queue holding register */
681d335a 2460 writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a
FMH
2461 }
2462 } else {
46ca84c4 2463 unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits;
88b12a9a 2464
681d335a 2465 devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
9ef4dea6 2466 /* select BNC inputs */
681d335a 2467 devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4);
9ef4dea6 2468 /* select ranges */
88b12a9a
FMH
2469 for (i = 0; i < cmd->chanlist_len; i++) {
2470 unsigned int channel = CR_CHAN(cmd->chanlist[i]);
2471 unsigned int range = CR_RANGE(cmd->chanlist[i]);
2472
2473 if (range == 0)
681d335a 2474 devpriv->i2c_cal_range_bits |=
46ca84c4 2475 attenuate_bit(channel);
88b12a9a 2476 else
681d335a 2477 devpriv->i2c_cal_range_bits &=
46ca84c4 2478 ~attenuate_bit(channel);
88b12a9a 2479 }
46ca84c4
IA
2480 /* update calibration/range i2c register only if necessary,
2481 * as it is very slow */
681d335a
HS
2482 if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
2483 uint8_t i2c_data = devpriv->i2c_cal_range_bits;
43358ed0 2484
88b12a9a 2485 i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
0a85b6f0 2486 sizeof(i2c_data));
88b12a9a
FMH
2487 }
2488 }
2489 return 0;
2490}
2491
da91b269 2492static inline void load_first_dma_descriptor(struct comedi_device *dev,
0a85b6f0
MT
2493 unsigned int dma_channel,
2494 unsigned int descriptor_bits)
88b12a9a 2495{
681d335a
HS
2496 struct pcidas64_private *devpriv = dev->private;
2497
88b12a9a
FMH
2498 /* The transfer size, pci address, and local address registers
2499 * are supposedly unused during chained dma,
2500 * but I have found that left over values from last operation
2501 * occasionally cause problems with transfer of first dma
2502 * block. Initializing them to zero seems to fix the problem. */
2503 if (dma_channel) {
2504 writel(0,
681d335a
HS
2505 devpriv->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
2506 writel(0, devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
88b12a9a 2507 writel(0,
681d335a 2508 devpriv->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
88b12a9a 2509 writel(descriptor_bits,
681d335a 2510 devpriv->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
88b12a9a
FMH
2511 } else {
2512 writel(0,
681d335a
HS
2513 devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
2514 writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
88b12a9a 2515 writel(0,
681d335a 2516 devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
88b12a9a 2517 writel(descriptor_bits,
681d335a 2518 devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
88b12a9a
FMH
2519 }
2520}
2521
da91b269 2522static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 2523{
3bc86feb 2524 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 2525 struct pcidas64_private *devpriv = dev->private;
d163679c 2526 struct comedi_async *async = s->async;
ea6d0d4c 2527 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2528 uint32_t bits;
2529 unsigned int i;
2530 unsigned long flags;
2531 int retval;
2532
2533 disable_ai_pacing(dev);
2534 abort_dma(dev, 1);
2535
2536 retval = setup_channel_queue(dev, cmd);
2537 if (retval < 0)
2538 return retval;
2539
9ef4dea6 2540 /* make sure internal calibration source is turned off */
681d335a 2541 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
2542
2543 set_ai_pacing(dev, cmd);
2544
2545 setup_sample_counters(dev, cmd);
2546
2547 enable_ai_interrupts(dev, cmd);
2548
5f74ea14 2549 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 2550 /* set mode, allow conversions through software gate */
681d335a
HS
2551 devpriv->adc_control1_bits |= ADC_SW_GATE_BIT;
2552 devpriv->adc_control1_bits &= ~ADC_DITHER_BIT;
b07244ce 2553 if (thisboard->layout != LAYOUT_4020) {
681d335a 2554 devpriv->adc_control1_bits &= ~ADC_MODE_MASK;
88b12a9a 2555 if (cmd->convert_src == TRIG_EXT)
46ca84c4
IA
2556 /* good old mode 13 */
2557 devpriv->adc_control1_bits |= adc_mode_bits(13);
88b12a9a 2558 else
46ca84c4
IA
2559 /* mode 8. What else could you need? */
2560 devpriv->adc_control1_bits |= adc_mode_bits(8);
88b12a9a 2561 } else {
681d335a 2562 devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
88b12a9a 2563 if (cmd->chanlist_len == 4)
681d335a 2564 devpriv->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
88b12a9a 2565 else if (cmd->chanlist_len == 2)
681d335a
HS
2566 devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
2567 devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
2568 devpriv->adc_control1_bits |=
46ca84c4 2569 adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
681d335a
HS
2570 devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
2571 devpriv->adc_control1_bits |=
46ca84c4
IA
2572 adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist
2573 [cmd->chanlist_len - 1]));
88b12a9a 2574 }
681d335a
HS
2575 writew(devpriv->adc_control1_bits,
2576 devpriv->main_iobase + ADC_CONTROL1_REG);
5f74ea14 2577 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2578
9ef4dea6 2579 /* clear adc buffer */
681d335a 2580 writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG);
88b12a9a 2581
0ad08e4b 2582 if ((cmd->flags & CMDF_WAKE_EOS) == 0 ||
b07244ce 2583 thisboard->layout == LAYOUT_4020) {
681d335a 2584 devpriv->ai_dma_index = 0;
88b12a9a 2585
9ef4dea6 2586 /* set dma transfer size */
b07244ce 2587 for (i = 0; i < ai_dma_ring_count(thisboard); i++)
681d335a 2588 devpriv->ai_dma_desc[i].transfer_size =
46ca84c4
IA
2589 cpu_to_le32(dma_transfer_size(dev) *
2590 sizeof(uint16_t));
88b12a9a 2591
9ef4dea6 2592 /* give location of first dma descriptor */
88b12a9a 2593 load_first_dma_descriptor(dev, 1,
681d335a 2594 devpriv->ai_dma_desc_bus_addr |
0a85b6f0
MT
2595 PLX_DESC_IN_PCI_BIT |
2596 PLX_INTR_TERM_COUNT |
2597 PLX_XFER_LOCAL_TO_PCI);
88b12a9a
FMH
2598
2599 dma_start_sync(dev, 1);
2600 }
2601
b07244ce 2602 if (thisboard->layout == LAYOUT_4020) {
88b12a9a
FMH
2603 /* set source for external triggers */
2604 bits = 0;
2605 if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
2606 bits |= EXT_START_TRIG_BNC_BIT;
2607 if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
2608 bits |= EXT_STOP_TRIG_BNC_BIT;
681d335a 2609 writew(bits, devpriv->main_iobase + DAQ_ATRIG_LOW_4020_REG);
88b12a9a
FMH
2610 }
2611
5f74ea14 2612 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2613
2614 /* enable pacing, triggering, etc */
2615 bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
0ad08e4b 2616 if (cmd->flags & CMDF_WAKE_EOS)
88b12a9a 2617 bits |= ADC_DMA_DISABLE_BIT;
9ef4dea6 2618 /* set start trigger */
88b12a9a
FMH
2619 if (cmd->start_src == TRIG_EXT) {
2620 bits |= ADC_START_TRIG_EXT_BITS;
2621 if (cmd->start_arg & CR_INVERT)
2622 bits |= ADC_START_TRIG_FALLING_BIT;
2623 } else if (cmd->start_src == TRIG_NOW)
2624 bits |= ADC_START_TRIG_SOFT_BITS;
2625 if (use_hw_sample_counter(cmd))
2626 bits |= ADC_SAMPLE_COUNTER_EN_BIT;
681d335a 2627 writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG);
88b12a9a 2628
681d335a 2629 devpriv->ai_cmd_running = 1;
88b12a9a 2630
5f74ea14 2631 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2632
25985edc 2633 /* start acquisition */
220edb91 2634 if (cmd->start_src == TRIG_NOW)
681d335a 2635 writew(0, devpriv->main_iobase + ADC_START_REG);
88b12a9a
FMH
2636
2637 return 0;
2638}
2639
9ef4dea6 2640/* read num_samples from 16 bit wide ai fifo */
da91b269 2641static void pio_drain_ai_fifo_16(struct comedi_device *dev)
88b12a9a 2642{
681d335a 2643 struct pcidas64_private *devpriv = dev->private;
34c43922 2644 struct comedi_subdevice *s = dev->read_subdev;
d163679c 2645 struct comedi_async *async = s->async;
ea6d0d4c 2646 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2647 unsigned int i;
2648 uint16_t prepost_bits;
2649 int read_segment, read_index, write_segment, write_index;
2650 int num_samples;
2651
2652 do {
9ef4dea6 2653 /* get least significant 15 bits */
46ca84c4
IA
2654 read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
2655 0x7fff;
2656 write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) &
2657 0x7fff;
2658 /* Get most significant bits (grey code).
2659 * Different boards use different code so use a scheme
2660 * that doesn't depend on encoding. This read must
88b12a9a
FMH
2661 * occur after reading least significant 15 bits to avoid race
2662 * with fifo switching to next segment. */
681d335a 2663 prepost_bits = readw(devpriv->main_iobase + PREPOST_REG);
88b12a9a 2664
46ca84c4
IA
2665 /* if read and write pointers are not on the same fifo segment,
2666 * read to the end of the read segment */
88b12a9a
FMH
2667 read_segment = adc_upper_read_ptr_code(prepost_bits);
2668 write_segment = adc_upper_write_ptr_code(prepost_bits);
2669
88b12a9a
FMH
2670 if (read_segment != write_segment)
2671 num_samples =
46ca84c4 2672 devpriv->ai_fifo_segment_length - read_index;
88b12a9a
FMH
2673 else
2674 num_samples = write_index - read_index;
2675
2676 if (cmd->stop_src == TRIG_COUNT) {
681d335a 2677 if (devpriv->ai_count == 0)
88b12a9a 2678 break;
681d335a
HS
2679 if (num_samples > devpriv->ai_count)
2680 num_samples = devpriv->ai_count;
90cae794 2681
681d335a 2682 devpriv->ai_count -= num_samples;
88b12a9a
FMH
2683 }
2684
2685 if (num_samples < 0) {
f41ad667
IA
2686 dev_err(dev->class_dev,
2687 "cb_pcidas64: bug! num_samples < 0\n");
88b12a9a
FMH
2688 break;
2689 }
2690
88b12a9a
FMH
2691 for (i = 0; i < num_samples; i++) {
2692 cfc_write_to_buffer(s,
681d335a 2693 readw(devpriv->main_iobase +
0a85b6f0 2694 ADC_FIFO_REG));
88b12a9a
FMH
2695 }
2696
2697 } while (read_segment != write_segment);
2698}
2699
46ca84c4
IA
2700/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of
2701 * pointers. The pci-4020 hardware only supports dma transfers (it only
2702 * supports the use of pio for draining the last remaining points from the
2703 * fifo when a data acquisition operation has completed).
88b12a9a 2704 */
da91b269 2705static void pio_drain_ai_fifo_32(struct comedi_device *dev)
88b12a9a 2706{
681d335a 2707 struct pcidas64_private *devpriv = dev->private;
34c43922 2708 struct comedi_subdevice *s = dev->read_subdev;
d163679c 2709 struct comedi_async *async = s->async;
ea6d0d4c 2710 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2711 unsigned int i;
2712 unsigned int max_transfer = 100000;
2713 uint32_t fifo_data;
2714 int write_code =
46ca84c4 2715 readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
88b12a9a 2716 int read_code =
46ca84c4 2717 readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
88b12a9a
FMH
2718
2719 if (cmd->stop_src == TRIG_COUNT) {
681d335a
HS
2720 if (max_transfer > devpriv->ai_count)
2721 max_transfer = devpriv->ai_count;
90cae794 2722
88b12a9a
FMH
2723 }
2724 for (i = 0; read_code != write_code && i < max_transfer;) {
9ebd1028 2725 fifo_data = readl(dev->mmio + ADC_FIFO_REG);
88b12a9a
FMH
2726 cfc_write_to_buffer(s, fifo_data & 0xffff);
2727 i++;
2728 if (i < max_transfer) {
2729 cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff);
2730 i++;
2731 }
46ca84c4
IA
2732 read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
2733 0x7fff;
88b12a9a 2734 }
681d335a 2735 devpriv->ai_count -= i;
88b12a9a
FMH
2736}
2737
9ef4dea6 2738/* empty fifo */
da91b269 2739static void pio_drain_ai_fifo(struct comedi_device *dev)
88b12a9a 2740{
3bc86feb 2741 const struct pcidas64_board *thisboard = dev->board_ptr;
b07244ce
IA
2742
2743 if (thisboard->layout == LAYOUT_4020)
88b12a9a 2744 pio_drain_ai_fifo_32(dev);
90cae794 2745 else
88b12a9a
FMH
2746 pio_drain_ai_fifo_16(dev);
2747}
2748
da91b269 2749static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
88b12a9a 2750{
3bc86feb 2751 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 2752 struct pcidas64_private *devpriv = dev->private;
d163679c 2753 struct comedi_async *async = dev->read_subdev->async;
421ab41b 2754 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2755 uint32_t next_transfer_addr;
2756 int j;
2757 int num_samples = 0;
f31d0008 2758 void __iomem *pci_addr_reg;
88b12a9a
FMH
2759
2760 if (channel)
2761 pci_addr_reg =
681d335a 2762 devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
88b12a9a
FMH
2763 else
2764 pci_addr_reg =
681d335a 2765 devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
88b12a9a 2766
9ef4dea6 2767 /* loop until we have read all the full buffers */
88b12a9a 2768 for (j = 0, next_transfer_addr = readl(pci_addr_reg);
0a85b6f0 2769 (next_transfer_addr <
46ca84c4
IA
2770 devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] ||
2771 next_transfer_addr >=
681d335a 2772 devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] +
b07244ce 2773 DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) {
9ef4dea6 2774 /* transfer data from dma buffer to comedi buffer */
88b12a9a 2775 num_samples = dma_transfer_size(dev);
421ab41b 2776 if (cmd->stop_src == TRIG_COUNT) {
681d335a
HS
2777 if (num_samples > devpriv->ai_count)
2778 num_samples = devpriv->ai_count;
2779 devpriv->ai_count -= num_samples;
88b12a9a
FMH
2780 }
2781 cfc_write_array_to_buffer(dev->read_subdev,
681d335a 2782 devpriv->ai_buffer[devpriv->
46ca84c4 2783 ai_dma_index],
0a85b6f0 2784 num_samples * sizeof(uint16_t));
46ca84c4 2785 devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) %
b07244ce 2786 ai_dma_ring_count(thisboard);
88b12a9a 2787 }
46ca84c4
IA
2788 /* XXX check for dma ring buffer overrun
2789 * (use end-of-chain bit to mark last unused buffer) */
88b12a9a
FMH
2790}
2791
f31d0008
GKH
2792static void handle_ai_interrupt(struct comedi_device *dev,
2793 unsigned short status,
2794 unsigned int plx_status)
88b12a9a 2795{
3bc86feb 2796 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 2797 struct pcidas64_private *devpriv = dev->private;
34c43922 2798 struct comedi_subdevice *s = dev->read_subdev;
d163679c 2799 struct comedi_async *async = s->async;
ea6d0d4c 2800 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2801 uint8_t dma1_status;
2802 unsigned long flags;
2803
9ef4dea6 2804 /* check for fifo overrun */
88b12a9a 2805 if (status & ADC_OVERRUN_BIT) {
e176d78c 2806 dev_err(dev->class_dev, "fifo overrun\n");
88b12a9a
FMH
2807 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
2808 }
25985edc 2809 /* spin lock makes sure no one else changes plx dma control reg */
5f74ea14 2810 spin_lock_irqsave(&dev->spinlock, flags);
681d335a 2811 dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
9ef4dea6 2812 if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */
88b12a9a 2813 writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
681d335a 2814 devpriv->plx9080_iobase + PLX_DMA1_CS_REG);
88b12a9a 2815
90cae794 2816 if (dma1_status & PLX_DMA_EN_BIT)
88b12a9a 2817 drain_dma_buffers(dev, 1);
88b12a9a 2818 }
5f74ea14 2819 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2820
9ef4dea6 2821 /* drain fifo with pio */
88b12a9a 2822 if ((status & ADC_DONE_BIT) ||
0ad08e4b 2823 ((cmd->flags & CMDF_WAKE_EOS) &&
0a85b6f0 2824 (status & ADC_INTR_PENDING_BIT) &&
b07244ce 2825 (thisboard->layout != LAYOUT_4020))) {
5f74ea14 2826 spin_lock_irqsave(&dev->spinlock, flags);
681d335a 2827 if (devpriv->ai_cmd_running) {
5f74ea14 2828 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2829 pio_drain_ai_fifo(dev);
2830 } else
5f74ea14 2831 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2832 }
9ef4dea6 2833 /* if we are have all the data, then quit */
681d335a 2834 if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) ||
0a85b6f0 2835 (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
88b12a9a
FMH
2836 async->events |= COMEDI_CB_EOA;
2837 }
2838
2839 cfc_handle_events(dev, s);
2840}
2841
da91b269 2842static inline unsigned int prev_ao_dma_index(struct comedi_device *dev)
88b12a9a 2843{
681d335a 2844 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2845 unsigned int buffer_index;
2846
681d335a 2847 if (devpriv->ao_dma_index == 0)
88b12a9a
FMH
2848 buffer_index = AO_DMA_RING_COUNT - 1;
2849 else
681d335a 2850 buffer_index = devpriv->ao_dma_index - 1;
88b12a9a
FMH
2851 return buffer_index;
2852}
2853
da91b269 2854static int last_ao_dma_load_completed(struct comedi_device *dev)
88b12a9a 2855{
681d335a 2856 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2857 unsigned int buffer_index;
2858 unsigned int transfer_address;
2859 unsigned short dma_status;
2860
2861 buffer_index = prev_ao_dma_index(dev);
681d335a 2862 dma_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
88b12a9a
FMH
2863 if ((dma_status & PLX_DMA_DONE_BIT) == 0)
2864 return 0;
2865
2866 transfer_address =
46ca84c4 2867 readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
681d335a 2868 if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index])
88b12a9a
FMH
2869 return 0;
2870
2871 return 1;
2872}
2873
0a85b6f0
MT
2874static int ao_stopped_by_error(struct comedi_device *dev,
2875 const struct comedi_cmd *cmd)
88b12a9a 2876{
681d335a
HS
2877 struct pcidas64_private *devpriv = dev->private;
2878
88b12a9a
FMH
2879 if (cmd->stop_src == TRIG_NONE)
2880 return 1;
2881 if (cmd->stop_src == TRIG_COUNT) {
681d335a 2882 if (devpriv->ao_count)
88b12a9a
FMH
2883 return 1;
2884 if (last_ao_dma_load_completed(dev) == 0)
2885 return 1;
2886 }
2887 return 0;
2888}
2889
da91b269 2890static inline int ao_dma_needs_restart(struct comedi_device *dev,
0a85b6f0 2891 unsigned short dma_status)
88b12a9a
FMH
2892{
2893 if ((dma_status & PLX_DMA_DONE_BIT) == 0 ||
0a85b6f0 2894 (dma_status & PLX_DMA_EN_BIT) == 0)
88b12a9a
FMH
2895 return 0;
2896 if (last_ao_dma_load_completed(dev))
2897 return 0;
2898
2899 return 1;
2900}
2901
da91b269 2902static void restart_ao_dma(struct comedi_device *dev)
88b12a9a 2903{
681d335a 2904 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
2905 unsigned int dma_desc_bits;
2906
2907 dma_desc_bits =
46ca84c4 2908 readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
88b12a9a 2909 dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
88b12a9a
FMH
2910 load_first_dma_descriptor(dev, 0, dma_desc_bits);
2911
2912 dma_start_sync(dev, 0);
2913}
2914
dd379fa2
IA
2915static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
2916 const struct comedi_cmd *cmd)
2917{
2918 struct pcidas64_private *devpriv = dev->private;
2919 unsigned int num_bytes, buffer_index, prev_buffer_index;
2920 unsigned int next_bits;
2921
2922 buffer_index = devpriv->ao_dma_index;
2923 prev_buffer_index = prev_ao_dma_index(dev);
2924
e9edef3a 2925 num_bytes = comedi_buf_read_n_available(dev->write_subdev);
dd379fa2
IA
2926 if (num_bytes > DMA_BUFFER_SIZE)
2927 num_bytes = DMA_BUFFER_SIZE;
2928 if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count)
2929 num_bytes = devpriv->ao_count;
2930 num_bytes -= num_bytes % bytes_in_sample;
2931
2932 if (num_bytes == 0)
2933 return 0;
2934
dd379fa2
IA
2935 num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
2936 devpriv->
2937 ao_buffer[buffer_index],
2938 num_bytes);
2939 devpriv->ao_dma_desc[buffer_index].transfer_size =
2940 cpu_to_le32(num_bytes);
2941 /* set end of chain bit so we catch underruns */
2942 next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next);
2943 next_bits |= PLX_END_OF_CHAIN_BIT;
2944 devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
2945 /* clear end of chain bit on previous buffer now that we have set it
2946 * for the last buffer */
2947 next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next);
2948 next_bits &= ~PLX_END_OF_CHAIN_BIT;
2949 devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
2950
2951 devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
2952 devpriv->ao_count -= num_bytes;
2953
2954 return num_bytes;
2955}
2956
2957static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
2958{
2959 struct pcidas64_private *devpriv = dev->private;
2960 unsigned int num_bytes;
2961 unsigned int next_transfer_addr;
2962 void __iomem *pci_addr_reg =
2963 devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
2964 unsigned int buffer_index;
2965
2966 do {
2967 buffer_index = devpriv->ao_dma_index;
2968 /* don't overwrite data that hasn't been transferred yet */
2969 next_transfer_addr = readl(pci_addr_reg);
2970 if (next_transfer_addr >=
2971 devpriv->ao_buffer_bus_addr[buffer_index] &&
2972 next_transfer_addr <
2973 devpriv->ao_buffer_bus_addr[buffer_index] +
2974 DMA_BUFFER_SIZE)
2975 return;
2976 num_bytes = load_ao_dma_buffer(dev, cmd);
2977 } while (num_bytes >= DMA_BUFFER_SIZE);
2978}
2979
0a85b6f0
MT
2980static void handle_ao_interrupt(struct comedi_device *dev,
2981 unsigned short status, unsigned int plx_status)
88b12a9a 2982{
681d335a 2983 struct pcidas64_private *devpriv = dev->private;
34c43922 2984 struct comedi_subdevice *s = dev->write_subdev;
d163679c 2985 struct comedi_async *async;
ea6d0d4c 2986 struct comedi_cmd *cmd;
88b12a9a
FMH
2987 uint8_t dma0_status;
2988 unsigned long flags;
2989
2990 /* board might not support ao, in which case write_subdev is NULL */
2991 if (s == NULL)
2992 return;
2993 async = s->async;
2994 cmd = &async->cmd;
2995
25985edc 2996 /* spin lock makes sure no one else changes plx dma control reg */
5f74ea14 2997 spin_lock_irqsave(&dev->spinlock, flags);
681d335a 2998 dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
9ef4dea6 2999 if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */
46ca84c4
IA
3000 if ((dma0_status & PLX_DMA_EN_BIT) &&
3001 !(dma0_status & PLX_DMA_DONE_BIT))
88b12a9a 3002 writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
681d335a 3003 devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
88b12a9a
FMH
3004 else
3005 writeb(PLX_CLEAR_DMA_INTR_BIT,
681d335a 3006 devpriv->plx9080_iobase + PLX_DMA0_CS_REG);
5f74ea14 3007 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3008 if (dma0_status & PLX_DMA_EN_BIT) {
3009 load_ao_dma(dev, cmd);
3010 /* try to recover from dma end-of-chain event */
3011 if (ao_dma_needs_restart(dev, dma0_status))
3012 restart_ao_dma(dev);
3013 }
46ca84c4 3014 } else {
5f74ea14 3015 spin_unlock_irqrestore(&dev->spinlock, flags);
46ca84c4 3016 }
88b12a9a
FMH
3017
3018 if ((status & DAC_DONE_BIT)) {
3019 async->events |= COMEDI_CB_EOA;
3020 if (ao_stopped_by_error(dev, cmd))
3021 async->events |= COMEDI_CB_ERROR;
88b12a9a
FMH
3022 }
3023 cfc_handle_events(dev, s);
3024}
3025
70265d24 3026static irqreturn_t handle_interrupt(int irq, void *d)
88b12a9a 3027{
71b5f4f1 3028 struct comedi_device *dev = d;
681d335a 3029 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3030 unsigned short status;
3031 uint32_t plx_status;
3032 uint32_t plx_bits;
3033
681d335a
HS
3034 plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG);
3035 status = readw(devpriv->main_iobase + HW_STATUS_REG);
88b12a9a 3036
88b12a9a
FMH
3037 /* an interrupt before all the postconfig stuff gets done could
3038 * cause a NULL dereference if we continue through the
3039 * interrupt handler */
220edb91 3040 if (!dev->attached)
88b12a9a 3041 return IRQ_HANDLED;
220edb91 3042
88b12a9a
FMH
3043 handle_ai_interrupt(dev, status, plx_status);
3044 handle_ao_interrupt(dev, status, plx_status);
3045
9ef4dea6
BP
3046 /* clear possible plx9080 interrupt sources */
3047 if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */
681d335a
HS
3048 plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
3049 writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG);
88b12a9a
FMH
3050 }
3051
88b12a9a
FMH
3052 return IRQ_HANDLED;
3053}
3054
da91b269 3055static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3056{
681d335a 3057 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3058 unsigned long flags;
3059
5f74ea14 3060 spin_lock_irqsave(&dev->spinlock, flags);
681d335a 3061 if (devpriv->ai_cmd_running == 0) {
5f74ea14 3062 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3063 return 0;
3064 }
681d335a 3065 devpriv->ai_cmd_running = 0;
5f74ea14 3066 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3067
3068 disable_ai_pacing(dev);
3069
3070 abort_dma(dev, 1);
3071
88b12a9a
FMH
3072 return 0;
3073}
3074
da91b269 3075static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3076 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3077{
3bc86feb 3078 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a 3079 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3080 int chan = CR_CHAN(insn->chanspec);
3081 int range = CR_RANGE(insn->chanspec);
3082
9ef4dea6 3083 /* do some initializing */
681d335a 3084 writew(0, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a 3085
9ef4dea6 3086 /* set range */
681d335a
HS
3087 set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range);
3088 writew(devpriv->dac_control1_bits,
3089 devpriv->main_iobase + DAC_CONTROL1_REG);
88b12a9a 3090
9ef4dea6 3091 /* write to channel */
b07244ce 3092 if (thisboard->layout == LAYOUT_4020) {
88b12a9a 3093 writew(data[0] & 0xff,
681d335a 3094 devpriv->main_iobase + dac_lsb_4020_reg(chan));
88b12a9a 3095 writew((data[0] >> 8) & 0xf,
681d335a 3096 devpriv->main_iobase + dac_msb_4020_reg(chan));
88b12a9a 3097 } else {
681d335a 3098 writew(data[0], devpriv->main_iobase + dac_convert_reg(chan));
88b12a9a
FMH
3099 }
3100
9ef4dea6 3101 /* remember output value */
f88f75fe 3102 s->readback[chan] = data[0];
88b12a9a
FMH
3103
3104 return 1;
3105}
3106
0a85b6f0
MT
3107static void set_dac_control0_reg(struct comedi_device *dev,
3108 const struct comedi_cmd *cmd)
88b12a9a 3109{
681d335a 3110 struct pcidas64_private *devpriv = dev->private;
88b12a9a 3111 unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
46ca84c4 3112 WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
88b12a9a
FMH
3113
3114 if (cmd->start_src == TRIG_EXT) {
3115 bits |= WAVEFORM_TRIG_EXT_BITS;
3116 if (cmd->start_arg & CR_INVERT)
3117 bits |= WAVEFORM_TRIG_FALLING_BIT;
3118 } else {
3119 bits |= WAVEFORM_TRIG_SOFT_BITS;
3120 }
3121 if (cmd->scan_begin_src == TRIG_EXT) {
3122 bits |= DAC_EXT_UPDATE_ENABLE_BIT;
3123 if (cmd->scan_begin_arg & CR_INVERT)
3124 bits |= DAC_EXT_UPDATE_FALLING_BIT;
3125 }
681d335a 3126 writew(bits, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a
FMH
3127}
3128
0a85b6f0
MT
3129static void set_dac_control1_reg(struct comedi_device *dev,
3130 const struct comedi_cmd *cmd)
88b12a9a 3131{
681d335a 3132 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3133 int i;
3134
3135 for (i = 0; i < cmd->chanlist_len; i++) {
3136 int channel, range;
3137
3138 channel = CR_CHAN(cmd->chanlist[i]);
3139 range = CR_RANGE(cmd->chanlist[i]);
681d335a 3140 set_dac_range_bits(dev, &devpriv->dac_control1_bits, channel,
0a85b6f0 3141 range);
88b12a9a 3142 }
681d335a
HS
3143 devpriv->dac_control1_bits |= DAC_SW_GATE_BIT;
3144 writew(devpriv->dac_control1_bits,
3145 devpriv->main_iobase + DAC_CONTROL1_REG);
88b12a9a
FMH
3146}
3147
0a85b6f0
MT
3148static void set_dac_select_reg(struct comedi_device *dev,
3149 const struct comedi_cmd *cmd)
88b12a9a 3150{
681d335a 3151 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3152 uint16_t bits;
3153 unsigned int first_channel, last_channel;
3154
3155 first_channel = CR_CHAN(cmd->chanlist[0]);
3156 last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
3157 if (last_channel < first_channel)
e176d78c
HS
3158 dev_err(dev->class_dev,
3159 "bug! last ao channel < first ao channel\n");
88b12a9a
FMH
3160
3161 bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
3162
681d335a 3163 writew(bits, devpriv->main_iobase + DAC_SELECT_REG);
88b12a9a
FMH
3164}
3165
012e642c
IA
3166static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
3167{
3168 return get_divisor(ns, flags) - 2;
3169}
3170
0a85b6f0
MT
3171static void set_dac_interval_regs(struct comedi_device *dev,
3172 const struct comedi_cmd *cmd)
88b12a9a 3173{
681d335a 3174 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3175 unsigned int divisor;
3176
3177 if (cmd->scan_begin_src != TRIG_TIMER)
3178 return;
3179
3180 divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
3181 if (divisor > max_counter_value) {
e176d78c 3182 dev_err(dev->class_dev, "bug! ao divisor too big\n");
88b12a9a
FMH
3183 divisor = max_counter_value;
3184 }
3185 writew(divisor & 0xffff,
681d335a 3186 devpriv->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a 3187 writew((divisor >> 16) & 0xff,
681d335a 3188 devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
88b12a9a
FMH
3189}
3190
da91b269 3191static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
88b12a9a 3192{
681d335a 3193 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3194 unsigned int num_bytes;
3195 int i;
3196
3197 /* clear queue pointer too, since external queue has
3198 * weird interactions with ao fifo */
681d335a
HS
3199 writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
3200 writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
88b12a9a
FMH
3201
3202 num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
3203 if (cmd->stop_src == TRIG_COUNT &&
681d335a
HS
3204 num_bytes / bytes_in_sample > devpriv->ao_count)
3205 num_bytes = devpriv->ao_count * bytes_in_sample;
88b12a9a 3206 num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
681d335a 3207 devpriv->ao_bounce_buffer,
0a85b6f0 3208 num_bytes);
88b12a9a 3209 for (i = 0; i < num_bytes / bytes_in_sample; i++) {
681d335a
HS
3210 writew(devpriv->ao_bounce_buffer[i],
3211 devpriv->main_iobase + DAC_FIFO_REG);
88b12a9a 3212 }
681d335a
HS
3213 devpriv->ao_count -= num_bytes / bytes_in_sample;
3214 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0)
88b12a9a
FMH
3215 return 0;
3216 num_bytes = load_ao_dma_buffer(dev, cmd);
3217 if (num_bytes == 0)
3218 return -1;
88b12a9a
FMH
3219 load_ao_dma(dev, cmd);
3220
3221 dma_start_sync(dev, 0);
3222
3223 return 0;
3224}
3225
f5f3a2c6
HS
3226static inline int external_ai_queue_in_use(struct comedi_device *dev,
3227 struct comedi_subdevice *s,
3228 struct comedi_cmd *cmd)
88b12a9a 3229{
3bc86feb 3230 const struct pcidas64_board *thisboard = dev->board_ptr;
b07244ce 3231
f5f3a2c6 3232 if (s->busy)
88b12a9a 3233 return 0;
b07244ce 3234 if (thisboard->layout == LAYOUT_4020)
88b12a9a 3235 return 0;
f5f3a2c6 3236 else if (use_internal_queue_6xxx(cmd))
88b12a9a
FMH
3237 return 0;
3238 return 1;
3239}
3240
012e642c
IA
3241static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
3242 unsigned int trig_num)
3243{
3244 struct pcidas64_private *devpriv = dev->private;
3245 struct comedi_cmd *cmd = &s->async->cmd;
3246 int retval;
3247
020cb120 3248 if (trig_num != cmd->start_arg)
012e642c
IA
3249 return -EINVAL;
3250
3251 retval = prep_ao_dma(dev, cmd);
3252 if (retval < 0)
3253 return -EPIPE;
3254
3255 set_dac_control0_reg(dev, cmd);
3256
3257 if (cmd->start_src == TRIG_INT)
3258 writew(0, devpriv->main_iobase + DAC_START_REG);
3259
3260 s->async->inttrig = NULL;
3261
3262 return 0;
3263}
3264
da91b269 3265static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3266{
681d335a 3267 struct pcidas64_private *devpriv = dev->private;
ea6d0d4c 3268 struct comedi_cmd *cmd = &s->async->cmd;
88b12a9a 3269
f5f3a2c6 3270 if (external_ai_queue_in_use(dev, s, cmd)) {
88b12a9a
FMH
3271 warn_external_queue(dev);
3272 return -EBUSY;
3273 }
3274 /* disable analog output system during setup */
681d335a 3275 writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a 3276
681d335a
HS
3277 devpriv->ao_dma_index = 0;
3278 devpriv->ao_count = cmd->stop_arg * cmd->chanlist_len;
88b12a9a
FMH
3279
3280 set_dac_select_reg(dev, cmd);
3281 set_dac_interval_regs(dev, cmd);
681d335a 3282 load_first_dma_descriptor(dev, 0, devpriv->ao_dma_desc_bus_addr |
0a85b6f0 3283 PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
88b12a9a
FMH
3284
3285 set_dac_control1_reg(dev, cmd);
3286 s->async->inttrig = ao_inttrig;
3287
3288 return 0;
3289}
3290
e300e4fb
HS
3291static int cb_pcidas64_ao_check_chanlist(struct comedi_device *dev,
3292 struct comedi_subdevice *s,
3293 struct comedi_cmd *cmd)
3294{
3295 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
3296 int i;
3297
3298 for (i = 1; i < cmd->chanlist_len; i++) {
3299 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
3300
3301 if (chan != (chan0 + i)) {
3302 dev_dbg(dev->class_dev,
3303 "chanlist must use consecutive channels\n");
3304 return -EINVAL;
3305 }
3306 }
3307
3308 return 0;
3309}
3310
da91b269 3311static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3312 struct comedi_cmd *cmd)
88b12a9a 3313{
3bc86feb 3314 const struct pcidas64_board *thisboard = dev->board_ptr;
88b12a9a 3315 int err = 0;
88b12a9a 3316 unsigned int tmp_arg;
88b12a9a 3317
27020ffe 3318 /* Step 1 : check if triggers are trivially valid */
88b12a9a 3319
27020ffe
HS
3320 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
3321 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
46ca84c4 3322 TRIG_TIMER | TRIG_EXT);
27020ffe
HS
3323 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
3324 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
3325 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
88b12a9a
FMH
3326
3327 if (err)
3328 return 1;
3329
27020ffe 3330 /* Step 2a : make sure trigger sources are unique */
88b12a9a 3331
27020ffe
HS
3332 err |= cfc_check_trigger_is_unique(cmd->start_src);
3333 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
3334
3335 /* Step 2b : and mutually compatible */
88b12a9a 3336
88b12a9a 3337 if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
27020ffe 3338 err |= -EINVAL;
88b12a9a 3339 if (cmd->stop_src != TRIG_COUNT &&
0a85b6f0 3340 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
27020ffe 3341 err |= -EINVAL;
88b12a9a
FMH
3342
3343 if (err)
3344 return 2;
3345
dba2939c 3346 /* Step 3: check if arguments are trivially valid */
88b12a9a 3347
020cb120
HS
3348 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
3349
88b12a9a 3350 if (cmd->scan_begin_src == TRIG_TIMER) {
dba2939c
HS
3351 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
3352 thisboard->ao_scan_speed);
3353 if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) >
3354 max_counter_value) {
46ca84c4
IA
3355 cmd->scan_begin_arg = (max_counter_value + 2) *
3356 TIMER_BASE;
dba2939c 3357 err |= -EINVAL;
88b12a9a
FMH
3358 }
3359 }
3360
dba2939c
HS
3361 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
3362 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
88b12a9a
FMH
3363
3364 if (err)
3365 return 3;
3366
3367 /* step 4: fix up any arguments */
3368
3369 if (cmd->scan_begin_src == TRIG_TIMER) {
3370 tmp_arg = cmd->scan_begin_arg;
46ca84c4
IA
3371 cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg,
3372 cmd->flags) * TIMER_BASE;
88b12a9a
FMH
3373 if (tmp_arg != cmd->scan_begin_arg)
3374 err++;
3375 }
3376
3377 if (err)
3378 return 4;
3379
e300e4fb
HS
3380 /* Step 5: check channel list if it exists */
3381 if (cmd->chanlist && cmd->chanlist_len > 0)
3382 err |= cb_pcidas64_ao_check_chanlist(dev, s, cmd);
88b12a9a
FMH
3383
3384 if (err)
3385 return 5;
3386
3387 return 0;
3388}
3389
da91b269 3390static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3391{
681d335a
HS
3392 struct pcidas64_private *devpriv = dev->private;
3393
3394 writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG);
88b12a9a
FMH
3395 abort_dma(dev, 0);
3396 return 0;
3397}
3398
09d6dd74 3399static int dio_callback_4020(struct comedi_device *dev,
da261e1d 3400 int dir, int port, int data, unsigned long iobase)
88b12a9a 3401{
da261e1d 3402 struct pcidas64_private *devpriv = dev->private;
43358ed0 3403
88b12a9a 3404 if (dir) {
da261e1d 3405 writew(data, devpriv->main_iobase + iobase + 2 * port);
88b12a9a 3406 return 0;
88b12a9a 3407 }
da261e1d 3408 return readw(devpriv->main_iobase + iobase + 2 * port);
88b12a9a
FMH
3409}
3410
da91b269 3411static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3412 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3413{
790c5541 3414 unsigned int bits;
88b12a9a 3415
9ebd1028 3416 bits = readb(dev->mmio + DI_REG);
88b12a9a
FMH
3417 bits &= 0xf;
3418 data[1] = bits;
3419 data[0] = 0;
3420
a2714e3e 3421 return insn->n;
88b12a9a
FMH
3422}
3423
97f4289a
HS
3424static int do_wbits(struct comedi_device *dev,
3425 struct comedi_subdevice *s,
3426 struct comedi_insn *insn,
3427 unsigned int *data)
88b12a9a 3428{
97f4289a 3429 if (comedi_dio_update_state(s, data))
9ebd1028 3430 writeb(s->state, dev->mmio + DO_REG);
88b12a9a
FMH
3431
3432 data[1] = s->state;
3433
a2714e3e 3434 return insn->n;
88b12a9a
FMH
3435}
3436
0a85b6f0
MT
3437static int dio_60xx_config_insn(struct comedi_device *dev,
3438 struct comedi_subdevice *s,
ddf62f2c
HS
3439 struct comedi_insn *insn,
3440 unsigned int *data)
88b12a9a 3441{
ddf62f2c 3442 int ret;
88b12a9a 3443
ddf62f2c
HS
3444 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
3445 if (ret)
3446 return ret;
88b12a9a 3447
9ebd1028 3448 writeb(s->io_bits, dev->mmio + DIO_DIRECTION_60XX_REG);
88b12a9a 3449
ddf62f2c 3450 return insn->n;
88b12a9a
FMH
3451}
3452
97f4289a
HS
3453static int dio_60xx_wbits(struct comedi_device *dev,
3454 struct comedi_subdevice *s,
3455 struct comedi_insn *insn,
3456 unsigned int *data)
88b12a9a 3457{
9ebd1028
HS
3458 if (comedi_dio_update_state(s, data))
3459 writeb(s->state, dev->mmio + DIO_DATA_60XX_REG);
88b12a9a 3460
9ebd1028 3461 data[1] = readb(dev->mmio + DIO_DATA_60XX_REG);
88b12a9a 3462
a2714e3e 3463 return insn->n;
88b12a9a
FMH
3464}
3465
012e642c
IA
3466/* pci-6025 8800 caldac:
3467 * address 0 == dac channel 0 offset
3468 * address 1 == dac channel 0 gain
3469 * address 2 == dac channel 1 offset
3470 * address 3 == dac channel 1 gain
3471 * address 4 == fine adc offset
3472 * address 5 == coarse adc offset
3473 * address 6 == coarse adc gain
3474 * address 7 == fine adc gain
3475 */
3476/* pci-6402/16 uses all 8 channels for dac:
3477 * address 0 == dac channel 0 fine gain
3478 * address 1 == dac channel 0 coarse gain
3479 * address 2 == dac channel 0 coarse offset
3480 * address 3 == dac channel 1 coarse offset
3481 * address 4 == dac channel 1 fine gain
3482 * address 5 == dac channel 1 coarse gain
3483 * address 6 == dac channel 0 fine offset
3484 * address 7 == dac channel 1 fine offset
3485*/
3486
3487static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
3488 uint8_t value)
3489{
3490 struct pcidas64_private *devpriv = dev->private;
3491 static const int num_caldac_channels = 8;
3492 static const int bitstream_length = 11;
3493 unsigned int bitstream = ((address & 0x7) << 8) | value;
3494 unsigned int bit, register_bits;
3495 static const int caldac_8800_udelay = 1;
3496
3497 if (address >= num_caldac_channels) {
e176d78c 3498 dev_err(dev->class_dev, "illegal caldac channel\n");
012e642c
IA
3499 return -1;
3500 }
3501 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
3502 register_bits = 0;
3503 if (bitstream & bit)
3504 register_bits |= SERIAL_DATA_IN_BIT;
3505 udelay(caldac_8800_udelay);
3506 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
3507 register_bits |= SERIAL_CLOCK_BIT;
3508 udelay(caldac_8800_udelay);
3509 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
3510 }
3511 udelay(caldac_8800_udelay);
3512 writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG);
3513 udelay(caldac_8800_udelay);
3514 writew(0, devpriv->main_iobase + CALIBRATION_REG);
3515 udelay(caldac_8800_udelay);
3516 return 0;
3517}
3518
3519/* 4020 caldacs */
3520static int caldac_i2c_write(struct comedi_device *dev,
3521 unsigned int caldac_channel, unsigned int value)
3522{
3523 uint8_t serial_bytes[3];
3524 uint8_t i2c_addr;
3525 enum pointer_bits {
3526 /* manual has gain and offset bits switched */
3527 OFFSET_0_2 = 0x1,
3528 GAIN_0_2 = 0x2,
3529 OFFSET_1_3 = 0x4,
3530 GAIN_1_3 = 0x8,
3531 };
3532 enum data_bits {
3533 NOT_CLEAR_REGISTERS = 0x20,
3534 };
3535
3536 switch (caldac_channel) {
3537 case 0: /* chan 0 offset */
3538 i2c_addr = CALDAC0_I2C_ADDR;
3539 serial_bytes[0] = OFFSET_0_2;
3540 break;
3541 case 1: /* chan 1 offset */
3542 i2c_addr = CALDAC0_I2C_ADDR;
3543 serial_bytes[0] = OFFSET_1_3;
3544 break;
3545 case 2: /* chan 2 offset */
3546 i2c_addr = CALDAC1_I2C_ADDR;
3547 serial_bytes[0] = OFFSET_0_2;
3548 break;
3549 case 3: /* chan 3 offset */
3550 i2c_addr = CALDAC1_I2C_ADDR;
3551 serial_bytes[0] = OFFSET_1_3;
3552 break;
3553 case 4: /* chan 0 gain */
3554 i2c_addr = CALDAC0_I2C_ADDR;
3555 serial_bytes[0] = GAIN_0_2;
3556 break;
3557 case 5: /* chan 1 gain */
3558 i2c_addr = CALDAC0_I2C_ADDR;
3559 serial_bytes[0] = GAIN_1_3;
3560 break;
3561 case 6: /* chan 2 gain */
3562 i2c_addr = CALDAC1_I2C_ADDR;
3563 serial_bytes[0] = GAIN_0_2;
3564 break;
3565 case 7: /* chan 3 gain */
3566 i2c_addr = CALDAC1_I2C_ADDR;
3567 serial_bytes[0] = GAIN_1_3;
3568 break;
3569 default:
e176d78c 3570 dev_err(dev->class_dev, "invalid caldac channel\n");
012e642c 3571 return -1;
012e642c
IA
3572 }
3573 serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
3574 serial_bytes[2] = value & 0xff;
3575 i2c_write(dev, i2c_addr, serial_bytes, 3);
3576 return 0;
3577}
3578
da91b269 3579static void caldac_write(struct comedi_device *dev, unsigned int channel,
0a85b6f0 3580 unsigned int value)
88b12a9a 3581{
3bc86feb 3582 const struct pcidas64_board *thisboard = dev->board_ptr;
681d335a
HS
3583 struct pcidas64_private *devpriv = dev->private;
3584
3585 devpriv->caldac_state[channel] = value;
88b12a9a 3586
b07244ce 3587 switch (thisboard->layout) {
88b12a9a
FMH
3588 case LAYOUT_60XX:
3589 case LAYOUT_64XX:
3590 caldac_8800_write(dev, channel, value);
3591 break;
3592 case LAYOUT_4020:
3593 caldac_i2c_write(dev, channel, value);
3594 break;
3595 default:
3596 break;
3597 }
3598}
3599
0a85b6f0
MT
3600static int calib_write_insn(struct comedi_device *dev,
3601 struct comedi_subdevice *s,
3602 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3603{
681d335a 3604 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3605 int channel = CR_CHAN(insn->chanspec);
3606
3607 /* return immediately if setting hasn't changed, since
3608 * programming these things is slow */
681d335a 3609 if (devpriv->caldac_state[channel] == data[0])
88b12a9a
FMH
3610 return 1;
3611
3612 caldac_write(dev, channel, data[0]);
3613
3614 return 1;
3615}
3616
0a85b6f0
MT
3617static int calib_read_insn(struct comedi_device *dev,
3618 struct comedi_subdevice *s, struct comedi_insn *insn,
3619 unsigned int *data)
88b12a9a 3620{
681d335a 3621 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3622 unsigned int channel = CR_CHAN(insn->chanspec);
3623
681d335a 3624 data[0] = devpriv->caldac_state[channel];
88b12a9a
FMH
3625
3626 return 1;
3627}
3628
da91b269 3629static void ad8402_write(struct comedi_device *dev, unsigned int channel,
0a85b6f0 3630 unsigned int value)
88b12a9a 3631{
681d335a 3632 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3633 static const int bitstream_length = 10;
3634 unsigned int bit, register_bits;
3635 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
5f74ea14 3636 static const int ad8402_udelay = 1;
88b12a9a 3637
681d335a 3638 devpriv->ad8402_state[channel] = value;
88b12a9a
FMH
3639
3640 register_bits = SELECT_8402_64XX_BIT;
5f74ea14 3641 udelay(ad8402_udelay);
681d335a 3642 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3643
3644 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
3645 if (bitstream & bit)
3646 register_bits |= SERIAL_DATA_IN_BIT;
3647 else
3648 register_bits &= ~SERIAL_DATA_IN_BIT;
5f74ea14 3649 udelay(ad8402_udelay);
681d335a 3650 writew(register_bits, devpriv->main_iobase + CALIBRATION_REG);
5f74ea14 3651 udelay(ad8402_udelay);
88b12a9a 3652 writew(register_bits | SERIAL_CLOCK_BIT,
681d335a 3653 devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3654 }
3655
5f74ea14 3656 udelay(ad8402_udelay);
681d335a 3657 writew(0, devpriv->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3658}
3659
3660/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
0a85b6f0
MT
3661static int ad8402_write_insn(struct comedi_device *dev,
3662 struct comedi_subdevice *s,
3663 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3664{
681d335a 3665 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3666 int channel = CR_CHAN(insn->chanspec);
3667
3668 /* return immediately if setting hasn't changed, since
3669 * programming these things is slow */
681d335a 3670 if (devpriv->ad8402_state[channel] == data[0])
88b12a9a
FMH
3671 return 1;
3672
681d335a 3673 devpriv->ad8402_state[channel] = data[0];
88b12a9a
FMH
3674
3675 ad8402_write(dev, channel, data[0]);
3676
3677 return 1;
3678}
3679
0a85b6f0
MT
3680static int ad8402_read_insn(struct comedi_device *dev,
3681 struct comedi_subdevice *s,
3682 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3683{
681d335a 3684 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3685 unsigned int channel = CR_CHAN(insn->chanspec);
3686
681d335a 3687 data[0] = devpriv->ad8402_state[channel];
88b12a9a
FMH
3688
3689 return 1;
3690}
3691
da91b269 3692static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
88b12a9a 3693{
681d335a 3694 struct pcidas64_private *devpriv = dev->private;
88b12a9a
FMH
3695 static const int bitstream_length = 11;
3696 static const int read_command = 0x6;
3697 unsigned int bitstream = (read_command << 8) | address;
3698 unsigned int bit;
f31d0008 3699 void __iomem * const plx_control_addr =
46ca84c4 3700 devpriv->plx9080_iobase + PLX_CONTROL_REG;
88b12a9a
FMH
3701 uint16_t value;
3702 static const int value_length = 16;
5f74ea14 3703 static const int eeprom_udelay = 1;
88b12a9a 3704
5f74ea14 3705 udelay(eeprom_udelay);
681d335a 3706 devpriv->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
9ef4dea6 3707 /* make sure we don't send anything to the i2c bus on 4020 */
681d335a
HS
3708 devpriv->plx_control_bits |= CTL_USERO;
3709 writel(devpriv->plx_control_bits, plx_control_addr);
9ef4dea6 3710 /* activate serial eeprom */
5f74ea14 3711 udelay(eeprom_udelay);
681d335a
HS
3712 devpriv->plx_control_bits |= CTL_EE_CS;
3713 writel(devpriv->plx_control_bits, plx_control_addr);
88b12a9a 3714
9ef4dea6 3715 /* write read command and desired memory address */
88b12a9a 3716 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
9ef4dea6 3717 /* set bit to be written */
5f74ea14 3718 udelay(eeprom_udelay);
88b12a9a 3719 if (bitstream & bit)
681d335a 3720 devpriv->plx_control_bits |= CTL_EE_W;
88b12a9a 3721 else
681d335a
HS
3722 devpriv->plx_control_bits &= ~CTL_EE_W;
3723 writel(devpriv->plx_control_bits, plx_control_addr);
9ef4dea6 3724 /* clock in bit */
5f74ea14 3725 udelay(eeprom_udelay);
681d335a
HS
3726 devpriv->plx_control_bits |= CTL_EE_CLK;
3727 writel(devpriv->plx_control_bits, plx_control_addr);
5f74ea14 3728 udelay(eeprom_udelay);
681d335a
HS
3729 devpriv->plx_control_bits &= ~CTL_EE_CLK;
3730 writel(devpriv->plx_control_bits, plx_control_addr);
88b12a9a 3731 }
9ef4dea6 3732 /* read back value from eeprom memory location */
88b12a9a
FMH
3733 value = 0;
3734 for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
9ef4dea6 3735 /* clock out bit */
5f74ea14 3736 udelay(eeprom_udelay);
681d335a
HS
3737 devpriv->plx_control_bits |= CTL_EE_CLK;
3738 writel(devpriv->plx_control_bits, plx_control_addr);
5f74ea14 3739 udelay(eeprom_udelay);
681d335a
HS
3740 devpriv->plx_control_bits &= ~CTL_EE_CLK;
3741 writel(devpriv->plx_control_bits, plx_control_addr);
5f74ea14 3742 udelay(eeprom_udelay);
88b12a9a
FMH
3743 if (readl(plx_control_addr) & CTL_EE_R)
3744 value |= bit;
3745 }
3746
9ef4dea6 3747 /* deactivate eeprom serial input */
5f74ea14 3748 udelay(eeprom_udelay);
681d335a
HS
3749 devpriv->plx_control_bits &= ~CTL_EE_CS;
3750 writel(devpriv->plx_control_bits, plx_control_addr);
88b12a9a
FMH
3751
3752 return value;
3753}
3754
0a85b6f0
MT
3755static int eeprom_read_insn(struct comedi_device *dev,
3756 struct comedi_subdevice *s,
3757 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3758{
3759 data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
3760
3761 return 1;
3762}
3763
9c7a00f5
IA
3764/* Allocate and initialize the subdevice structures.
3765 */
3766static int setup_subdevices(struct comedi_device *dev)
3767{
3bc86feb 3768 const struct pcidas64_board *thisboard = dev->board_ptr;
9c7a00f5
IA
3769 struct pcidas64_private *devpriv = dev->private;
3770 struct comedi_subdevice *s;
9c7a00f5
IA
3771 int i;
3772 int ret;
3773
3774 ret = comedi_alloc_subdevices(dev, 10);
3775 if (ret)
3776 return ret;
3777
3778 s = &dev->subdevices[0];
3779 /* analog input subdevice */
3780 dev->read_subdev = s;
3781 s->type = COMEDI_SUBD_AI;
3782 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
3783 if (thisboard->layout == LAYOUT_60XX)
3784 s->subdev_flags |= SDF_COMMON | SDF_DIFF;
3785 else if (thisboard->layout == LAYOUT_64XX)
3786 s->subdev_flags |= SDF_DIFF;
3787 /* XXX Number of inputs in differential mode is ignored */
3788 s->n_chan = thisboard->ai_se_chans;
3789 s->len_chanlist = 0x2000;
3790 s->maxdata = (1 << thisboard->ai_bits) - 1;
3791 s->range_table = thisboard->ai_range_table;
3792 s->insn_read = ai_rinsn;
3793 s->insn_config = ai_config_insn;
3794 s->do_cmd = ai_cmd;
3795 s->do_cmdtest = ai_cmdtest;
3796 s->cancel = ai_cancel;
3797 if (thisboard->layout == LAYOUT_4020) {
3798 uint8_t data;
3799 /* set adc to read from inputs
3800 * (not internal calibration sources) */
3801 devpriv->i2c_cal_range_bits = adc_src_4020_bits(4);
3802 /* set channels to +-5 volt input ranges */
3803 for (i = 0; i < s->n_chan; i++)
3804 devpriv->i2c_cal_range_bits |= attenuate_bit(i);
3805 data = devpriv->i2c_cal_range_bits;
3806 i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
3807 }
3808
3809 /* analog output subdevice */
3810 s = &dev->subdevices[1];
3811 if (thisboard->ao_nchan) {
3812 s->type = COMEDI_SUBD_AO;
3813 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
3814 SDF_GROUND | SDF_CMD_WRITE;
3815 s->n_chan = thisboard->ao_nchan;
3816 s->maxdata = (1 << thisboard->ao_bits) - 1;
3817 s->range_table = thisboard->ao_range_table;
9c7a00f5 3818 s->insn_write = ao_winsn;
f88f75fe
HS
3819 s->insn_read = comedi_readback_insn_read;
3820
3821 ret = comedi_alloc_subdev_readback(s);
3822 if (ret)
3823 return ret;
3824
9c7a00f5
IA
3825 if (ao_cmd_is_supported(thisboard)) {
3826 dev->write_subdev = s;
3827 s->do_cmdtest = ao_cmdtest;
3828 s->do_cmd = ao_cmd;
3829 s->len_chanlist = thisboard->ao_nchan;
3830 s->cancel = ao_cancel;
3831 }
3832 } else {
3833 s->type = COMEDI_SUBD_UNUSED;
3834 }
3835
3836 /* digital input */
3837 s = &dev->subdevices[2];
3838 if (thisboard->layout == LAYOUT_64XX) {
3839 s->type = COMEDI_SUBD_DI;
3840 s->subdev_flags = SDF_READABLE;
3841 s->n_chan = 4;
3842 s->maxdata = 1;
3843 s->range_table = &range_digital;
3844 s->insn_bits = di_rbits;
3845 } else
3846 s->type = COMEDI_SUBD_UNUSED;
3847
3848 /* digital output */
3849 if (thisboard->layout == LAYOUT_64XX) {
3850 s = &dev->subdevices[3];
3851 s->type = COMEDI_SUBD_DO;
3852 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
3853 s->n_chan = 4;
3854 s->maxdata = 1;
3855 s->range_table = &range_digital;
3856 s->insn_bits = do_wbits;
3857 } else
3858 s->type = COMEDI_SUBD_UNUSED;
3859
3860 /* 8255 */
3861 s = &dev->subdevices[4];
3862 if (thisboard->has_8255) {
3863 if (thisboard->layout == LAYOUT_4020) {
e6439a45 3864 ret = subdev_8255_init(dev, s, dio_callback_4020,
da261e1d 3865 I8255_4020_REG);
9c7a00f5 3866 } else {
5c19084b
HS
3867 ret = subdev_8255_mm_init(dev, s, NULL,
3868 DIO_8255_OFFSET);
9c7a00f5 3869 }
e6439a45
HS
3870 if (ret)
3871 return ret;
3872 } else {
9c7a00f5 3873 s->type = COMEDI_SUBD_UNUSED;
e6439a45 3874 }
9c7a00f5
IA
3875
3876 /* 8 channel dio for 60xx */
3877 s = &dev->subdevices[5];
3878 if (thisboard->layout == LAYOUT_60XX) {
3879 s->type = COMEDI_SUBD_DIO;
3880 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
3881 s->n_chan = 8;
3882 s->maxdata = 1;
3883 s->range_table = &range_digital;
3884 s->insn_config = dio_60xx_config_insn;
3885 s->insn_bits = dio_60xx_wbits;
3886 } else
3887 s->type = COMEDI_SUBD_UNUSED;
3888
3889 /* caldac */
3890 s = &dev->subdevices[6];
3891 s->type = COMEDI_SUBD_CALIB;
3892 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
3893 s->n_chan = 8;
3894 if (thisboard->layout == LAYOUT_4020)
3895 s->maxdata = 0xfff;
3896 else
3897 s->maxdata = 0xff;
3898 s->insn_read = calib_read_insn;
3899 s->insn_write = calib_write_insn;
3900 for (i = 0; i < s->n_chan; i++)
3901 caldac_write(dev, i, s->maxdata / 2);
3902
3903 /* 2 channel ad8402 potentiometer */
3904 s = &dev->subdevices[7];
3905 if (thisboard->layout == LAYOUT_64XX) {
3906 s->type = COMEDI_SUBD_CALIB;
3907 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
3908 s->n_chan = 2;
3909 s->insn_read = ad8402_read_insn;
3910 s->insn_write = ad8402_write_insn;
3911 s->maxdata = 0xff;
3912 for (i = 0; i < s->n_chan; i++)
3913 ad8402_write(dev, i, s->maxdata / 2);
3914 } else
3915 s->type = COMEDI_SUBD_UNUSED;
3916
3917 /* serial EEPROM, if present */
3918 s = &dev->subdevices[8];
3919 if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
3920 s->type = COMEDI_SUBD_MEMORY;
3921 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
3922 s->n_chan = 128;
3923 s->maxdata = 0xffff;
3924 s->insn_read = eeprom_read_insn;
3925 } else
3926 s->type = COMEDI_SUBD_UNUSED;
3927
3928 /* user counter subd XXX */
3929 s = &dev->subdevices[9];
3930 s->type = COMEDI_SUBD_UNUSED;
3931
3932 return 0;
3933}
3934
a690b7e5 3935static int auto_attach(struct comedi_device *dev,
463740d4 3936 unsigned long context)
a299d881 3937{
a299d881 3938 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
463740d4
HS
3939 const struct pcidas64_board *thisboard = NULL;
3940 struct pcidas64_private *devpriv;
a299d881
IA
3941 uint32_t local_range, local_decode;
3942 int retval;
3943
463740d4
HS
3944 if (context < ARRAY_SIZE(pcidas64_boards))
3945 thisboard = &pcidas64_boards[context];
3946 if (!thisboard)
3947 return -ENODEV;
3948 dev->board_ptr = thisboard;
a299d881 3949
0bdab509 3950 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
a299d881
IA
3951 if (!devpriv)
3952 return -ENOMEM;
a299d881 3953
818f569f
HS
3954 retval = comedi_pci_enable(dev);
3955 if (retval)
3956 return retval;
a299d881
IA
3957 pci_set_master(pcidev);
3958
3959 /* Initialize dev->board_name */
3960 dev->board_name = thisboard->name;
3961
81d985a1
HS
3962 devpriv->main_phys_iobase = pci_resource_start(pcidev, 2);
3963 devpriv->dio_counter_phys_iobase = pci_resource_start(pcidev, 3);
a299d881 3964
c71b2e52
HS
3965 devpriv->plx9080_iobase = pci_ioremap_bar(pcidev, 0);
3966 devpriv->main_iobase = pci_ioremap_bar(pcidev, 2);
9ebd1028 3967 dev->mmio = pci_ioremap_bar(pcidev, 3);
a299d881 3968
9ebd1028 3969 if (!devpriv->plx9080_iobase || !devpriv->main_iobase || !dev->mmio) {
a299d881
IA
3970 dev_warn(dev->class_dev, "failed to remap io memory\n");
3971 return -ENOMEM;
3972 }
3973
a299d881
IA
3974 /* figure out what local addresses are */
3975 local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) &
3976 LRNG_MEM_MASK;
3977 local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) &
3978 local_range & LMAP_MEM_MASK;
3979 devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase &
3980 ~local_range) | local_decode;
3981 local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) &
3982 LRNG_MEM_MASK;
3983 local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) &
3984 local_range & LMAP_MEM_MASK;
3985 devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase &
3986 ~local_range) | local_decode;
3987
a299d881
IA
3988 retval = alloc_and_init_dma_members(dev);
3989 if (retval < 0)
3990 return retval;
3991
3992 devpriv->hw_revision =
3993 hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG));
3994 dev_dbg(dev->class_dev, "stc hardware revision %i\n",
3995 devpriv->hw_revision);
3996 init_plx9080(dev);
3997 init_stc_registers(dev);
71e06874
HS
3998
3999 retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
4000 dev->board_name, dev);
4001 if (retval) {
a299d881
IA
4002 dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
4003 pcidev->irq);
71e06874 4004 return retval;
a299d881
IA
4005 }
4006 dev->irq = pcidev->irq;
4007 dev_dbg(dev->class_dev, "irq %u\n", dev->irq);
4008
4009 retval = setup_subdevices(dev);
4010 if (retval < 0)
4011 return retval;
4012
4013 return 0;
4014}
4015
4016static void detach(struct comedi_device *dev)
4017{
a299d881 4018 struct pcidas64_private *devpriv = dev->private;
a299d881
IA
4019
4020 if (dev->irq)
4021 free_irq(dev->irq, dev);
4022 if (devpriv) {
f9804323
HS
4023 if (devpriv->plx9080_iobase) {
4024 disable_plx_interrupts(dev);
4025 iounmap(devpriv->plx9080_iobase);
a299d881 4026 }
f9804323
HS
4027 if (devpriv->main_iobase)
4028 iounmap(devpriv->main_iobase);
4029 if (dev->mmio)
4030 iounmap(dev->mmio);
a299d881 4031 }
7f072f54 4032 comedi_pci_disable(dev);
f9804323 4033 cb_pcidas64_free_dma(dev);
a299d881
IA
4034}
4035
bdc7cc50
HS
4036static struct comedi_driver cb_pcidas64_driver = {
4037 .driver_name = "cb_pcidas64",
4038 .module = THIS_MODULE,
b91524ee 4039 .auto_attach = auto_attach,
bdc7cc50
HS
4040 .detach = detach,
4041};
4042
a690b7e5 4043static int cb_pcidas64_pci_probe(struct pci_dev *dev,
b8f4ac23 4044 const struct pci_device_id *id)
bdc7cc50 4045{
b8f4ac23
HS
4046 return comedi_pci_auto_config(dev, &cb_pcidas64_driver,
4047 id->driver_data);
bdc7cc50
HS
4048}
4049
41e043fc 4050static const struct pci_device_id cb_pcidas64_pci_table[] = {
463740d4
HS
4051 { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 },
4052 { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 },
4053 { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 },
4054 { PCI_VDEVICE(CB, 0x0036), BOARD_PCIDAS64_M2_16 },
4055 { PCI_VDEVICE(CB, 0x0037), BOARD_PCIDAS64_M3_16 },
4056 { PCI_VDEVICE(CB, 0x0052), BOARD_PCIDAS4020_12 },
4057 { PCI_VDEVICE(CB, 0x005d), BOARD_PCIDAS6023 },
4058 { PCI_VDEVICE(CB, 0x005e), BOARD_PCIDAS6025 },
4059 { PCI_VDEVICE(CB, 0x005f), BOARD_PCIDAS6030 },
4060 { PCI_VDEVICE(CB, 0x0060), BOARD_PCIDAS6031 },
4061 { PCI_VDEVICE(CB, 0x0061), BOARD_PCIDAS6032 },
4062 { PCI_VDEVICE(CB, 0x0062), BOARD_PCIDAS6033 },
4063 { PCI_VDEVICE(CB, 0x0063), BOARD_PCIDAS6034 },
4064 { PCI_VDEVICE(CB, 0x0064), BOARD_PCIDAS6035 },
4065 { PCI_VDEVICE(CB, 0x0065), BOARD_PCIDAS6040 },
4066 { PCI_VDEVICE(CB, 0x0066), BOARD_PCIDAS6052 },
4067 { PCI_VDEVICE(CB, 0x0067), BOARD_PCIDAS6070 },
4068 { PCI_VDEVICE(CB, 0x0068), BOARD_PCIDAS6071 },
4069 { PCI_VDEVICE(CB, 0x006f), BOARD_PCIDAS6036 },
4070 { PCI_VDEVICE(CB, 0x0078), BOARD_PCIDAS6013 },
4071 { PCI_VDEVICE(CB, 0x0079), BOARD_PCIDAS6014 },
bdc7cc50
HS
4072 { 0 }
4073};
4074MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table);
4075
4076static struct pci_driver cb_pcidas64_pci_driver = {
4077 .name = "cb_pcidas64",
4078 .id_table = cb_pcidas64_pci_table,
4079 .probe = cb_pcidas64_pci_probe,
9901a4d7 4080 .remove = comedi_pci_auto_unconfig,
bdc7cc50
HS
4081};
4082module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver);
4083
90f703d3
AT
4084MODULE_AUTHOR("Comedi http://www.comedi.org");
4085MODULE_DESCRIPTION("Comedi low-level driver");
4086MODULE_LICENSE("GPL");
This page took 0.921599 seconds and 5 git commands to generate.