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