Merge branch 'for-linus' of git://github.com/schandinat/linux-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.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 1239
727b286b
AT
1240static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev,
1241 const struct pci_device_id *ent)
1242{
1243 return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name);
1244}
1245
1246static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev)
1247{
1248 comedi_pci_auto_unconfig(dev);
1249}
1250
1251static struct pci_driver driver_cb_pcidas_pci_driver = {
1252 .id_table = pcidas64_pci_table,
1253 .probe = &driver_cb_pcidas_pci_probe,
1254 .remove = __devexit_p(&driver_cb_pcidas_pci_remove)
1255};
1256
1257static int __init driver_cb_pcidas_init_module(void)
1258{
1259 int retval;
1260
1261 retval = comedi_driver_register(&driver_cb_pcidas);
1262 if (retval < 0)
1263 return retval;
1264
1265 driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name;
1266 return pci_register_driver(&driver_cb_pcidas_pci_driver);
1267}
1268
1269static void __exit driver_cb_pcidas_cleanup_module(void)
1270{
1271 pci_unregister_driver(&driver_cb_pcidas_pci_driver);
1272 comedi_driver_unregister(&driver_cb_pcidas);
1273}
1274
1275module_init(driver_cb_pcidas_init_module);
1276module_exit(driver_cb_pcidas_cleanup_module);
88b12a9a 1277
814900c9 1278static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
0a85b6f0 1279 unsigned int range_index)
88b12a9a 1280{
1f6325d6 1281 const struct comedi_krange *range =
0a85b6f0 1282 &board(dev)->ai_range_table->range[range_index];
88b12a9a
FMH
1283 unsigned int bits = 0;
1284
1285 switch (range->max) {
1286 case 10000000:
1287 bits = 0x000;
1288 break;
1289 case 5000000:
1290 bits = 0x100;
1291 break;
1292 case 2000000:
1293 case 2500000:
1294 bits = 0x200;
1295 break;
1296 case 1000000:
1297 case 1250000:
1298 bits = 0x300;
1299 break;
1300 case 500000:
1301 bits = 0x400;
1302 break;
1303 case 200000:
1304 case 250000:
1305 bits = 0x500;
1306 break;
1307 case 100000:
1308 bits = 0x600;
1309 break;
1310 case 50000:
1311 bits = 0x700;
1312 break;
1313 default:
1314 comedi_error(dev, "bug! in ai_range_bits_6xxx");
1315 break;
1316 }
1317 if (range->min == 0)
1318 bits += 0x900;
1319 return bits;
1320}
1321
da91b269 1322static unsigned int hw_revision(const struct comedi_device *dev,
0a85b6f0 1323 uint16_t hw_status_bits)
88b12a9a
FMH
1324{
1325 if (board(dev)->layout == LAYOUT_4020)
1326 return (hw_status_bits >> 13) & 0x7;
1327
1328 return (hw_status_bits >> 12) & 0xf;
1329}
1330
0a85b6f0
MT
1331static void set_dac_range_bits(struct comedi_device *dev,
1332 volatile uint16_t * bits, unsigned int channel,
1333 unsigned int range)
88b12a9a
FMH
1334{
1335 unsigned int code = board(dev)->ao_range_code[range];
1336
1337 if (channel > 1)
1338 comedi_error(dev, "bug! bad channel?");
1339 if (code & ~0x3)
1340 comedi_error(dev, "bug! bad range code?");
1341
1342 *bits &= ~(0x3 << (2 * channel));
1343 *bits |= code << (2 * channel);
1344};
1345
da91b269 1346static inline int ao_cmd_is_supported(const struct pcidas64_board *board)
88b12a9a
FMH
1347{
1348 return board->ao_nchan && board->layout != LAYOUT_4020;
1349}
1350
9ef4dea6 1351/* initialize plx9080 chip */
da91b269 1352static void init_plx9080(struct comedi_device *dev)
88b12a9a
FMH
1353{
1354 uint32_t bits;
f31d0008 1355 void __iomem *plx_iobase = priv(dev)->plx9080_iobase;
88b12a9a
FMH
1356
1357 priv(dev)->plx_control_bits =
0a85b6f0 1358 readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
88b12a9a 1359
9ef4dea6 1360 /* plx9080 dump */
88b12a9a 1361 DEBUG_PRINT(" plx interrupt status 0x%x\n",
0a85b6f0 1362 readl(plx_iobase + PLX_INTRCS_REG));
88b12a9a
FMH
1363 DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
1364 DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits);
1365 DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n",
0a85b6f0 1366 readl(plx_iobase + PLX_MARB_REG));
88b12a9a 1367 DEBUG_PRINT(" plx region0 reg 0x%x\n",
0a85b6f0 1368 readl(plx_iobase + PLX_REGION0_REG));
88b12a9a 1369 DEBUG_PRINT(" plx region1 reg 0x%x\n",
0a85b6f0 1370 readl(plx_iobase + PLX_REGION1_REG));
88b12a9a
FMH
1371
1372 DEBUG_PRINT(" plx revision 0x%x\n",
0a85b6f0 1373 readl(plx_iobase + PLX_REVISION_REG));
88b12a9a 1374 DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
0a85b6f0 1375 readl(plx_iobase + PLX_DMA0_MODE_REG));
88b12a9a 1376 DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
0a85b6f0 1377 readl(plx_iobase + PLX_DMA1_MODE_REG));
88b12a9a 1378 DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
0a85b6f0 1379 readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
88b12a9a 1380 DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
0a85b6f0 1381 readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
88b12a9a 1382 DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
0a85b6f0 1383 readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
88b12a9a 1384 DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
0a85b6f0 1385 readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
88b12a9a 1386 DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
0a85b6f0 1387 readb(plx_iobase + PLX_DMA0_CS_REG));
88b12a9a 1388 DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
0a85b6f0 1389 readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
88b12a9a
FMH
1390 DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
1391
1392#ifdef __BIG_ENDIAN
1393 bits = BIGEND_DMA0 | BIGEND_DMA1;
1394#else
1395 bits = 0;
1396#endif
1397 writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
1398
1399 disable_plx_interrupts(dev);
1400
1401 abort_dma(dev, 0);
1402 abort_dma(dev, 1);
1403
9ef4dea6 1404 /* configure dma0 mode */
88b12a9a 1405 bits = 0;
9ef4dea6 1406 /* enable ready input, not sure if this is necessary */
88b12a9a 1407 bits |= PLX_DMA_EN_READYIN_BIT;
9ef4dea6 1408 /* enable bterm, not sure if this is necessary */
88b12a9a 1409 bits |= PLX_EN_BTERM_BIT;
9ef4dea6 1410 /* enable dma chaining */
88b12a9a 1411 bits |= PLX_EN_CHAIN_BIT;
9ef4dea6 1412 /* enable interrupt on dma done (probably don't need this, since chain never finishes) */
88b12a9a 1413 bits |= PLX_EN_DMA_DONE_INTR_BIT;
9ef4dea6 1414 /* don't increment local address during transfers (we are transferring from a fixed fifo register) */
88b12a9a 1415 bits |= PLX_LOCAL_ADDR_CONST_BIT;
9ef4dea6 1416 /* route dma interrupt to pci bus */
88b12a9a 1417 bits |= PLX_DMA_INTR_PCI_BIT;
9ef4dea6 1418 /* enable demand mode */
88b12a9a 1419 bits |= PLX_DEMAND_MODE_BIT;
9ef4dea6 1420 /* enable local burst mode */
88b12a9a 1421 bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
9ef4dea6 1422 /* 4020 uses 32 bit dma */
88b12a9a
FMH
1423 if (board(dev)->layout == LAYOUT_4020) {
1424 bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
9ef4dea6 1425 } else { /* localspace0 bus is 16 bits wide */
88b12a9a
FMH
1426 bits |= PLX_LOCAL_BUS_16_WIDE_BITS;
1427 }
1428 writel(bits, plx_iobase + PLX_DMA1_MODE_REG);
1429 if (ao_cmd_is_supported(board(dev)))
1430 writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
1431
9ef4dea6 1432 /* enable interrupts on plx 9080 */
88b12a9a 1433 priv(dev)->plx_intcsr_bits |=
0a85b6f0
MT
1434 ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
1435 ICS_DMA0_E | ICS_DMA1_E;
88b12a9a 1436 writel(priv(dev)->plx_intcsr_bits,
0a85b6f0 1437 priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
88b12a9a
FMH
1438}
1439
1440/* Allocate and initialize the subdevice structures.
1441 */
da91b269 1442static int setup_subdevices(struct comedi_device *dev)
88b12a9a 1443{
34c43922 1444 struct comedi_subdevice *s;
f31d0008 1445 void __iomem *dio_8255_iobase;
88b12a9a
FMH
1446 int i;
1447
1448 if (alloc_subdevices(dev, 10) < 0)
1449 return -ENOMEM;
1450
1451 s = dev->subdevices + 0;
1452 /* analog input subdevice */
1453 dev->read_subdev = s;
1454 s->type = COMEDI_SUBD_AI;
1455 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
1456 if (board(dev)->layout == LAYOUT_60XX)
1457 s->subdev_flags |= SDF_COMMON | SDF_DIFF;
1458 else if (board(dev)->layout == LAYOUT_64XX)
1459 s->subdev_flags |= SDF_DIFF;
1460 /* XXX Number of inputs in differential mode is ignored */
1461 s->n_chan = board(dev)->ai_se_chans;
1462 s->len_chanlist = 0x2000;
1463 s->maxdata = (1 << board(dev)->ai_bits) - 1;
1464 s->range_table = board(dev)->ai_range_table;
1465 s->insn_read = ai_rinsn;
1466 s->insn_config = ai_config_insn;
1467 s->do_cmd = ai_cmd;
1468 s->do_cmdtest = ai_cmdtest;
1469 s->cancel = ai_cancel;
1470 if (board(dev)->layout == LAYOUT_4020) {
88b12a9a 1471 uint8_t data;
9ef4dea6 1472 /* set adc to read from inputs (not internal calibration sources) */
88b12a9a 1473 priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4);
9ef4dea6 1474 /* set channels to +-5 volt input ranges */
88b12a9a
FMH
1475 for (i = 0; i < s->n_chan; i++)
1476 priv(dev)->i2c_cal_range_bits |= attenuate_bit(i);
1477 data = priv(dev)->i2c_cal_range_bits;
1478 i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
1479 }
1480
1481 /* analog output subdevice */
1482 s = dev->subdevices + 1;
1483 if (board(dev)->ao_nchan) {
1484 s->type = COMEDI_SUBD_AO;
1485 s->subdev_flags =
0a85b6f0 1486 SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
88b12a9a
FMH
1487 s->n_chan = board(dev)->ao_nchan;
1488 s->maxdata = (1 << board(dev)->ao_bits) - 1;
1489 s->range_table = board(dev)->ao_range_table;
1490 s->insn_read = ao_readback_insn;
1491 s->insn_write = ao_winsn;
1492 if (ao_cmd_is_supported(board(dev))) {
1493 dev->write_subdev = s;
1494 s->do_cmdtest = ao_cmdtest;
1495 s->do_cmd = ao_cmd;
1496 s->len_chanlist = board(dev)->ao_nchan;
1497 s->cancel = ao_cancel;
1498 }
1499 } else {
1500 s->type = COMEDI_SUBD_UNUSED;
1501 }
1502
9ef4dea6 1503 /* digital input */
88b12a9a
FMH
1504 s = dev->subdevices + 2;
1505 if (board(dev)->layout == LAYOUT_64XX) {
1506 s->type = COMEDI_SUBD_DI;
1507 s->subdev_flags = SDF_READABLE;
1508 s->n_chan = 4;
1509 s->maxdata = 1;
1510 s->range_table = &range_digital;
1511 s->insn_bits = di_rbits;
1512 } else
1513 s->type = COMEDI_SUBD_UNUSED;
1514
9ef4dea6 1515 /* digital output */
88b12a9a
FMH
1516 if (board(dev)->layout == LAYOUT_64XX) {
1517 s = dev->subdevices + 3;
1518 s->type = COMEDI_SUBD_DO;
1519 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1520 s->n_chan = 4;
1521 s->maxdata = 1;
1522 s->range_table = &range_digital;
1523 s->insn_bits = do_wbits;
1524 } else
1525 s->type = COMEDI_SUBD_UNUSED;
1526
1527 /* 8255 */
1528 s = dev->subdevices + 4;
1529 if (board(dev)->has_8255) {
1530 if (board(dev)->layout == LAYOUT_4020) {
1531 dio_8255_iobase =
0a85b6f0 1532 priv(dev)->main_iobase + I8255_4020_REG;
88b12a9a 1533 subdev_8255_init(dev, s, dio_callback_4020,
0a85b6f0 1534 (unsigned long)dio_8255_iobase);
88b12a9a
FMH
1535 } else {
1536 dio_8255_iobase =
0a85b6f0 1537 priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
88b12a9a 1538 subdev_8255_init(dev, s, dio_callback,
0a85b6f0 1539 (unsigned long)dio_8255_iobase);
88b12a9a
FMH
1540 }
1541 } else
1542 s->type = COMEDI_SUBD_UNUSED;
1543
9ef4dea6 1544 /* 8 channel dio for 60xx */
88b12a9a
FMH
1545 s = dev->subdevices + 5;
1546 if (board(dev)->layout == LAYOUT_60XX) {
1547 s->type = COMEDI_SUBD_DIO;
1548 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1549 s->n_chan = 8;
1550 s->maxdata = 1;
1551 s->range_table = &range_digital;
1552 s->insn_config = dio_60xx_config_insn;
1553 s->insn_bits = dio_60xx_wbits;
1554 } else
1555 s->type = COMEDI_SUBD_UNUSED;
1556
9ef4dea6 1557 /* caldac */
88b12a9a
FMH
1558 s = dev->subdevices + 6;
1559 s->type = COMEDI_SUBD_CALIB;
1560 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1561 s->n_chan = 8;
1562 if (board(dev)->layout == LAYOUT_4020)
1563 s->maxdata = 0xfff;
1564 else
1565 s->maxdata = 0xff;
1566 s->insn_read = calib_read_insn;
1567 s->insn_write = calib_write_insn;
1568 for (i = 0; i < s->n_chan; i++)
1569 caldac_write(dev, i, s->maxdata / 2);
1570
9ef4dea6 1571 /* 2 channel ad8402 potentiometer */
88b12a9a
FMH
1572 s = dev->subdevices + 7;
1573 if (board(dev)->layout == LAYOUT_64XX) {
1574 s->type = COMEDI_SUBD_CALIB;
1575 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1576 s->n_chan = 2;
1577 s->insn_read = ad8402_read_insn;
1578 s->insn_write = ad8402_write_insn;
1579 s->maxdata = 0xff;
1580 for (i = 0; i < s->n_chan; i++)
1581 ad8402_write(dev, i, s->maxdata / 2);
1582 } else
1583 s->type = COMEDI_SUBD_UNUSED;
1584
9ef4dea6 1585 /* serial EEPROM, if present */
88b12a9a
FMH
1586 s = dev->subdevices + 8;
1587 if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
1588 s->type = COMEDI_SUBD_MEMORY;
1589 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1590 s->n_chan = 128;
1591 s->maxdata = 0xffff;
1592 s->insn_read = eeprom_read_insn;
1593 } else
1594 s->type = COMEDI_SUBD_UNUSED;
1595
9ef4dea6 1596 /* user counter subd XXX */
88b12a9a
FMH
1597 s = dev->subdevices + 9;
1598 s->type = COMEDI_SUBD_UNUSED;
1599
1600 return 0;
1601}
1602
da91b269 1603static void disable_plx_interrupts(struct comedi_device *dev)
88b12a9a
FMH
1604{
1605 priv(dev)->plx_intcsr_bits = 0;
1606 writel(priv(dev)->plx_intcsr_bits,
0a85b6f0 1607 priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
88b12a9a
FMH
1608}
1609
da91b269 1610static void init_stc_registers(struct comedi_device *dev)
88b12a9a
FMH
1611{
1612 uint16_t bits;
1613 unsigned long flags;
1614
5f74ea14 1615 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 1616
9ef4dea6 1617 /* bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX */
88b12a9a
FMH
1618 if (1)
1619 priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
1620 writew(priv(dev)->adc_control1_bits,
0a85b6f0 1621 priv(dev)->main_iobase + ADC_CONTROL1_REG);
88b12a9a 1622
9ef4dea6 1623 /* 6402/16 manual says this register must be initialized to 0xff? */
88b12a9a
FMH
1624 writew(0xff, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
1625
1626 bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
1627 if (board(dev)->layout == LAYOUT_4020)
1628 bits |= INTERNAL_CLOCK_4020_BITS;
1629 priv(dev)->hw_config_bits |= bits;
1630 writew(priv(dev)->hw_config_bits,
0a85b6f0 1631 priv(dev)->main_iobase + HW_CONFIG_REG);
88b12a9a
FMH
1632
1633 writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG);
1634 writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
1635
5f74ea14 1636 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 1637
9ef4dea6 1638 /* set fifos to maximum size */
88b12a9a
FMH
1639 priv(dev)->fifo_size_bits |= DAC_FIFO_BITS;
1640 set_ai_fifo_segment_length(dev,
0a85b6f0 1641 board(dev)->ai_fifo->max_segment_length);
88b12a9a
FMH
1642
1643 priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
1644 priv(dev)->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
0a85b6f0 1645 EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
88b12a9a 1646 writew(priv(dev)->intr_enable_bits,
0a85b6f0 1647 priv(dev)->main_iobase + INTR_ENABLE_REG);
88b12a9a
FMH
1648
1649 disable_ai_pacing(dev);
1650};
1651
f31d0008 1652static int alloc_and_init_dma_members(struct comedi_device *dev)
88b12a9a
FMH
1653{
1654 int i;
1655
9ef4dea6 1656 /* alocate pci dma buffers */
88b12a9a
FMH
1657 for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
1658 priv(dev)->ai_buffer[i] =
0a85b6f0
MT
1659 pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
1660 &priv(dev)->ai_buffer_bus_addr[i]);
90cae794 1661 if (priv(dev)->ai_buffer[i] == NULL)
88b12a9a 1662 return -ENOMEM;
90cae794 1663
88b12a9a
FMH
1664 }
1665 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
1666 if (ao_cmd_is_supported(board(dev))) {
1667 priv(dev)->ao_buffer[i] =
0a85b6f0
MT
1668 pci_alloc_consistent(priv(dev)->hw_dev,
1669 DMA_BUFFER_SIZE,
1670 &priv(dev)->
1671 ao_buffer_bus_addr[i]);
90cae794 1672 if (priv(dev)->ao_buffer[i] == NULL)
88b12a9a 1673 return -ENOMEM;
90cae794 1674
88b12a9a
FMH
1675 }
1676 }
9ef4dea6 1677 /* allocate dma descriptors */
88b12a9a 1678 priv(dev)->ai_dma_desc =
0a85b6f0
MT
1679 pci_alloc_consistent(priv(dev)->hw_dev,
1680 sizeof(struct plx_dma_desc) *
1681 ai_dma_ring_count(board(dev)),
1682 &priv(dev)->ai_dma_desc_bus_addr);
90cae794 1683 if (priv(dev)->ai_dma_desc == NULL)
88b12a9a 1684 return -ENOMEM;
90cae794 1685
88b12a9a 1686 DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n",
0a85b6f0 1687 priv(dev)->ai_dma_desc_bus_addr);
88b12a9a
FMH
1688 if (ao_cmd_is_supported(board(dev))) {
1689 priv(dev)->ao_dma_desc =
0a85b6f0
MT
1690 pci_alloc_consistent(priv(dev)->hw_dev,
1691 sizeof(struct plx_dma_desc) *
1692 AO_DMA_RING_COUNT,
1693 &priv(dev)->ao_dma_desc_bus_addr);
90cae794 1694 if (priv(dev)->ao_dma_desc == NULL)
88b12a9a 1695 return -ENOMEM;
90cae794 1696
88b12a9a 1697 DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n",
0a85b6f0 1698 priv(dev)->ao_dma_desc_bus_addr);
88b12a9a 1699 }
9ef4dea6 1700 /* initialize dma descriptors */
88b12a9a
FMH
1701 for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
1702 priv(dev)->ai_dma_desc[i].pci_start_addr =
0a85b6f0 1703 cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]);
88b12a9a
FMH
1704 if (board(dev)->layout == LAYOUT_4020)
1705 priv(dev)->ai_dma_desc[i].local_start_addr =
0a85b6f0
MT
1706 cpu_to_le32(priv(dev)->local1_iobase +
1707 ADC_FIFO_REG);
88b12a9a
FMH
1708 else
1709 priv(dev)->ai_dma_desc[i].local_start_addr =
0a85b6f0
MT
1710 cpu_to_le32(priv(dev)->local0_iobase +
1711 ADC_FIFO_REG);
88b12a9a
FMH
1712 priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
1713 priv(dev)->ai_dma_desc[i].next =
0a85b6f0
MT
1714 cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i +
1715 1) %
1716 ai_dma_ring_count
1717 (board
1718 (dev))) *
1719 sizeof(priv(dev)->ai_dma_desc[0])) |
1720 PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
1721 PLX_XFER_LOCAL_TO_PCI);
88b12a9a
FMH
1722 }
1723 if (ao_cmd_is_supported(board(dev))) {
1724 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
1725 priv(dev)->ao_dma_desc[i].pci_start_addr =
0a85b6f0 1726 cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]);
88b12a9a 1727 priv(dev)->ao_dma_desc[i].local_start_addr =
0a85b6f0
MT
1728 cpu_to_le32(priv(dev)->local0_iobase +
1729 DAC_FIFO_REG);
88b12a9a 1730 priv(dev)->ao_dma_desc[i].transfer_size =
0a85b6f0 1731 cpu_to_le32(0);
88b12a9a 1732 priv(dev)->ao_dma_desc[i].next =
0a85b6f0
MT
1733 cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr +
1734 ((i + 1) % (AO_DMA_RING_COUNT)) *
1735 sizeof(priv(dev)->ao_dma_desc[0])) |
1736 PLX_DESC_IN_PCI_BIT |
1737 PLX_INTR_TERM_COUNT);
88b12a9a
FMH
1738 }
1739 }
1740 return 0;
1741}
1742
da91b269 1743static inline void warn_external_queue(struct comedi_device *dev)
88b12a9a
FMH
1744{
1745 comedi_error(dev,
0a85b6f0 1746 "AO command and AI external channel queue cannot be used simultaneously.");
88b12a9a 1747 comedi_error(dev,
0a85b6f0 1748 "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
88b12a9a
FMH
1749}
1750
1751/*
1752 * Attach is called by the Comedi core to configure the driver
1753 * for a particular board.
1754 */
0707bb04 1755static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
88b12a9a 1756{
20fb2280 1757 struct pci_dev *pcidev = NULL;
88b12a9a
FMH
1758 int index;
1759 uint32_t local_range, local_decode;
1760 int retval;
1761
1762 printk("comedi%d: cb_pcidas64\n", dev->minor);
1763
1764/*
1765 * Allocate the private structure area.
1766 */
450032a3 1767 if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0)
88b12a9a
FMH
1768 return -ENOMEM;
1769
1770/*
1771 * Probe the device to determine what device in the series it is.
1772 */
1773
20fb2280 1774 for_each_pci_dev(pcidev) {
9ef4dea6 1775 /* is it not a computer boards card? */
88b12a9a
FMH
1776 if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
1777 continue;
9ef4dea6 1778 /* loop through cards supported by this driver */
8629efa4 1779 for (index = 0; index < ARRAY_SIZE(pcidas64_boards); index++) {
88b12a9a
FMH
1780 if (pcidas64_boards[index].device_id != pcidev->device)
1781 continue;
9ef4dea6 1782 /* was a particular bus/slot requested? */
88b12a9a 1783 if (it->options[0] || it->options[1]) {
9ef4dea6 1784 /* are we on the wrong bus/slot? */
88b12a9a 1785 if (pcidev->bus->number != it->options[0] ||
0a85b6f0 1786 PCI_SLOT(pcidev->devfn) != it->options[1]) {
88b12a9a
FMH
1787 continue;
1788 }
1789 }
1790 priv(dev)->hw_dev = pcidev;
1791 dev->board_ptr = pcidas64_boards + index;
1792 break;
1793 }
1794 if (dev->board_ptr)
1795 break;
1796 }
1797
1798 if (dev->board_ptr == NULL) {
0a85b6f0
MT
1799 printk
1800 ("No supported ComputerBoards/MeasurementComputing card found\n");
88b12a9a
FMH
1801 return -EIO;
1802 }
1803
1804 printk("Found %s on bus %i, slot %i\n", board(dev)->name,
0a85b6f0 1805 pcidev->bus->number, PCI_SLOT(pcidev->devfn));
88b12a9a
FMH
1806
1807 if (comedi_pci_enable(pcidev, driver_cb_pcidas.driver_name)) {
1808 printk(KERN_WARNING
0a85b6f0 1809 " failed to enable PCI device and request regions\n");
88b12a9a
FMH
1810 return -EIO;
1811 }
1812 pci_set_master(pcidev);
1813
9ef4dea6 1814 /* Initialize dev->board_name */
88b12a9a
FMH
1815 dev->board_name = board(dev)->name;
1816
1817 priv(dev)->plx9080_phys_iobase =
0a85b6f0 1818 pci_resource_start(pcidev, PLX9080_BADDRINDEX);
88b12a9a 1819 priv(dev)->main_phys_iobase =
0a85b6f0 1820 pci_resource_start(pcidev, MAIN_BADDRINDEX);
88b12a9a 1821 priv(dev)->dio_counter_phys_iobase =
0a85b6f0 1822 pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
88b12a9a 1823
9ef4dea6 1824 /* remap, won't work with 2.0 kernels but who cares */
88b12a9a 1825 priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
0a85b6f0
MT
1826 pci_resource_len(pcidev,
1827 PLX9080_BADDRINDEX));
1828 priv(dev)->main_iobase =
1829 ioremap(priv(dev)->main_phys_iobase,
1830 pci_resource_len(pcidev, MAIN_BADDRINDEX));
88b12a9a 1831 priv(dev)->dio_counter_iobase =
0a85b6f0
MT
1832 ioremap(priv(dev)->dio_counter_phys_iobase,
1833 pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
88b12a9a
FMH
1834
1835 if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase
0a85b6f0 1836 || !priv(dev)->dio_counter_iobase) {
88b12a9a
FMH
1837 printk(" failed to remap io memory\n");
1838 return -ENOMEM;
1839 }
1840
1841 DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
1842 DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase);
1843 DEBUG_PRINT(" diocounter remapped to 0x%p\n",
0a85b6f0 1844 priv(dev)->dio_counter_iobase);
88b12a9a 1845
9ef4dea6 1846 /* figure out what local addresses are */
88b12a9a 1847 local_range =
0a85b6f0 1848 readl(priv(dev)->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK;
88b12a9a 1849 local_decode =
0a85b6f0
MT
1850 readl(priv(dev)->plx9080_iobase +
1851 PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK;
88b12a9a 1852 priv(dev)->local0_iobase =
0a85b6f0
MT
1853 ((uint32_t) priv(dev)->main_phys_iobase & ~local_range) |
1854 local_decode;
88b12a9a 1855 local_range =
0a85b6f0 1856 readl(priv(dev)->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK;
88b12a9a 1857 local_decode =
0a85b6f0
MT
1858 readl(priv(dev)->plx9080_iobase +
1859 PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK;
88b12a9a 1860 priv(dev)->local1_iobase =
0a85b6f0
MT
1861 ((uint32_t) priv(dev)->dio_counter_phys_iobase & ~local_range) |
1862 local_decode;
88b12a9a
FMH
1863
1864 DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase);
1865 DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase);
1866
1867 retval = alloc_and_init_dma_members(dev);
1868 if (retval < 0)
1869 return retval;
1870
1871 priv(dev)->hw_revision =
0a85b6f0 1872 hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
88b12a9a
FMH
1873 printk(" stc hardware revision %i\n", priv(dev)->hw_revision);
1874 init_plx9080(dev);
1875 init_stc_registers(dev);
9ef4dea6 1876 /* get irq */
5f74ea14 1877 if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
88b12a9a
FMH
1878 "cb_pcidas64", dev)) {
1879 printk(" unable to allocate irq %u\n", pcidev->irq);
1880 return -EINVAL;
1881 }
1882 dev->irq = pcidev->irq;
1883 printk(" irq %u\n", dev->irq);
1884
1885 retval = setup_subdevices(dev);
90cae794 1886 if (retval < 0)
88b12a9a 1887 return retval;
90cae794 1888
88b12a9a
FMH
1889
1890 return 0;
1891}
1892
1893/*
1894 * _detach is called to deconfigure a device. It should deallocate
1895 * resources.
1896 * This function is also called when _attach() fails, so it should be
1897 * careful not to release resources that were not necessarily
1898 * allocated by _attach(). dev->private and dev->subdevices are
1899 * deallocated automatically by the core.
1900 */
da91b269 1901static int detach(struct comedi_device *dev)
88b12a9a
FMH
1902{
1903 unsigned int i;
1904
1905 printk("comedi%d: cb_pcidas: remove\n", dev->minor);
1906
1907 if (dev->irq)
5f74ea14 1908 free_irq(dev->irq, dev);
88b12a9a
FMH
1909 if (priv(dev)) {
1910 if (priv(dev)->hw_dev) {
1911 if (priv(dev)->plx9080_iobase) {
1912 disable_plx_interrupts(dev);
f31d0008 1913 iounmap(priv(dev)->plx9080_iobase);
88b12a9a
FMH
1914 }
1915 if (priv(dev)->main_iobase)
f31d0008 1916 iounmap(priv(dev)->main_iobase);
88b12a9a 1917 if (priv(dev)->dio_counter_iobase)
f31d0008 1918 iounmap(priv(dev)->dio_counter_iobase);
9ef4dea6 1919 /* free pci dma buffers */
88b12a9a
FMH
1920 for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
1921 if (priv(dev)->ai_buffer[i])
1922 pci_free_consistent(priv(dev)->hw_dev,
0a85b6f0
MT
1923 DMA_BUFFER_SIZE,
1924 priv(dev)->
1925 ai_buffer[i],
1926 priv
1927 (dev)->ai_buffer_bus_addr
1928 [i]);
88b12a9a
FMH
1929 }
1930 for (i = 0; i < AO_DMA_RING_COUNT; i++) {
1931 if (priv(dev)->ao_buffer[i])
1932 pci_free_consistent(priv(dev)->hw_dev,
0a85b6f0
MT
1933 DMA_BUFFER_SIZE,
1934 priv(dev)->
1935 ao_buffer[i],
1936 priv
1937 (dev)->ao_buffer_bus_addr
1938 [i]);
88b12a9a 1939 }
9ef4dea6 1940 /* free dma descriptors */
88b12a9a
FMH
1941 if (priv(dev)->ai_dma_desc)
1942 pci_free_consistent(priv(dev)->hw_dev,
0a85b6f0
MT
1943 sizeof(struct plx_dma_desc)
1944 *
1945 ai_dma_ring_count(board
1946 (dev)),
1947 priv(dev)->ai_dma_desc,
1948 priv(dev)->
1949 ai_dma_desc_bus_addr);
88b12a9a
FMH
1950 if (priv(dev)->ao_dma_desc)
1951 pci_free_consistent(priv(dev)->hw_dev,
0a85b6f0
MT
1952 sizeof(struct plx_dma_desc)
1953 * AO_DMA_RING_COUNT,
1954 priv(dev)->ao_dma_desc,
1955 priv(dev)->
1956 ao_dma_desc_bus_addr);
90cae794 1957 if (priv(dev)->main_phys_iobase)
88b12a9a 1958 comedi_pci_disable(priv(dev)->hw_dev);
003b3e94 1959
88b12a9a
FMH
1960 pci_dev_put(priv(dev)->hw_dev);
1961 }
1962 }
1963 if (dev->subdevices)
1964 subdev_8255_cleanup(dev, dev->subdevices + 4);
1965
1966 return 0;
1967}
1968
da91b269 1969static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1970 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
1971{
1972 unsigned int bits = 0, n, i;
1973 unsigned int channel, range, aref;
1974 unsigned long flags;
1975 static const int timeout = 100;
1976
1977 DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec);
1978 channel = CR_CHAN(insn->chanspec);
1979 range = CR_RANGE(insn->chanspec);
1980 aref = CR_AREF(insn->chanspec);
1981
9ef4dea6
BP
1982 /* disable card's analog input interrupt sources and pacing */
1983 /* 4020 generates dac done interrupts even though they are disabled */
88b12a9a
FMH
1984 disable_ai_pacing(dev);
1985
5f74ea14 1986 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
1987 if (insn->chanspec & CR_ALT_FILTER)
1988 priv(dev)->adc_control1_bits |= ADC_DITHER_BIT;
1989 else
1990 priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
1991 writew(priv(dev)->adc_control1_bits,
0a85b6f0 1992 priv(dev)->main_iobase + ADC_CONTROL1_REG);
5f74ea14 1993 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
1994
1995 if (board(dev)->layout != LAYOUT_4020) {
9ef4dea6 1996 /* use internal queue */
88b12a9a
FMH
1997 priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
1998 writew(priv(dev)->hw_config_bits,
0a85b6f0 1999 priv(dev)->main_iobase + HW_CONFIG_REG);
88b12a9a 2000
9ef4dea6 2001 /* ALT_SOURCE is internal calibration reference */
88b12a9a
FMH
2002 if (insn->chanspec & CR_ALT_SOURCE) {
2003 unsigned int cal_en_bit;
2004
2005 DEBUG_PRINT("reading calibration source\n");
2006 if (board(dev)->layout == LAYOUT_60XX)
2007 cal_en_bit = CAL_EN_60XX_BIT;
2008 else
2009 cal_en_bit = CAL_EN_64XX_BIT;
9ef4dea6 2010 /* select internal reference source to connect to channel 0 */
0a85b6f0
MT
2011 writew(cal_en_bit |
2012 adc_src_bits(priv(dev)->calibration_source),
2013 priv(dev)->main_iobase + CALIBRATION_REG);
88b12a9a 2014 } else {
9ef4dea6 2015 /* make sure internal calibration source is turned off */
88b12a9a
FMH
2016 writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
2017 }
9ef4dea6 2018 /* load internal queue */
88b12a9a 2019 bits = 0;
9ef4dea6 2020 /* set gain */
88b12a9a 2021 bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
9ef4dea6 2022 /* set single-ended / differential */
88b12a9a
FMH
2023 bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
2024 if (aref == AREF_COMMON)
2025 bits |= ADC_COMMON_BIT;
2026 bits |= adc_chan_bits(channel);
9ef4dea6 2027 /* set stop channel */
88b12a9a 2028 writew(adc_chan_bits(channel),
0a85b6f0 2029 priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
9ef4dea6 2030 /* set start channel, and rest of settings */
88b12a9a
FMH
2031 writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
2032 } else {
2033 uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits;
2034
2035 priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
2036 if (insn->chanspec & CR_ALT_SOURCE) {
2037 DEBUG_PRINT("reading calibration source\n");
2038 priv(dev)->i2c_cal_range_bits |=
0a85b6f0 2039 adc_src_4020_bits(priv(dev)->calibration_source);
9ef4dea6 2040 } else { /* select BNC inputs */
88b12a9a
FMH
2041 priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
2042 }
9ef4dea6 2043 /* select range */
88b12a9a
FMH
2044 if (range == 0)
2045 priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel);
2046 else
2047 priv(dev)->i2c_cal_range_bits &=
0a85b6f0 2048 ~attenuate_bit(channel);
9ef4dea6 2049 /* update calibration/range i2c register only if necessary, as it is very slow */
88b12a9a
FMH
2050 if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
2051 uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
2052 i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
0a85b6f0 2053 sizeof(i2c_data));
88b12a9a
FMH
2054 }
2055
2056 /* 4020 manual asks that sample interval register to be set before writing to convert register.
2057 * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */
2058 writew(0,
0a85b6f0 2059 priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
88b12a9a 2060 writew(2,
0a85b6f0 2061 priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a
FMH
2062 }
2063
2064 for (n = 0; n < insn->n; n++) {
2065
9ef4dea6 2066 /* clear adc buffer (inside loop for 4020 sake) */
88b12a9a
FMH
2067 writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
2068
2069 /* trigger conversion, bits sent only matter for 4020 */
2070 writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
0a85b6f0 2071 priv(dev)->main_iobase + ADC_CONVERT_REG);
88b12a9a 2072
9ef4dea6 2073 /* wait for data */
88b12a9a
FMH
2074 for (i = 0; i < timeout; i++) {
2075 bits = readw(priv(dev)->main_iobase + HW_STATUS_REG);
2076 DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits));
2077 if (board(dev)->layout == LAYOUT_4020) {
2078 if (readw(priv(dev)->main_iobase +
0a85b6f0 2079 ADC_WRITE_PNTR_REG))
88b12a9a
FMH
2080 break;
2081 } else {
2082 if (pipe_full_bits(bits))
2083 break;
2084 }
5f74ea14 2085 udelay(1);
88b12a9a
FMH
2086 }
2087 DEBUG_PRINT(" looped %i times waiting for data\n", i);
2088 if (i == timeout) {
2089 comedi_error(dev, " analog input read insn timed out");
5f74ea14 2090 printk(" status 0x%x\n", bits);
88b12a9a
FMH
2091 return -ETIME;
2092 }
2093 if (board(dev)->layout == LAYOUT_4020)
2094 data[n] =
0a85b6f0
MT
2095 readl(priv(dev)->dio_counter_iobase +
2096 ADC_FIFO_REG) & 0xffff;
88b12a9a
FMH
2097 else
2098 data[n] =
0a85b6f0 2099 readw(priv(dev)->main_iobase + PIPE1_READ_REG);
88b12a9a
FMH
2100 }
2101
2102 return n;
2103}
2104
0a85b6f0
MT
2105static int ai_config_calibration_source(struct comedi_device *dev,
2106 unsigned int *data)
88b12a9a 2107{
790c5541 2108 unsigned int source = data[1];
88b12a9a
FMH
2109 int num_calibration_sources;
2110
2111 if (board(dev)->layout == LAYOUT_60XX)
2112 num_calibration_sources = 16;
2113 else
2114 num_calibration_sources = 8;
2115 if (source >= num_calibration_sources) {
2116 printk("invalid calibration source: %i\n", source);
2117 return -EINVAL;
2118 }
2119
2120 DEBUG_PRINT("setting calibration source to %i\n", source);
2121 priv(dev)->calibration_source = source;
2122
2123 return 2;
2124}
2125
da91b269 2126static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
88b12a9a
FMH
2127{
2128 int fifo_size;
675935dd 2129 const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
88b12a9a
FMH
2130 unsigned int block_size, requested_block_size;
2131 int retval;
2132
2133 requested_block_size = data[1];
2134
2135 if (requested_block_size) {
2136 fifo_size =
0a85b6f0 2137 requested_block_size * fifo->num_segments / bytes_in_sample;
88b12a9a
FMH
2138
2139 retval = set_ai_fifo_size(dev, fifo_size);
2140 if (retval < 0)
2141 return retval;
2142
2143 }
2144
2145 block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
2146
2147 data[1] = block_size;
2148
2149 return 2;
2150}
2151
0a85b6f0
MT
2152static int ai_config_master_clock_4020(struct comedi_device *dev,
2153 unsigned int *data)
88b12a9a
FMH
2154{
2155 unsigned int divisor = data[4];
2156 int retval = 0;
2157
2158 if (divisor < 2) {
2159 divisor = 2;
2160 retval = -EAGAIN;
2161 }
2162
2163 switch (data[1]) {
2164 case COMEDI_EV_SCAN_BEGIN:
2165 priv(dev)->ext_clock.divisor = divisor;
2166 priv(dev)->ext_clock.chanspec = data[2];
2167 break;
2168 default:
2169 return -EINVAL;
2170 break;
2171 }
2172
2173 data[4] = divisor;
2174
2175 return retval ? retval : 5;
2176}
2177
9ef4dea6 2178/* XXX could add support for 60xx series */
da91b269 2179static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
88b12a9a
FMH
2180{
2181
2182 switch (board(dev)->layout) {
2183 case LAYOUT_4020:
2184 return ai_config_master_clock_4020(dev, data);
2185 break;
2186 default:
2187 return -EINVAL;
2188 break;
2189 }
2190
2191 return -EINVAL;
2192}
2193
da91b269 2194static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 2195 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
2196{
2197 int id = data[0];
2198
2199 switch (id) {
2200 case INSN_CONFIG_ALT_SOURCE:
2201 return ai_config_calibration_source(dev, data);
2202 break;
2203 case INSN_CONFIG_BLOCK_SIZE:
2204 return ai_config_block_size(dev, data);
2205 break;
2206 case INSN_CONFIG_TIMER_1:
2207 return ai_config_master_clock(dev, data);
2208 break;
2209 default:
2210 return -EINVAL;
2211 break;
2212 }
2213 return -EINVAL;
2214}
2215
da91b269 2216static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 2217 struct comedi_cmd *cmd)
88b12a9a
FMH
2218{
2219 int err = 0;
2220 int tmp;
2221 unsigned int tmp_arg, tmp_arg2;
2222 int i;
2223 int aref;
2224 unsigned int triggers;
2225
2226 /* step 1: make sure trigger sources are trivially valid */
2227
2228 tmp = cmd->start_src;
2229 cmd->start_src &= TRIG_NOW | TRIG_EXT;
2230 if (!cmd->start_src || tmp != cmd->start_src)
2231 err++;
2232
2233 tmp = cmd->scan_begin_src;
2234 triggers = TRIG_TIMER;
2235 if (board(dev)->layout == LAYOUT_4020)
2236 triggers |= TRIG_OTHER;
2237 else
2238 triggers |= TRIG_FOLLOW;
2239 cmd->scan_begin_src &= triggers;
2240 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
2241 err++;
2242
2243 tmp = cmd->convert_src;
2244 triggers = TRIG_TIMER;
2245 if (board(dev)->layout == LAYOUT_4020)
2246 triggers |= TRIG_NOW;
2247 else
2248 triggers |= TRIG_EXT;
2249 cmd->convert_src &= triggers;
2250 if (!cmd->convert_src || tmp != cmd->convert_src)
2251 err++;
2252
2253 tmp = cmd->scan_end_src;
2254 cmd->scan_end_src &= TRIG_COUNT;
2255 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
2256 err++;
2257
2258 tmp = cmd->stop_src;
2259 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
2260 if (!cmd->stop_src || tmp != cmd->stop_src)
2261 err++;
2262
2263 if (err)
2264 return 1;
2265
2266 /* step 2: make sure trigger sources are unique and mutually compatible */
2267
9ef4dea6 2268 /* uniqueness check */
88b12a9a
FMH
2269 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
2270 err++;
2271 if (cmd->scan_begin_src != TRIG_TIMER &&
0a85b6f0
MT
2272 cmd->scan_begin_src != TRIG_OTHER &&
2273 cmd->scan_begin_src != TRIG_FOLLOW)
88b12a9a
FMH
2274 err++;
2275 if (cmd->convert_src != TRIG_TIMER &&
0a85b6f0 2276 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
88b12a9a
FMH
2277 err++;
2278 if (cmd->stop_src != TRIG_COUNT &&
0a85b6f0 2279 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
88b12a9a
FMH
2280 err++;
2281
9ef4dea6 2282 /* compatibility check */
88b12a9a
FMH
2283 if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
2284 err++;
2285 if (cmd->stop_src != TRIG_COUNT &&
0a85b6f0 2286 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
88b12a9a
FMH
2287 err++;
2288
2289 if (err)
2290 return 2;
2291
2292 /* step 3: make sure arguments are trivially compatible */
2293
2294 if (cmd->convert_src == TRIG_TIMER) {
2295 if (board(dev)->layout == LAYOUT_4020) {
2296 if (cmd->convert_arg) {
2297 cmd->convert_arg = 0;
2298 err++;
2299 }
2300 } else {
2301 if (cmd->convert_arg < board(dev)->ai_speed) {
2302 cmd->convert_arg = board(dev)->ai_speed;
2303 err++;
2304 }
2305 if (cmd->scan_begin_src == TRIG_TIMER) {
9ef4dea6 2306 /* if scans are timed faster than conversion rate allows */
88b12a9a 2307 if (cmd->convert_arg * cmd->chanlist_len >
0a85b6f0 2308 cmd->scan_begin_arg) {
88b12a9a 2309 cmd->scan_begin_arg =
0a85b6f0
MT
2310 cmd->convert_arg *
2311 cmd->chanlist_len;
88b12a9a
FMH
2312 err++;
2313 }
2314 }
2315 }
2316 }
2317
2318 if (!cmd->chanlist_len) {
2319 cmd->chanlist_len = 1;
2320 err++;
2321 }
2322 if (cmd->scan_end_arg != cmd->chanlist_len) {
2323 cmd->scan_end_arg = cmd->chanlist_len;
2324 err++;
2325 }
2326
2327 switch (cmd->stop_src) {
2328 case TRIG_EXT:
2329 break;
2330 case TRIG_COUNT:
2331 if (!cmd->stop_arg) {
2332 cmd->stop_arg = 1;
2333 err++;
2334 }
2335 break;
2336 case TRIG_NONE:
2337 if (cmd->stop_arg != 0) {
2338 cmd->stop_arg = 0;
2339 err++;
2340 }
2341 break;
2342 default:
2343 break;
2344 }
2345
2346 if (err)
2347 return 3;
2348
2349 /* step 4: fix up any arguments */
2350
2351 if (cmd->convert_src == TRIG_TIMER) {
2352 tmp_arg = cmd->convert_arg;
2353 tmp_arg2 = cmd->scan_begin_arg;
2354 check_adc_timing(dev, cmd);
2355 if (tmp_arg != cmd->convert_arg)
2356 err++;
2357 if (tmp_arg2 != cmd->scan_begin_arg)
2358 err++;
2359 }
2360
2361 if (err)
2362 return 4;
2363
9ef4dea6 2364 /* make sure user is doesn't change analog reference mid chanlist */
88b12a9a
FMH
2365 if (cmd->chanlist) {
2366 aref = CR_AREF(cmd->chanlist[0]);
2367 for (i = 1; i < cmd->chanlist_len; i++) {
2368 if (aref != CR_AREF(cmd->chanlist[i])) {
2369 comedi_error(dev,
0a85b6f0 2370 "all elements in chanlist must use the same analog reference");
88b12a9a
FMH
2371 err++;
2372 break;
2373 }
2374 }
9ef4dea6 2375 /* check 4020 chanlist */
88b12a9a
FMH
2376 if (board(dev)->layout == LAYOUT_4020) {
2377 unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
2378 for (i = 1; i < cmd->chanlist_len; i++) {
2379 if (CR_CHAN(cmd->chanlist[i]) !=
0a85b6f0 2380 first_channel + i) {
88b12a9a 2381 comedi_error(dev,
0a85b6f0 2382 "chanlist must use consecutive channels");
88b12a9a
FMH
2383 err++;
2384 break;
2385 }
2386 }
2387 if (cmd->chanlist_len == 3) {
2388 comedi_error(dev,
0a85b6f0 2389 "chanlist cannot be 3 channels long, use 1, 2, or 4 channels");
88b12a9a
FMH
2390 err++;
2391 }
2392 }
2393 }
2394
2395 if (err)
2396 return 5;
2397
2398 return 0;
2399}
2400
da91b269 2401static int use_hw_sample_counter(struct comedi_cmd *cmd)
88b12a9a 2402{
9ef4dea6 2403/* disable for now until I work out a race */
88b12a9a
FMH
2404 return 0;
2405
2406 if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
2407 return 1;
2408 else
2409 return 0;
2410}
2411
0a85b6f0
MT
2412static void setup_sample_counters(struct comedi_device *dev,
2413 struct comedi_cmd *cmd)
88b12a9a
FMH
2414{
2415 if (cmd->stop_src == TRIG_COUNT) {
9ef4dea6 2416 /* set software count */
88b12a9a
FMH
2417 priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len;
2418 }
9ef4dea6 2419 /* load hardware conversion counter */
88b12a9a
FMH
2420 if (use_hw_sample_counter(cmd)) {
2421 writew(cmd->stop_arg & 0xffff,
0a85b6f0 2422 priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
88b12a9a 2423 writew((cmd->stop_arg >> 16) & 0xff,
0a85b6f0 2424 priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
88b12a9a
FMH
2425 } else {
2426 writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
2427 }
2428}
2429
da91b269 2430static inline unsigned int dma_transfer_size(struct comedi_device *dev)
88b12a9a
FMH
2431{
2432 unsigned int num_samples;
2433
2434 num_samples =
0a85b6f0
MT
2435 priv(dev)->ai_fifo_segment_length *
2436 board(dev)->ai_fifo->sample_packing_ratio;
88b12a9a
FMH
2437 if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
2438 num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
2439
2440 return num_samples;
2441}
2442
da91b269 2443static void disable_ai_pacing(struct comedi_device *dev)
88b12a9a
FMH
2444{
2445 unsigned long flags;
2446
2447 disable_ai_interrupts(dev);
2448
5f74ea14 2449 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2450 priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT;
2451 writew(priv(dev)->adc_control1_bits,
0a85b6f0 2452 priv(dev)->main_iobase + ADC_CONTROL1_REG);
5f74ea14 2453 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2454
2455 /* disable pacing, triggering, etc */
2456 writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
0a85b6f0 2457 priv(dev)->main_iobase + ADC_CONTROL0_REG);
88b12a9a
FMH
2458}
2459
da91b269 2460static void disable_ai_interrupts(struct comedi_device *dev)
88b12a9a
FMH
2461{
2462 unsigned long flags;
2463
5f74ea14 2464 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 2465 priv(dev)->intr_enable_bits &=
0a85b6f0
MT
2466 ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
2467 ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
2468 ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
88b12a9a 2469 writew(priv(dev)->intr_enable_bits,
0a85b6f0 2470 priv(dev)->main_iobase + INTR_ENABLE_REG);
5f74ea14 2471 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2472
2473 DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
2474}
2475
0a85b6f0
MT
2476static void enable_ai_interrupts(struct comedi_device *dev,
2477 const struct comedi_cmd *cmd)
88b12a9a
FMH
2478{
2479 uint32_t bits;
2480 unsigned long flags;
2481
2482 bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
0a85b6f0 2483 EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
9ef4dea6 2484 /* Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set. */
88b12a9a 2485 if (cmd->flags & TRIG_WAKE_EOS) {
9ef4dea6 2486 /* 4020 doesn't support pio transfers except for fifo dregs */
88b12a9a
FMH
2487 if (board(dev)->layout != LAYOUT_4020)
2488 bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
2489 }
5f74ea14 2490 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2491 priv(dev)->intr_enable_bits |= bits;
2492 writew(priv(dev)->intr_enable_bits,
0a85b6f0 2493 priv(dev)->main_iobase + INTR_ENABLE_REG);
88b12a9a 2494 DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
5f74ea14 2495 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2496}
2497
da91b269 2498static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
0a85b6f0 2499 const struct comedi_cmd *cmd)
88b12a9a 2500{
9ef4dea6 2501 /* supposed to load counter with desired divisor minus 3 */
88b12a9a
FMH
2502 return cmd->convert_arg / TIMER_BASE - 3;
2503}
2504
0a85b6f0
MT
2505static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
2506 struct comedi_cmd *cmd)
88b12a9a
FMH
2507{
2508 uint32_t count;
9ef4dea6 2509 /* figure out how long we need to delay at end of scan */
88b12a9a
FMH
2510 switch (cmd->scan_begin_src) {
2511 case TRIG_TIMER:
2512 count = (cmd->scan_begin_arg -
0a85b6f0
MT
2513 (cmd->convert_arg * (cmd->chanlist_len - 1)))
2514 / TIMER_BASE;
88b12a9a
FMH
2515 break;
2516 case TRIG_FOLLOW:
2517 count = cmd->convert_arg / TIMER_BASE;
2518 break;
2519 default:
2520 return 0;
2521 break;
2522 }
2523 return count - 3;
2524}
2525
0a85b6f0
MT
2526static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
2527 struct comedi_cmd *cmd)
88b12a9a
FMH
2528{
2529 unsigned int divisor;
2530
2531 switch (cmd->scan_begin_src) {
2532 case TRIG_TIMER:
2533 divisor = cmd->scan_begin_arg / TIMER_BASE;
2534 break;
2535 case TRIG_OTHER:
2536 divisor = priv(dev)->ext_clock.divisor;
2537 break;
9ef4dea6 2538 default: /* should never happen */
88b12a9a
FMH
2539 comedi_error(dev, "bug! failed to set ai pacing!");
2540 divisor = 1000;
2541 break;
2542 }
2543
9ef4dea6 2544 /* supposed to load counter with desired divisor minus 2 for 4020 */
88b12a9a
FMH
2545 return divisor - 2;
2546}
2547
da91b269 2548static void select_master_clock_4020(struct comedi_device *dev,
0a85b6f0 2549 const struct comedi_cmd *cmd)
88b12a9a 2550{
9ef4dea6 2551 /* select internal/external master clock */
88b12a9a
FMH
2552 priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
2553 if (cmd->scan_begin_src == TRIG_OTHER) {
2554 int chanspec = priv(dev)->ext_clock.chanspec;
2555
2556 if (CR_CHAN(chanspec))
2557 priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS;
2558 else
2559 priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS;
2560 } else {
2561 priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
2562 }
2563 writew(priv(dev)->hw_config_bits,
0a85b6f0 2564 priv(dev)->main_iobase + HW_CONFIG_REG);
88b12a9a
FMH
2565}
2566
0a85b6f0
MT
2567static void select_master_clock(struct comedi_device *dev,
2568 const struct comedi_cmd *cmd)
88b12a9a
FMH
2569{
2570 switch (board(dev)->layout) {
2571 case LAYOUT_4020:
2572 select_master_clock_4020(dev, cmd);
2573 break;
2574 default:
2575 break;
2576 }
2577}
2578
0a85b6f0
MT
2579static inline void dma_start_sync(struct comedi_device *dev,
2580 unsigned int channel)
88b12a9a
FMH
2581{
2582 unsigned long flags;
2583
9ef4dea6 2584 /* spinlock for plx dma control/status reg */
5f74ea14 2585 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2586 if (channel)
2587 writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
0a85b6f0
MT
2588 PLX_CLEAR_DMA_INTR_BIT,
2589 priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
88b12a9a
FMH
2590 else
2591 writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
0a85b6f0
MT
2592 PLX_CLEAR_DMA_INTR_BIT,
2593 priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
5f74ea14 2594 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
2595}
2596
da91b269 2597static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
88b12a9a
FMH
2598{
2599 uint32_t convert_counter = 0, scan_counter = 0;
2600
2601 check_adc_timing(dev, cmd);
2602
2603 select_master_clock(dev, cmd);
2604
2605 if (board(dev)->layout == LAYOUT_4020) {
2606 convert_counter = ai_convert_counter_4020(dev, cmd);
2607 } else {
2608 convert_counter = ai_convert_counter_6xxx(dev, cmd);
2609 scan_counter = ai_scan_counter_6xxx(dev, cmd);
2610 }
2611
9ef4dea6 2612 /* load lower 16 bits of convert interval */
88b12a9a 2613 writew(convert_counter & 0xffff,
0a85b6f0 2614 priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a 2615 DEBUG_PRINT("convert counter 0x%x\n", convert_counter);
9ef4dea6 2616 /* load upper 8 bits of convert interval */
88b12a9a 2617 writew((convert_counter >> 16) & 0xff,
0a85b6f0 2618 priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
9ef4dea6 2619 /* load lower 16 bits of scan delay */
88b12a9a 2620 writew(scan_counter & 0xffff,
0a85b6f0 2621 priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
9ef4dea6 2622 /* load upper 8 bits of scan delay */
88b12a9a 2623 writew((scan_counter >> 16) & 0xff,
0a85b6f0 2624 priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
88b12a9a
FMH
2625 DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
2626}
2627
da91b269 2628static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
88b12a9a
FMH
2629{
2630 int i;
2631 for (i = 0; i + 1 < cmd->chanlist_len; i++) {
2632 if (CR_CHAN(cmd->chanlist[i + 1]) !=
0a85b6f0 2633 CR_CHAN(cmd->chanlist[i]) + 1)
88b12a9a
FMH
2634 return 0;
2635 if (CR_RANGE(cmd->chanlist[i + 1]) !=
0a85b6f0 2636 CR_RANGE(cmd->chanlist[i]))
88b12a9a
FMH
2637 return 0;
2638 if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
2639 return 0;
2640 }
2641 return 1;
2642}
2643
0a85b6f0
MT
2644static int setup_channel_queue(struct comedi_device *dev,
2645 const struct comedi_cmd *cmd)
88b12a9a
FMH
2646{
2647 unsigned short bits;
2648 int i;
2649
2650 if (board(dev)->layout != LAYOUT_4020) {
2651 if (use_internal_queue_6xxx(cmd)) {
2652 priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
2653 writew(priv(dev)->hw_config_bits,
0a85b6f0 2654 priv(dev)->main_iobase + HW_CONFIG_REG);
88b12a9a 2655 bits = 0;
9ef4dea6 2656 /* set channel */
88b12a9a 2657 bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
9ef4dea6 2658 /* set gain */
88b12a9a 2659 bits |= ai_range_bits_6xxx(dev,
0a85b6f0 2660 CR_RANGE(cmd->chanlist[0]));
9ef4dea6 2661 /* set single-ended / differential */
88b12a9a 2662 bits |= se_diff_bit_6xxx(dev,
0a85b6f0
MT
2663 CR_AREF(cmd->chanlist[0]) ==
2664 AREF_DIFF);
88b12a9a
FMH
2665 if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
2666 bits |= ADC_COMMON_BIT;
9ef4dea6 2667 /* set stop channel */
0a85b6f0
MT
2668 writew(adc_chan_bits
2669 (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])),
2670 priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
9ef4dea6 2671 /* set start channel, and rest of settings */
88b12a9a 2672 writew(bits,
0a85b6f0 2673 priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
88b12a9a 2674 } else {
9ef4dea6 2675 /* use external queue */
88b12a9a
FMH
2676 if (dev->write_subdev && dev->write_subdev->busy) {
2677 warn_external_queue(dev);
2678 return -EBUSY;
2679 }
2680 priv(dev)->hw_config_bits |= EXT_QUEUE_BIT;
2681 writew(priv(dev)->hw_config_bits,
0a85b6f0 2682 priv(dev)->main_iobase + HW_CONFIG_REG);
9ef4dea6 2683 /* clear DAC buffer to prevent weird interactions */
88b12a9a 2684 writew(0,
0a85b6f0 2685 priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
9ef4dea6 2686 /* clear queue pointer */
88b12a9a 2687 writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
9ef4dea6 2688 /* load external queue */
88b12a9a
FMH
2689 for (i = 0; i < cmd->chanlist_len; i++) {
2690 bits = 0;
9ef4dea6 2691 /* set channel */
0a85b6f0
MT
2692 bits |=
2693 adc_chan_bits(CR_CHAN(cmd->chanlist[i]));
9ef4dea6 2694 /* set gain */
88b12a9a 2695 bits |= ai_range_bits_6xxx(dev,
0a85b6f0
MT
2696 CR_RANGE(cmd->
2697 chanlist
2698 [i]));
9ef4dea6 2699 /* set single-ended / differential */
88b12a9a 2700 bits |= se_diff_bit_6xxx(dev,
0a85b6f0
MT
2701 CR_AREF(cmd->
2702 chanlist[i]) ==
2703 AREF_DIFF);
88b12a9a
FMH
2704 if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
2705 bits |= ADC_COMMON_BIT;
9ef4dea6 2706 /* mark end of queue */
88b12a9a
FMH
2707 if (i == cmd->chanlist_len - 1)
2708 bits |= QUEUE_EOSCAN_BIT |
0a85b6f0 2709 QUEUE_EOSEQ_BIT;
88b12a9a 2710 writew(bits,
0a85b6f0
MT
2711 priv(dev)->main_iobase +
2712 ADC_QUEUE_FIFO_REG);
88b12a9a 2713 DEBUG_PRINT
0a85b6f0
MT
2714 ("wrote 0x%x to external channel queue\n",
2715 bits);
88b12a9a
FMH
2716 }
2717 /* doing a queue clear is not specified in board docs,
2718 * but required for reliable operation */
2719 writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
9ef4dea6 2720 /* prime queue holding register */
88b12a9a
FMH
2721 writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
2722 }
2723 } else {
2724 unsigned short old_cal_range_bits =
0a85b6f0 2725 priv(dev)->i2c_cal_range_bits;
88b12a9a
FMH
2726
2727 priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
9ef4dea6 2728 /* select BNC inputs */
88b12a9a 2729 priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
9ef4dea6 2730 /* select ranges */
88b12a9a
FMH
2731 for (i = 0; i < cmd->chanlist_len; i++) {
2732 unsigned int channel = CR_CHAN(cmd->chanlist[i]);
2733 unsigned int range = CR_RANGE(cmd->chanlist[i]);
2734
2735 if (range == 0)
2736 priv(dev)->i2c_cal_range_bits |=
0a85b6f0 2737 attenuate_bit(channel);
88b12a9a
FMH
2738 else
2739 priv(dev)->i2c_cal_range_bits &=
0a85b6f0 2740 ~attenuate_bit(channel);
88b12a9a 2741 }
9ef4dea6 2742 /* update calibration/range i2c register only if necessary, as it is very slow */
88b12a9a
FMH
2743 if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
2744 uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
2745 i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
0a85b6f0 2746 sizeof(i2c_data));
88b12a9a
FMH
2747 }
2748 }
2749 return 0;
2750}
2751
da91b269 2752static inline void load_first_dma_descriptor(struct comedi_device *dev,
0a85b6f0
MT
2753 unsigned int dma_channel,
2754 unsigned int descriptor_bits)
88b12a9a
FMH
2755{
2756 /* The transfer size, pci address, and local address registers
2757 * are supposedly unused during chained dma,
2758 * but I have found that left over values from last operation
2759 * occasionally cause problems with transfer of first dma
2760 * block. Initializing them to zero seems to fix the problem. */
2761 if (dma_channel) {
2762 writel(0,
0a85b6f0 2763 priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
88b12a9a
FMH
2764 writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
2765 writel(0,
0a85b6f0 2766 priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
88b12a9a 2767 writel(descriptor_bits,
0a85b6f0 2768 priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
88b12a9a
FMH
2769 } else {
2770 writel(0,
0a85b6f0 2771 priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
88b12a9a
FMH
2772 writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
2773 writel(0,
0a85b6f0 2774 priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
88b12a9a 2775 writel(descriptor_bits,
0a85b6f0 2776 priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
88b12a9a
FMH
2777 }
2778}
2779
da91b269 2780static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 2781{
d163679c 2782 struct comedi_async *async = s->async;
ea6d0d4c 2783 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2784 uint32_t bits;
2785 unsigned int i;
2786 unsigned long flags;
2787 int retval;
2788
2789 disable_ai_pacing(dev);
2790 abort_dma(dev, 1);
2791
2792 retval = setup_channel_queue(dev, cmd);
2793 if (retval < 0)
2794 return retval;
2795
9ef4dea6 2796 /* make sure internal calibration source is turned off */
88b12a9a
FMH
2797 writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
2798
2799 set_ai_pacing(dev, cmd);
2800
2801 setup_sample_counters(dev, cmd);
2802
2803 enable_ai_interrupts(dev, cmd);
2804
5f74ea14 2805 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2806 /* set mode, allow conversions through software gate */
2807 priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT;
2808 priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
2809 if (board(dev)->layout != LAYOUT_4020) {
2810 priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK;
2811 if (cmd->convert_src == TRIG_EXT)
9ef4dea6 2812 priv(dev)->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */
88b12a9a 2813 else
9ef4dea6 2814 priv(dev)->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */
88b12a9a
FMH
2815 } else {
2816 priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
2817 if (cmd->chanlist_len == 4)
2818 priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
2819 else if (cmd->chanlist_len == 2)
2820 priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
2821 priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
2822 priv(dev)->adc_control1_bits |=
0a85b6f0 2823 adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
88b12a9a
FMH
2824 priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
2825 priv(dev)->adc_control1_bits |=
0a85b6f0
MT
2826 adc_hi_chan_4020_bits(CR_CHAN
2827 (cmd->
2828 chanlist[cmd->chanlist_len - 1]));
88b12a9a
FMH
2829 }
2830 writew(priv(dev)->adc_control1_bits,
0a85b6f0 2831 priv(dev)->main_iobase + ADC_CONTROL1_REG);
88b12a9a 2832 DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits);
5f74ea14 2833 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2834
9ef4dea6 2835 /* clear adc buffer */
88b12a9a
FMH
2836 writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
2837
2838 if ((cmd->flags & TRIG_WAKE_EOS) == 0 ||
0a85b6f0 2839 board(dev)->layout == LAYOUT_4020) {
88b12a9a
FMH
2840 priv(dev)->ai_dma_index = 0;
2841
9ef4dea6 2842 /* set dma transfer size */
88b12a9a
FMH
2843 for (i = 0; i < ai_dma_ring_count(board(dev)); i++)
2844 priv(dev)->ai_dma_desc[i].transfer_size =
0a85b6f0
MT
2845 cpu_to_le32(dma_transfer_size(dev) *
2846 sizeof(uint16_t));
88b12a9a 2847
9ef4dea6 2848 /* give location of first dma descriptor */
88b12a9a 2849 load_first_dma_descriptor(dev, 1,
0a85b6f0
MT
2850 priv(dev)->ai_dma_desc_bus_addr |
2851 PLX_DESC_IN_PCI_BIT |
2852 PLX_INTR_TERM_COUNT |
2853 PLX_XFER_LOCAL_TO_PCI);
88b12a9a
FMH
2854
2855 dma_start_sync(dev, 1);
2856 }
2857
2858 if (board(dev)->layout == LAYOUT_4020) {
2859 /* set source for external triggers */
2860 bits = 0;
2861 if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
2862 bits |= EXT_START_TRIG_BNC_BIT;
2863 if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
2864 bits |= EXT_STOP_TRIG_BNC_BIT;
2865 writew(bits, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG);
2866 }
2867
5f74ea14 2868 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
2869
2870 /* enable pacing, triggering, etc */
2871 bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
2872 if (cmd->flags & TRIG_WAKE_EOS)
2873 bits |= ADC_DMA_DISABLE_BIT;
9ef4dea6 2874 /* set start trigger */
88b12a9a
FMH
2875 if (cmd->start_src == TRIG_EXT) {
2876 bits |= ADC_START_TRIG_EXT_BITS;
2877 if (cmd->start_arg & CR_INVERT)
2878 bits |= ADC_START_TRIG_FALLING_BIT;
2879 } else if (cmd->start_src == TRIG_NOW)
2880 bits |= ADC_START_TRIG_SOFT_BITS;
2881 if (use_hw_sample_counter(cmd))
2882 bits |= ADC_SAMPLE_COUNTER_EN_BIT;
2883 writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG);
2884 DEBUG_PRINT("control0 bits 0x%x\n", bits);
2885
2886 priv(dev)->ai_cmd_running = 1;
2887
5f74ea14 2888 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 2889
9ef4dea6 2890 /* start aquisition */
88b12a9a
FMH
2891 if (cmd->start_src == TRIG_NOW) {
2892 writew(0, priv(dev)->main_iobase + ADC_START_REG);
2893 DEBUG_PRINT("soft trig\n");
2894 }
2895
2896 return 0;
2897}
2898
9ef4dea6 2899/* read num_samples from 16 bit wide ai fifo */
da91b269 2900static void pio_drain_ai_fifo_16(struct comedi_device *dev)
88b12a9a 2901{
34c43922 2902 struct comedi_subdevice *s = dev->read_subdev;
d163679c 2903 struct comedi_async *async = s->async;
ea6d0d4c 2904 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2905 unsigned int i;
2906 uint16_t prepost_bits;
2907 int read_segment, read_index, write_segment, write_index;
2908 int num_samples;
2909
2910 do {
9ef4dea6 2911 /* get least significant 15 bits */
88b12a9a 2912 read_index =
0a85b6f0 2913 readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
88b12a9a 2914 write_index =
0a85b6f0 2915 readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
88b12a9a
FMH
2916 /* Get most significant bits (grey code). Different boards use different code
2917 * so use a scheme that doesn't depend on encoding. This read must
2918 * occur after reading least significant 15 bits to avoid race
2919 * with fifo switching to next segment. */
2920 prepost_bits = readw(priv(dev)->main_iobase + PREPOST_REG);
2921
2922 /* if read and write pointers are not on the same fifo segment, read to the
2923 * end of the read segment */
2924 read_segment = adc_upper_read_ptr_code(prepost_bits);
2925 write_segment = adc_upper_write_ptr_code(prepost_bits);
2926
2927 DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n",
0a85b6f0
MT
2928 read_segment, write_segment, read_index,
2929 write_index);
88b12a9a
FMH
2930
2931 if (read_segment != write_segment)
2932 num_samples =
0a85b6f0 2933 priv(dev)->ai_fifo_segment_length - read_index;
88b12a9a
FMH
2934 else
2935 num_samples = write_index - read_index;
2936
2937 if (cmd->stop_src == TRIG_COUNT) {
2938 if (priv(dev)->ai_count == 0)
2939 break;
90cae794 2940 if (num_samples > priv(dev)->ai_count)
88b12a9a 2941 num_samples = priv(dev)->ai_count;
90cae794 2942
88b12a9a
FMH
2943 priv(dev)->ai_count -= num_samples;
2944 }
2945
2946 if (num_samples < 0) {
5f74ea14 2947 printk(" cb_pcidas64: bug! num_samples < 0\n");
88b12a9a
FMH
2948 break;
2949 }
2950
2951 DEBUG_PRINT(" read %i samples from fifo\n", num_samples);
2952
2953 for (i = 0; i < num_samples; i++) {
2954 cfc_write_to_buffer(s,
0a85b6f0
MT
2955 readw(priv(dev)->main_iobase +
2956 ADC_FIFO_REG));
88b12a9a
FMH
2957 }
2958
2959 } while (read_segment != write_segment);
2960}
2961
2962/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers.
2963 * The pci-4020 hardware only supports
2964 * dma transfers (it only supports the use of pio for draining the last remaining
2965 * points from the fifo when a data aquisition operation has completed).
2966 */
da91b269 2967static void pio_drain_ai_fifo_32(struct comedi_device *dev)
88b12a9a 2968{
34c43922 2969 struct comedi_subdevice *s = dev->read_subdev;
d163679c 2970 struct comedi_async *async = s->async;
ea6d0d4c 2971 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
2972 unsigned int i;
2973 unsigned int max_transfer = 100000;
2974 uint32_t fifo_data;
2975 int write_code =
0a85b6f0 2976 readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
88b12a9a 2977 int read_code =
0a85b6f0 2978 readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
88b12a9a
FMH
2979
2980 if (cmd->stop_src == TRIG_COUNT) {
90cae794 2981 if (max_transfer > priv(dev)->ai_count)
88b12a9a 2982 max_transfer = priv(dev)->ai_count;
90cae794 2983
88b12a9a
FMH
2984 }
2985 for (i = 0; read_code != write_code && i < max_transfer;) {
2986 fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG);
2987 cfc_write_to_buffer(s, fifo_data & 0xffff);
2988 i++;
2989 if (i < max_transfer) {
2990 cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff);
2991 i++;
2992 }
2993 read_code =
0a85b6f0 2994 readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
88b12a9a
FMH
2995 }
2996 priv(dev)->ai_count -= i;
2997}
2998
9ef4dea6 2999/* empty fifo */
da91b269 3000static void pio_drain_ai_fifo(struct comedi_device *dev)
88b12a9a 3001{
90cae794 3002 if (board(dev)->layout == LAYOUT_4020)
88b12a9a 3003 pio_drain_ai_fifo_32(dev);
90cae794 3004 else
88b12a9a
FMH
3005 pio_drain_ai_fifo_16(dev);
3006}
3007
da91b269 3008static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
88b12a9a 3009{
d163679c 3010 struct comedi_async *async = dev->read_subdev->async;
88b12a9a
FMH
3011 uint32_t next_transfer_addr;
3012 int j;
3013 int num_samples = 0;
f31d0008 3014 void __iomem *pci_addr_reg;
88b12a9a
FMH
3015
3016 if (channel)
3017 pci_addr_reg =
0a85b6f0 3018 priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
88b12a9a
FMH
3019 else
3020 pci_addr_reg =
0a85b6f0 3021 priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
88b12a9a 3022
9ef4dea6 3023 /* loop until we have read all the full buffers */
88b12a9a 3024 for (j = 0, next_transfer_addr = readl(pci_addr_reg);
0a85b6f0
MT
3025 (next_transfer_addr <
3026 priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index]
3027 || next_transfer_addr >=
3028 priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] +
3029 DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) {
9ef4dea6 3030 /* transfer data from dma buffer to comedi buffer */
88b12a9a
FMH
3031 num_samples = dma_transfer_size(dev);
3032 if (async->cmd.stop_src == TRIG_COUNT) {
3033 if (num_samples > priv(dev)->ai_count)
3034 num_samples = priv(dev)->ai_count;
3035 priv(dev)->ai_count -= num_samples;
3036 }
3037 cfc_write_array_to_buffer(dev->read_subdev,
0a85b6f0
MT
3038 priv(dev)->ai_buffer[priv(dev)->
3039 ai_dma_index],
3040 num_samples * sizeof(uint16_t));
88b12a9a 3041 priv(dev)->ai_dma_index =
0a85b6f0
MT
3042 (priv(dev)->ai_dma_index +
3043 1) % ai_dma_ring_count(board(dev));
88b12a9a
FMH
3044
3045 DEBUG_PRINT("next buffer addr 0x%lx\n",
0a85b6f0
MT
3046 (unsigned long)priv(dev)->
3047 ai_buffer_bus_addr[priv(dev)->ai_dma_index]);
88b12a9a
FMH
3048 DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
3049 }
3050 /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last
3051 * unused buffer) */
3052}
3053
f31d0008
GKH
3054static void handle_ai_interrupt(struct comedi_device *dev,
3055 unsigned short status,
3056 unsigned int plx_status)
88b12a9a 3057{
34c43922 3058 struct comedi_subdevice *s = dev->read_subdev;
d163679c 3059 struct comedi_async *async = s->async;
ea6d0d4c 3060 struct comedi_cmd *cmd = &async->cmd;
88b12a9a
FMH
3061 uint8_t dma1_status;
3062 unsigned long flags;
3063
9ef4dea6 3064 /* check for fifo overrun */
88b12a9a
FMH
3065 if (status & ADC_OVERRUN_BIT) {
3066 comedi_error(dev, "fifo overrun");
3067 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
3068 }
9ef4dea6 3069 /* spin lock makes sure noone else changes plx dma control reg */
5f74ea14 3070 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 3071 dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
9ef4dea6 3072 if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */
88b12a9a 3073 writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
0a85b6f0 3074 priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
88b12a9a
FMH
3075 DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
3076
90cae794 3077 if (dma1_status & PLX_DMA_EN_BIT)
88b12a9a 3078 drain_dma_buffers(dev, 1);
90cae794 3079
88b12a9a
FMH
3080 DEBUG_PRINT(" cleared dma ch1 interrupt\n");
3081 }
5f74ea14 3082 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3083
3084 if (status & ADC_DONE_BIT)
3085 DEBUG_PRINT("adc done interrupt\n");
3086
9ef4dea6 3087 /* drain fifo with pio */
88b12a9a 3088 if ((status & ADC_DONE_BIT) ||
0a85b6f0
MT
3089 ((cmd->flags & TRIG_WAKE_EOS) &&
3090 (status & ADC_INTR_PENDING_BIT) &&
3091 (board(dev)->layout != LAYOUT_4020))) {
88b12a9a 3092 DEBUG_PRINT("pio fifo drain\n");
5f74ea14 3093 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 3094 if (priv(dev)->ai_cmd_running) {
5f74ea14 3095 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3096 pio_drain_ai_fifo(dev);
3097 } else
5f74ea14 3098 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a 3099 }
9ef4dea6 3100 /* if we are have all the data, then quit */
88b12a9a 3101 if ((cmd->stop_src == TRIG_COUNT && priv(dev)->ai_count <= 0) ||
0a85b6f0 3102 (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
88b12a9a
FMH
3103 async->events |= COMEDI_CB_EOA;
3104 }
3105
3106 cfc_handle_events(dev, s);
3107}
3108
da91b269 3109static inline unsigned int prev_ao_dma_index(struct comedi_device *dev)
88b12a9a
FMH
3110{
3111 unsigned int buffer_index;
3112
3113 if (priv(dev)->ao_dma_index == 0)
3114 buffer_index = AO_DMA_RING_COUNT - 1;
3115 else
3116 buffer_index = priv(dev)->ao_dma_index - 1;
3117 return buffer_index;
3118}
3119
da91b269 3120static int last_ao_dma_load_completed(struct comedi_device *dev)
88b12a9a
FMH
3121{
3122 unsigned int buffer_index;
3123 unsigned int transfer_address;
3124 unsigned short dma_status;
3125
3126 buffer_index = prev_ao_dma_index(dev);
3127 dma_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
3128 if ((dma_status & PLX_DMA_DONE_BIT) == 0)
3129 return 0;
3130
3131 transfer_address =
0a85b6f0 3132 readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
88b12a9a
FMH
3133 if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index])
3134 return 0;
3135
3136 return 1;
3137}
3138
0a85b6f0
MT
3139static int ao_stopped_by_error(struct comedi_device *dev,
3140 const struct comedi_cmd *cmd)
88b12a9a
FMH
3141{
3142 if (cmd->stop_src == TRIG_NONE)
3143 return 1;
3144 if (cmd->stop_src == TRIG_COUNT) {
3145 if (priv(dev)->ao_count)
3146 return 1;
3147 if (last_ao_dma_load_completed(dev) == 0)
3148 return 1;
3149 }
3150 return 0;
3151}
3152
da91b269 3153static inline int ao_dma_needs_restart(struct comedi_device *dev,
0a85b6f0 3154 unsigned short dma_status)
88b12a9a
FMH
3155{
3156 if ((dma_status & PLX_DMA_DONE_BIT) == 0 ||
0a85b6f0 3157 (dma_status & PLX_DMA_EN_BIT) == 0)
88b12a9a
FMH
3158 return 0;
3159 if (last_ao_dma_load_completed(dev))
3160 return 0;
3161
3162 return 1;
3163}
3164
da91b269 3165static void restart_ao_dma(struct comedi_device *dev)
88b12a9a
FMH
3166{
3167 unsigned int dma_desc_bits;
3168
3169 dma_desc_bits =
0a85b6f0 3170 readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
88b12a9a
FMH
3171 dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
3172 DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits);
3173 load_first_dma_descriptor(dev, 0, dma_desc_bits);
3174
3175 dma_start_sync(dev, 0);
3176}
3177
0a85b6f0
MT
3178static void handle_ao_interrupt(struct comedi_device *dev,
3179 unsigned short status, unsigned int plx_status)
88b12a9a 3180{
34c43922 3181 struct comedi_subdevice *s = dev->write_subdev;
d163679c 3182 struct comedi_async *async;
ea6d0d4c 3183 struct comedi_cmd *cmd;
88b12a9a
FMH
3184 uint8_t dma0_status;
3185 unsigned long flags;
3186
3187 /* board might not support ao, in which case write_subdev is NULL */
3188 if (s == NULL)
3189 return;
3190 async = s->async;
3191 cmd = &async->cmd;
3192
9ef4dea6 3193 /* spin lock makes sure noone else changes plx dma control reg */
5f74ea14 3194 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 3195 dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
9ef4dea6 3196 if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */
88b12a9a 3197 if ((dma0_status & PLX_DMA_EN_BIT)
0a85b6f0 3198 && !(dma0_status & PLX_DMA_DONE_BIT))
88b12a9a 3199 writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
0a85b6f0 3200 priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
88b12a9a
FMH
3201 else
3202 writeb(PLX_CLEAR_DMA_INTR_BIT,
0a85b6f0 3203 priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
5f74ea14 3204 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3205 DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
3206 if (dma0_status & PLX_DMA_EN_BIT) {
3207 load_ao_dma(dev, cmd);
3208 /* try to recover from dma end-of-chain event */
3209 if (ao_dma_needs_restart(dev, dma0_status))
3210 restart_ao_dma(dev);
3211 }
3212 DEBUG_PRINT(" cleared dma ch0 interrupt\n");
3213 } else
5f74ea14 3214 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3215
3216 if ((status & DAC_DONE_BIT)) {
3217 async->events |= COMEDI_CB_EOA;
3218 if (ao_stopped_by_error(dev, cmd))
3219 async->events |= COMEDI_CB_ERROR;
3220 DEBUG_PRINT("plx dma0 desc reg 0x%x\n",
0a85b6f0
MT
3221 readl(priv(dev)->plx9080_iobase +
3222 PLX_DMA0_DESCRIPTOR_REG));
88b12a9a 3223 DEBUG_PRINT("plx dma0 address reg 0x%x\n",
0a85b6f0
MT
3224 readl(priv(dev)->plx9080_iobase +
3225 PLX_DMA0_PCI_ADDRESS_REG));
88b12a9a
FMH
3226 }
3227 cfc_handle_events(dev, s);
3228}
3229
70265d24 3230static irqreturn_t handle_interrupt(int irq, void *d)
88b12a9a 3231{
71b5f4f1 3232 struct comedi_device *dev = d;
88b12a9a
FMH
3233 unsigned short status;
3234 uint32_t plx_status;
3235 uint32_t plx_bits;
3236
3237 plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
3238 status = readw(priv(dev)->main_iobase + HW_STATUS_REG);
3239
3240 DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status);
3241 DEBUG_PRINT("plx status 0x%x\n", plx_status);
3242
3243 /* an interrupt before all the postconfig stuff gets done could
3244 * cause a NULL dereference if we continue through the
3245 * interrupt handler */
3246 if (dev->attached == 0) {
3247 DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring",
0a85b6f0 3248 status);
88b12a9a
FMH
3249 return IRQ_HANDLED;
3250 }
3251 handle_ai_interrupt(dev, status, plx_status);
3252 handle_ao_interrupt(dev, status, plx_status);
3253
9ef4dea6
BP
3254 /* clear possible plx9080 interrupt sources */
3255 if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */
88b12a9a
FMH
3256 plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
3257 writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
3258 DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
3259 }
3260
3261 DEBUG_PRINT("exiting handler\n");
3262
3263 return IRQ_HANDLED;
3264}
3265
f31d0008 3266static void abort_dma(struct comedi_device *dev, unsigned int channel)
88b12a9a
FMH
3267{
3268 unsigned long flags;
3269
9ef4dea6 3270 /* spinlock for plx dma control/status reg */
5f74ea14 3271 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a
FMH
3272
3273 plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
3274
5f74ea14 3275 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3276}
3277
da91b269 3278static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a
FMH
3279{
3280 unsigned long flags;
3281
5f74ea14 3282 spin_lock_irqsave(&dev->spinlock, flags);
88b12a9a 3283 if (priv(dev)->ai_cmd_running == 0) {
5f74ea14 3284 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3285 return 0;
3286 }
3287 priv(dev)->ai_cmd_running = 0;
5f74ea14 3288 spin_unlock_irqrestore(&dev->spinlock, flags);
88b12a9a
FMH
3289
3290 disable_ai_pacing(dev);
3291
3292 abort_dma(dev, 1);
3293
3294 DEBUG_PRINT("ai canceled\n");
3295 return 0;
3296}
3297
da91b269 3298static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3299 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3300{
3301 int chan = CR_CHAN(insn->chanspec);
3302 int range = CR_RANGE(insn->chanspec);
3303
9ef4dea6 3304 /* do some initializing */
88b12a9a
FMH
3305 writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
3306
9ef4dea6 3307 /* set range */
88b12a9a
FMH
3308 set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range);
3309 writew(priv(dev)->dac_control1_bits,
0a85b6f0 3310 priv(dev)->main_iobase + DAC_CONTROL1_REG);
88b12a9a 3311
9ef4dea6 3312 /* write to channel */
88b12a9a
FMH
3313 if (board(dev)->layout == LAYOUT_4020) {
3314 writew(data[0] & 0xff,
0a85b6f0 3315 priv(dev)->main_iobase + dac_lsb_4020_reg(chan));
88b12a9a 3316 writew((data[0] >> 8) & 0xf,
0a85b6f0 3317 priv(dev)->main_iobase + dac_msb_4020_reg(chan));
88b12a9a
FMH
3318 } else {
3319 writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan));
3320 }
3321
9ef4dea6 3322 /* remember output value */
88b12a9a
FMH
3323 priv(dev)->ao_value[chan] = data[0];
3324
3325 return 1;
3326}
3327
0a85b6f0
MT
3328static int ao_readback_insn(struct comedi_device *dev,
3329 struct comedi_subdevice *s,
3330 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3331{
3332 data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)];
3333
3334 return 1;
3335}
3336
0a85b6f0
MT
3337static void set_dac_control0_reg(struct comedi_device *dev,
3338 const struct comedi_cmd *cmd)
88b12a9a
FMH
3339{
3340 unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
0a85b6f0 3341 WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
88b12a9a
FMH
3342
3343 if (cmd->start_src == TRIG_EXT) {
3344 bits |= WAVEFORM_TRIG_EXT_BITS;
3345 if (cmd->start_arg & CR_INVERT)
3346 bits |= WAVEFORM_TRIG_FALLING_BIT;
3347 } else {
3348 bits |= WAVEFORM_TRIG_SOFT_BITS;
3349 }
3350 if (cmd->scan_begin_src == TRIG_EXT) {
3351 bits |= DAC_EXT_UPDATE_ENABLE_BIT;
3352 if (cmd->scan_begin_arg & CR_INVERT)
3353 bits |= DAC_EXT_UPDATE_FALLING_BIT;
3354 }
3355 writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG);
3356}
3357
0a85b6f0
MT
3358static void set_dac_control1_reg(struct comedi_device *dev,
3359 const struct comedi_cmd *cmd)
88b12a9a
FMH
3360{
3361 int i;
3362
3363 for (i = 0; i < cmd->chanlist_len; i++) {
3364 int channel, range;
3365
3366 channel = CR_CHAN(cmd->chanlist[i]);
3367 range = CR_RANGE(cmd->chanlist[i]);
3368 set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
0a85b6f0 3369 range);
88b12a9a
FMH
3370 }
3371 priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT;
3372 writew(priv(dev)->dac_control1_bits,
0a85b6f0 3373 priv(dev)->main_iobase + DAC_CONTROL1_REG);
88b12a9a
FMH
3374}
3375
0a85b6f0
MT
3376static void set_dac_select_reg(struct comedi_device *dev,
3377 const struct comedi_cmd *cmd)
88b12a9a
FMH
3378{
3379 uint16_t bits;
3380 unsigned int first_channel, last_channel;
3381
3382 first_channel = CR_CHAN(cmd->chanlist[0]);
3383 last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
3384 if (last_channel < first_channel)
3385 comedi_error(dev, "bug! last ao channel < first ao channel");
3386
3387 bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
3388
3389 writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG);
3390}
3391
0a85b6f0
MT
3392static void set_dac_interval_regs(struct comedi_device *dev,
3393 const struct comedi_cmd *cmd)
88b12a9a
FMH
3394{
3395 unsigned int divisor;
3396
3397 if (cmd->scan_begin_src != TRIG_TIMER)
3398 return;
3399
3400 divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
3401 if (divisor > max_counter_value) {
3402 comedi_error(dev, "bug! ao divisor too big");
3403 divisor = max_counter_value;
3404 }
3405 writew(divisor & 0xffff,
0a85b6f0 3406 priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
88b12a9a 3407 writew((divisor >> 16) & 0xff,
0a85b6f0 3408 priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
88b12a9a
FMH
3409}
3410
da91b269 3411static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
0a85b6f0 3412 const struct comedi_cmd *cmd)
88b12a9a
FMH
3413{
3414 unsigned int num_bytes, buffer_index, prev_buffer_index;
3415 unsigned int next_bits;
3416
3417 buffer_index = priv(dev)->ao_dma_index;
3418 prev_buffer_index = prev_ao_dma_index(dev);
3419
3420 DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index,
0a85b6f0 3421 priv(dev)->ao_buffer_bus_addr[buffer_index]);
88b12a9a
FMH
3422
3423 num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
3424 if (num_bytes > DMA_BUFFER_SIZE)
3425 num_bytes = DMA_BUFFER_SIZE;
3426 if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count)
3427 num_bytes = priv(dev)->ao_count;
3428 num_bytes -= num_bytes % bytes_in_sample;
3429
3430 if (num_bytes == 0)
3431 return 0;
3432
3433 DEBUG_PRINT("loading %i bytes\n", num_bytes);
3434
3435 num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
0a85b6f0
MT
3436 priv(dev)->
3437 ao_buffer[buffer_index],
3438 num_bytes);
88b12a9a 3439 priv(dev)->ao_dma_desc[buffer_index].transfer_size =
0a85b6f0 3440 cpu_to_le32(num_bytes);
88b12a9a
FMH
3441 /* set end of chain bit so we catch underruns */
3442 next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next);
3443 next_bits |= PLX_END_OF_CHAIN_BIT;
3444 priv(dev)->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
3445 /* clear end of chain bit on previous buffer now that we have set it
3446 * for the last buffer */
3447 next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[prev_buffer_index].next);
3448 next_bits &= ~PLX_END_OF_CHAIN_BIT;
3449 priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
3450
3451 priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
3452 priv(dev)->ao_count -= num_bytes;
3453
3454 return num_bytes;
3455}
3456
da91b269 3457static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
88b12a9a
FMH
3458{
3459 unsigned int num_bytes;
3460 unsigned int next_transfer_addr;
f31d0008 3461 void __iomem *pci_addr_reg =
0a85b6f0 3462 priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
88b12a9a
FMH
3463 unsigned int buffer_index;
3464
3465 do {
3466 buffer_index = priv(dev)->ao_dma_index;
3467 /* don't overwrite data that hasn't been transferred yet */
3468 next_transfer_addr = readl(pci_addr_reg);
3469 if (next_transfer_addr >=
0a85b6f0
MT
3470 priv(dev)->ao_buffer_bus_addr[buffer_index]
3471 && next_transfer_addr <
3472 priv(dev)->ao_buffer_bus_addr[buffer_index] +
3473 DMA_BUFFER_SIZE)
88b12a9a
FMH
3474 return;
3475 num_bytes = load_ao_dma_buffer(dev, cmd);
3476 } while (num_bytes >= DMA_BUFFER_SIZE);
3477}
3478
da91b269 3479static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
88b12a9a
FMH
3480{
3481 unsigned int num_bytes;
3482 int i;
3483
3484 /* clear queue pointer too, since external queue has
3485 * weird interactions with ao fifo */
3486 writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
3487 writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
3488
3489 num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
3490 if (cmd->stop_src == TRIG_COUNT &&
0a85b6f0 3491 num_bytes / bytes_in_sample > priv(dev)->ao_count)
88b12a9a
FMH
3492 num_bytes = priv(dev)->ao_count * bytes_in_sample;
3493 num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
0a85b6f0
MT
3494 priv(dev)->ao_bounce_buffer,
3495 num_bytes);
88b12a9a
FMH
3496 for (i = 0; i < num_bytes / bytes_in_sample; i++) {
3497 writew(priv(dev)->ao_bounce_buffer[i],
0a85b6f0 3498 priv(dev)->main_iobase + DAC_FIFO_REG);
88b12a9a
FMH
3499 }
3500 priv(dev)->ao_count -= num_bytes / bytes_in_sample;
3501 if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0)
3502 return 0;
3503 num_bytes = load_ao_dma_buffer(dev, cmd);
3504 if (num_bytes == 0)
3505 return -1;
3506 if (num_bytes >= DMA_BUFFER_SIZE) ;
3507 load_ao_dma(dev, cmd);
3508
3509 dma_start_sync(dev, 0);
3510
3511 return 0;
3512}
3513
da91b269 3514static inline int external_ai_queue_in_use(struct comedi_device *dev)
88b12a9a
FMH
3515{
3516 if (dev->read_subdev->busy)
3517 return 0;
3518 if (board(dev)->layout == LAYOUT_4020)
3519 return 0;
3520 else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd))
3521 return 0;
3522 return 1;
3523}
3524
da91b269 3525static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a 3526{
ea6d0d4c 3527 struct comedi_cmd *cmd = &s->async->cmd;
88b12a9a
FMH
3528
3529 if (external_ai_queue_in_use(dev)) {
3530 warn_external_queue(dev);
3531 return -EBUSY;
3532 }
3533 /* disable analog output system during setup */
3534 writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
3535
3536 priv(dev)->ao_dma_index = 0;
3537 priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len;
3538
3539 set_dac_select_reg(dev, cmd);
3540 set_dac_interval_regs(dev, cmd);
3541 load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr |
0a85b6f0 3542 PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
88b12a9a
FMH
3543
3544 set_dac_control1_reg(dev, cmd);
3545 s->async->inttrig = ao_inttrig;
3546
3547 return 0;
3548}
3549
da91b269 3550static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3551 unsigned int trig_num)
88b12a9a 3552{
ea6d0d4c 3553 struct comedi_cmd *cmd = &s->async->cmd;
88b12a9a
FMH
3554 int retval;
3555
3556 if (trig_num != 0)
3557 return -EINVAL;
3558
3559 retval = prep_ao_dma(dev, cmd);
3560 if (retval < 0)
3561 return -EPIPE;
3562
3563 set_dac_control0_reg(dev, cmd);
3564
3565 if (cmd->start_src == TRIG_INT)
3566 writew(0, priv(dev)->main_iobase + DAC_START_REG);
3567
3568 s->async->inttrig = NULL;
3569
3570 return 0;
3571}
3572
da91b269 3573static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3574 struct comedi_cmd *cmd)
88b12a9a
FMH
3575{
3576 int err = 0;
3577 int tmp;
3578 unsigned int tmp_arg;
3579 int i;
3580
3581 /* step 1: make sure trigger sources are trivially valid */
3582
3583 tmp = cmd->start_src;
3584 cmd->start_src &= TRIG_INT | TRIG_EXT;
3585 if (!cmd->start_src || tmp != cmd->start_src)
3586 err++;
3587
3588 tmp = cmd->scan_begin_src;
3589 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
3590 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
3591 err++;
3592
3593 tmp = cmd->convert_src;
3594 cmd->convert_src &= TRIG_NOW;
3595 if (!cmd->convert_src || tmp != cmd->convert_src)
3596 err++;
3597
3598 tmp = cmd->scan_end_src;
3599 cmd->scan_end_src &= TRIG_COUNT;
3600 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
3601 err++;
3602
3603 tmp = cmd->stop_src;
3604 cmd->stop_src &= TRIG_NONE;
3605 if (!cmd->stop_src || tmp != cmd->stop_src)
3606 err++;
3607
3608 if (err)
3609 return 1;
3610
3611 /* step 2: make sure trigger sources are unique and mutually compatible */
3612
9ef4dea6 3613 /* uniqueness check */
88b12a9a
FMH
3614 if (cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
3615 err++;
3616 if (cmd->scan_begin_src != TRIG_TIMER &&
0a85b6f0 3617 cmd->scan_begin_src != TRIG_EXT)
88b12a9a
FMH
3618 err++;
3619
9ef4dea6 3620 /* compatibility check */
88b12a9a
FMH
3621 if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
3622 err++;
3623 if (cmd->stop_src != TRIG_COUNT &&
0a85b6f0 3624 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
88b12a9a
FMH
3625 err++;
3626
3627 if (err)
3628 return 2;
3629
3630 /* step 3: make sure arguments are trivially compatible */
3631
3632 if (cmd->scan_begin_src == TRIG_TIMER) {
3633 if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) {
3634 cmd->scan_begin_arg = board(dev)->ao_scan_speed;
3635 err++;
3636 }
3637 if (get_ao_divisor(cmd->scan_begin_arg,
0a85b6f0 3638 cmd->flags) > max_counter_value) {
88b12a9a 3639 cmd->scan_begin_arg =
0a85b6f0 3640 (max_counter_value + 2) * TIMER_BASE;
88b12a9a
FMH
3641 err++;
3642 }
3643 }
3644
3645 if (!cmd->chanlist_len) {
3646 cmd->chanlist_len = 1;
3647 err++;
3648 }
3649 if (cmd->scan_end_arg != cmd->chanlist_len) {
3650 cmd->scan_end_arg = cmd->chanlist_len;
3651 err++;
3652 }
3653
3654 if (err)
3655 return 3;
3656
3657 /* step 4: fix up any arguments */
3658
3659 if (cmd->scan_begin_src == TRIG_TIMER) {
3660 tmp_arg = cmd->scan_begin_arg;
3661 cmd->scan_begin_arg =
0a85b6f0 3662 get_divisor(cmd->scan_begin_arg, cmd->flags) * TIMER_BASE;
88b12a9a
FMH
3663 if (tmp_arg != cmd->scan_begin_arg)
3664 err++;
3665 }
3666
3667 if (err)
3668 return 4;
3669
3670 if (cmd->chanlist) {
3671 unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
3672 for (i = 1; i < cmd->chanlist_len; i++) {
3673 if (CR_CHAN(cmd->chanlist[i]) != first_channel + i) {
3674 comedi_error(dev,
0a85b6f0 3675 "chanlist must use consecutive channels");
88b12a9a
FMH
3676 err++;
3677 break;
3678 }
3679 }
3680 }
3681
3682 if (err)
3683 return 5;
3684
3685 return 0;
3686}
3687
da91b269 3688static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
88b12a9a
FMH
3689{
3690 writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
3691 abort_dma(dev, 0);
3692 return 0;
3693}
3694
318a5b2a 3695static int dio_callback(int dir, int port, int data, unsigned long arg)
88b12a9a 3696{
318a5b2a 3697 void __iomem *iobase = (void __iomem *)arg;
88b12a9a 3698 if (dir) {
f31d0008 3699 writeb(data, iobase + port);
88b12a9a
FMH
3700 DEBUG_PRINT("wrote 0x%x to port %i\n", data, port);
3701 return 0;
3702 } else {
f31d0008 3703 return readb(iobase + port);
88b12a9a
FMH
3704 }
3705}
3706
318a5b2a 3707static int dio_callback_4020(int dir, int port, int data, unsigned long arg)
88b12a9a 3708{
318a5b2a 3709 void __iomem *iobase = (void __iomem *)arg;
88b12a9a 3710 if (dir) {
f31d0008 3711 writew(data, iobase + 2 * port);
88b12a9a
FMH
3712 return 0;
3713 } else {
f31d0008 3714 return readw(iobase + 2 * port);
88b12a9a
FMH
3715 }
3716}
3717
da91b269 3718static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3719 struct comedi_insn *insn, unsigned int *data)
88b12a9a 3720{
790c5541 3721 unsigned int bits;
88b12a9a
FMH
3722
3723 bits = readb(priv(dev)->dio_counter_iobase + DI_REG);
3724 bits &= 0xf;
3725 data[1] = bits;
3726 data[0] = 0;
3727
3728 return 2;
3729}
3730
da91b269 3731static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3732 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3733{
3734 data[0] &= 0xf;
9ef4dea6 3735 /* zero bits we are going to change */
88b12a9a 3736 s->state &= ~data[0];
9ef4dea6 3737 /* set new bits */
88b12a9a
FMH
3738 s->state |= data[0] & data[1];
3739
3740 writeb(s->state, priv(dev)->dio_counter_iobase + DO_REG);
3741
3742 data[1] = s->state;
3743
3744 return 2;
3745}
3746
0a85b6f0
MT
3747static int dio_60xx_config_insn(struct comedi_device *dev,
3748 struct comedi_subdevice *s,
3749 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3750{
3751 unsigned int mask;
3752
3753 mask = 1 << CR_CHAN(insn->chanspec);
3754
3755 switch (data[0]) {
3756 case INSN_CONFIG_DIO_INPUT:
3757 s->io_bits &= ~mask;
3758 break;
3759 case INSN_CONFIG_DIO_OUTPUT:
3760 s->io_bits |= mask;
3761 break;
3762 case INSN_CONFIG_DIO_QUERY:
3763 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
3764 return 2;
3765 default:
3766 return -EINVAL;
3767 }
3768
3769 writeb(s->io_bits,
0a85b6f0 3770 priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
88b12a9a
FMH
3771
3772 return 1;
3773}
3774
da91b269 3775static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3776 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3777{
3778 if (data[0]) {
3779 s->state &= ~data[0];
3780 s->state |= (data[0] & data[1]);
3781 writeb(s->state,
0a85b6f0 3782 priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
88b12a9a
FMH
3783 }
3784
3785 data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
3786
3787 return 2;
3788}
3789
da91b269 3790static void caldac_write(struct comedi_device *dev, unsigned int channel,
0a85b6f0 3791 unsigned int value)
88b12a9a
FMH
3792{
3793 priv(dev)->caldac_state[channel] = value;
3794
3795 switch (board(dev)->layout) {
3796 case LAYOUT_60XX:
3797 case LAYOUT_64XX:
3798 caldac_8800_write(dev, channel, value);
3799 break;
3800 case LAYOUT_4020:
3801 caldac_i2c_write(dev, channel, value);
3802 break;
3803 default:
3804 break;
3805 }
3806}
3807
0a85b6f0
MT
3808static int calib_write_insn(struct comedi_device *dev,
3809 struct comedi_subdevice *s,
3810 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3811{
3812 int channel = CR_CHAN(insn->chanspec);
3813
3814 /* return immediately if setting hasn't changed, since
3815 * programming these things is slow */
3816 if (priv(dev)->caldac_state[channel] == data[0])
3817 return 1;
3818
3819 caldac_write(dev, channel, data[0]);
3820
3821 return 1;
3822}
3823
0a85b6f0
MT
3824static int calib_read_insn(struct comedi_device *dev,
3825 struct comedi_subdevice *s, struct comedi_insn *insn,
3826 unsigned int *data)
88b12a9a
FMH
3827{
3828 unsigned int channel = CR_CHAN(insn->chanspec);
3829
3830 data[0] = priv(dev)->caldac_state[channel];
3831
3832 return 1;
3833}
3834
da91b269 3835static void ad8402_write(struct comedi_device *dev, unsigned int channel,
0a85b6f0 3836 unsigned int value)
88b12a9a
FMH
3837{
3838 static const int bitstream_length = 10;
3839 unsigned int bit, register_bits;
3840 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
5f74ea14 3841 static const int ad8402_udelay = 1;
88b12a9a
FMH
3842
3843 priv(dev)->ad8402_state[channel] = value;
3844
3845 register_bits = SELECT_8402_64XX_BIT;
5f74ea14 3846 udelay(ad8402_udelay);
88b12a9a
FMH
3847 writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
3848
3849 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
3850 if (bitstream & bit)
3851 register_bits |= SERIAL_DATA_IN_BIT;
3852 else
3853 register_bits &= ~SERIAL_DATA_IN_BIT;
5f74ea14 3854 udelay(ad8402_udelay);
88b12a9a 3855 writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
5f74ea14 3856 udelay(ad8402_udelay);
88b12a9a 3857 writew(register_bits | SERIAL_CLOCK_BIT,
0a85b6f0 3858 priv(dev)->main_iobase + CALIBRATION_REG);
88b12a9a
FMH
3859 }
3860
5f74ea14 3861 udelay(ad8402_udelay);
88b12a9a
FMH
3862 writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
3863}
3864
3865/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
0a85b6f0
MT
3866static int ad8402_write_insn(struct comedi_device *dev,
3867 struct comedi_subdevice *s,
3868 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3869{
3870 int channel = CR_CHAN(insn->chanspec);
3871
3872 /* return immediately if setting hasn't changed, since
3873 * programming these things is slow */
3874 if (priv(dev)->ad8402_state[channel] == data[0])
3875 return 1;
3876
3877 priv(dev)->ad8402_state[channel] = data[0];
3878
3879 ad8402_write(dev, channel, data[0]);
3880
3881 return 1;
3882}
3883
0a85b6f0
MT
3884static int ad8402_read_insn(struct comedi_device *dev,
3885 struct comedi_subdevice *s,
3886 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3887{
3888 unsigned int channel = CR_CHAN(insn->chanspec);
3889
3890 data[0] = priv(dev)->ad8402_state[channel];
3891
3892 return 1;
3893}
3894
da91b269 3895static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
88b12a9a
FMH
3896{
3897 static const int bitstream_length = 11;
3898 static const int read_command = 0x6;
3899 unsigned int bitstream = (read_command << 8) | address;
3900 unsigned int bit;
f31d0008 3901 void __iomem * const plx_control_addr =
0a85b6f0 3902 priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
88b12a9a
FMH
3903 uint16_t value;
3904 static const int value_length = 16;
5f74ea14 3905 static const int eeprom_udelay = 1;
88b12a9a 3906
5f74ea14 3907 udelay(eeprom_udelay);
88b12a9a 3908 priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
9ef4dea6 3909 /* make sure we don't send anything to the i2c bus on 4020 */
88b12a9a
FMH
3910 priv(dev)->plx_control_bits |= CTL_USERO;
3911 writel(priv(dev)->plx_control_bits, plx_control_addr);
9ef4dea6 3912 /* activate serial eeprom */
5f74ea14 3913 udelay(eeprom_udelay);
88b12a9a
FMH
3914 priv(dev)->plx_control_bits |= CTL_EE_CS;
3915 writel(priv(dev)->plx_control_bits, plx_control_addr);
3916
9ef4dea6 3917 /* write read command and desired memory address */
88b12a9a 3918 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
9ef4dea6 3919 /* set bit to be written */
5f74ea14 3920 udelay(eeprom_udelay);
88b12a9a
FMH
3921 if (bitstream & bit)
3922 priv(dev)->plx_control_bits |= CTL_EE_W;
3923 else
3924 priv(dev)->plx_control_bits &= ~CTL_EE_W;
3925 writel(priv(dev)->plx_control_bits, plx_control_addr);
9ef4dea6 3926 /* clock in bit */
5f74ea14 3927 udelay(eeprom_udelay);
88b12a9a
FMH
3928 priv(dev)->plx_control_bits |= CTL_EE_CLK;
3929 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 3930 udelay(eeprom_udelay);
88b12a9a
FMH
3931 priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
3932 writel(priv(dev)->plx_control_bits, plx_control_addr);
3933 }
9ef4dea6 3934 /* read back value from eeprom memory location */
88b12a9a
FMH
3935 value = 0;
3936 for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
9ef4dea6 3937 /* clock out bit */
5f74ea14 3938 udelay(eeprom_udelay);
88b12a9a
FMH
3939 priv(dev)->plx_control_bits |= CTL_EE_CLK;
3940 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 3941 udelay(eeprom_udelay);
88b12a9a
FMH
3942 priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
3943 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 3944 udelay(eeprom_udelay);
88b12a9a
FMH
3945 if (readl(plx_control_addr) & CTL_EE_R)
3946 value |= bit;
3947 }
3948
9ef4dea6 3949 /* deactivate eeprom serial input */
5f74ea14 3950 udelay(eeprom_udelay);
88b12a9a
FMH
3951 priv(dev)->plx_control_bits &= ~CTL_EE_CS;
3952 writel(priv(dev)->plx_control_bits, plx_control_addr);
3953
3954 return value;
3955}
3956
0a85b6f0
MT
3957static int eeprom_read_insn(struct comedi_device *dev,
3958 struct comedi_subdevice *s,
3959 struct comedi_insn *insn, unsigned int *data)
88b12a9a
FMH
3960{
3961 data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
3962
3963 return 1;
3964}
3965
3966/* utility function that rounds desired timing to an achievable time, and
3967 * sets cmd members appropriately.
3968 * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
3969 */
ea6d0d4c 3970static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
88b12a9a
FMH
3971{
3972 unsigned int convert_divisor = 0, scan_divisor;
3973 static const int min_convert_divisor = 3;
3974 static const int max_convert_divisor =
0a85b6f0 3975 max_counter_value + min_convert_divisor;
88b12a9a
FMH
3976 static const int min_scan_divisor_4020 = 2;
3977 unsigned long long max_scan_divisor, min_scan_divisor;
3978
3979 if (cmd->convert_src == TRIG_TIMER) {
3980 if (board(dev)->layout == LAYOUT_4020) {
3981 cmd->convert_arg = 0;
3982 } else {
3983 convert_divisor =
0a85b6f0 3984 get_divisor(cmd->convert_arg, cmd->flags);
88b12a9a
FMH
3985 if (convert_divisor > max_convert_divisor)
3986 convert_divisor = max_convert_divisor;
3987 if (convert_divisor < min_convert_divisor)
3988 convert_divisor = min_convert_divisor;
3989 cmd->convert_arg = convert_divisor * TIMER_BASE;
3990 }
3991 } else if (cmd->convert_src == TRIG_NOW)
3992 cmd->convert_arg = 0;
3993
3994 if (cmd->scan_begin_src == TRIG_TIMER) {
3995 scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
3996 if (cmd->convert_src == TRIG_TIMER) {
9ef4dea6 3997 /* XXX check for integer overflows */
88b12a9a
FMH
3998 min_scan_divisor = convert_divisor * cmd->chanlist_len;
3999 max_scan_divisor =
0a85b6f0
MT
4000 (convert_divisor * cmd->chanlist_len - 1) +
4001 max_counter_value;
88b12a9a
FMH
4002 } else {
4003 min_scan_divisor = min_scan_divisor_4020;
4004 max_scan_divisor = max_counter_value + min_scan_divisor;
4005 }
4006 if (scan_divisor > max_scan_divisor)
4007 scan_divisor = max_scan_divisor;
4008 if (scan_divisor < min_scan_divisor)
4009 scan_divisor = min_scan_divisor;
4010 cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
4011 }
4012
4013 return;
4014}
4015
4016/* Gets nearest achievable timing given master clock speed, does not
4017 * take into account possible minimum/maximum divisor values. Used
4018 * by other timing checking functions. */
4019static unsigned int get_divisor(unsigned int ns, unsigned int flags)
4020{
4021 unsigned int divisor;
4022
4023 switch (flags & TRIG_ROUND_MASK) {
4024 case TRIG_ROUND_UP:
4025 divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
4026 break;
4027 case TRIG_ROUND_DOWN:
4028 divisor = ns / TIMER_BASE;
4029 break;
4030 case TRIG_ROUND_NEAREST:
4031 default:
4032 divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
4033 break;
4034 }
4035 return divisor;
4036}
4037
4038static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
4039{
4040 return get_divisor(ns, flags) - 2;
4041}
4042
9ef4dea6 4043/* adjusts the size of hardware fifo (which determines block size for dma xfers) */
da91b269 4044static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
88b12a9a
FMH
4045{
4046 unsigned int num_fifo_entries;
4047 int retval;
675935dd 4048 const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
88b12a9a
FMH
4049
4050 num_fifo_entries = num_samples / fifo->sample_packing_ratio;
4051
4052 retval = set_ai_fifo_segment_length(dev,
0a85b6f0
MT
4053 num_fifo_entries /
4054 fifo->num_segments);
88b12a9a
FMH
4055 if (retval < 0)
4056 return retval;
4057
4058 num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
4059
4060 DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
4061
4062 return num_samples;
4063}
4064
9ef4dea6 4065/* query length of fifo */
da91b269 4066static unsigned int ai_fifo_size(struct comedi_device *dev)
88b12a9a
FMH
4067{
4068 return priv(dev)->ai_fifo_segment_length *
0a85b6f0
MT
4069 board(dev)->ai_fifo->num_segments *
4070 board(dev)->ai_fifo->sample_packing_ratio;
88b12a9a
FMH
4071}
4072
da91b269 4073static int set_ai_fifo_segment_length(struct comedi_device *dev,
0a85b6f0 4074 unsigned int num_entries)
88b12a9a
FMH
4075{
4076 static const int increment_size = 0x100;
675935dd 4077 const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
88b12a9a
FMH
4078 unsigned int num_increments;
4079 uint16_t bits;
4080
4081 if (num_entries < increment_size)
4082 num_entries = increment_size;
4083 if (num_entries > fifo->max_segment_length)
4084 num_entries = fifo->max_segment_length;
4085
9ef4dea6 4086 /* 1 == 256 entries, 2 == 512 entries, etc */
88b12a9a
FMH
4087 num_increments = (num_entries + increment_size / 2) / increment_size;
4088
4089 bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
4090 priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
4091 priv(dev)->fifo_size_bits |= bits;
4092 writew(priv(dev)->fifo_size_bits,
0a85b6f0 4093 priv(dev)->main_iobase + FIFO_SIZE_REG);
88b12a9a
FMH
4094
4095 priv(dev)->ai_fifo_segment_length = num_increments * increment_size;
4096
4097 DEBUG_PRINT("set hardware fifo segment length to %i\n",
0a85b6f0 4098 priv(dev)->ai_fifo_segment_length);
88b12a9a
FMH
4099
4100 return priv(dev)->ai_fifo_segment_length;
4101}
4102
4103/* pci-6025 8800 caldac:
4104 * address 0 == dac channel 0 offset
4105 * address 1 == dac channel 0 gain
4106 * address 2 == dac channel 1 offset
4107 * address 3 == dac channel 1 gain
4108 * address 4 == fine adc offset
4109 * address 5 == coarse adc offset
4110 * address 6 == coarse adc gain
4111 * address 7 == fine adc gain
4112 */
4113/* pci-6402/16 uses all 8 channels for dac:
4114 * address 0 == dac channel 0 fine gain
4115 * address 1 == dac channel 0 coarse gain
4116 * address 2 == dac channel 0 coarse offset
4117 * address 3 == dac channel 1 coarse offset
4118 * address 4 == dac channel 1 fine gain
4119 * address 5 == dac channel 1 coarse gain
4120 * address 6 == dac channel 0 fine offset
4121 * address 7 == dac channel 1 fine offset
4122*/
4123
da91b269 4124static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
0a85b6f0 4125 uint8_t value)
88b12a9a
FMH
4126{
4127 static const int num_caldac_channels = 8;
4128 static const int bitstream_length = 11;
4129 unsigned int bitstream = ((address & 0x7) << 8) | value;
4130 unsigned int bit, register_bits;
4131 static const int caldac_8800_udelay = 1;
4132
4133 if (address >= num_caldac_channels) {
4134 comedi_error(dev, "illegal caldac channel");
4135 return -1;
4136 }
4137 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
4138 register_bits = 0;
4139 if (bitstream & bit)
4140 register_bits |= SERIAL_DATA_IN_BIT;
5f74ea14 4141 udelay(caldac_8800_udelay);
88b12a9a
FMH
4142 writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
4143 register_bits |= SERIAL_CLOCK_BIT;
5f74ea14 4144 udelay(caldac_8800_udelay);
88b12a9a
FMH
4145 writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
4146 }
5f74ea14 4147 udelay(caldac_8800_udelay);
88b12a9a 4148 writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG);
5f74ea14 4149 udelay(caldac_8800_udelay);
88b12a9a 4150 writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
5f74ea14 4151 udelay(caldac_8800_udelay);
88b12a9a
FMH
4152 return 0;
4153}
4154
9ef4dea6 4155/* 4020 caldacs */
0a85b6f0
MT
4156static int caldac_i2c_write(struct comedi_device *dev,
4157 unsigned int caldac_channel, unsigned int value)
88b12a9a
FMH
4158{
4159 uint8_t serial_bytes[3];
4160 uint8_t i2c_addr;
4161 enum pointer_bits {
9ef4dea6 4162 /* manual has gain and offset bits switched */
88b12a9a
FMH
4163 OFFSET_0_2 = 0x1,
4164 GAIN_0_2 = 0x2,
4165 OFFSET_1_3 = 0x4,
4166 GAIN_1_3 = 0x8,
4167 };
4168 enum data_bits {
4169 NOT_CLEAR_REGISTERS = 0x20,
4170 };
4171
4172 switch (caldac_channel) {
9ef4dea6 4173 case 0: /* chan 0 offset */
88b12a9a
FMH
4174 i2c_addr = CALDAC0_I2C_ADDR;
4175 serial_bytes[0] = OFFSET_0_2;
4176 break;
9ef4dea6 4177 case 1: /* chan 1 offset */
88b12a9a
FMH
4178 i2c_addr = CALDAC0_I2C_ADDR;
4179 serial_bytes[0] = OFFSET_1_3;
4180 break;
9ef4dea6 4181 case 2: /* chan 2 offset */
88b12a9a
FMH
4182 i2c_addr = CALDAC1_I2C_ADDR;
4183 serial_bytes[0] = OFFSET_0_2;
4184 break;
9ef4dea6 4185 case 3: /* chan 3 offset */
88b12a9a
FMH
4186 i2c_addr = CALDAC1_I2C_ADDR;
4187 serial_bytes[0] = OFFSET_1_3;
4188 break;
9ef4dea6 4189 case 4: /* chan 0 gain */
88b12a9a
FMH
4190 i2c_addr = CALDAC0_I2C_ADDR;
4191 serial_bytes[0] = GAIN_0_2;
4192 break;
9ef4dea6 4193 case 5: /* chan 1 gain */
88b12a9a
FMH
4194 i2c_addr = CALDAC0_I2C_ADDR;
4195 serial_bytes[0] = GAIN_1_3;
4196 break;
9ef4dea6 4197 case 6: /* chan 2 gain */
88b12a9a
FMH
4198 i2c_addr = CALDAC1_I2C_ADDR;
4199 serial_bytes[0] = GAIN_0_2;
4200 break;
9ef4dea6 4201 case 7: /* chan 3 gain */
88b12a9a
FMH
4202 i2c_addr = CALDAC1_I2C_ADDR;
4203 serial_bytes[0] = GAIN_1_3;
4204 break;
4205 default:
4206 comedi_error(dev, "invalid caldac channel\n");
4207 return -1;
4208 break;
4209 }
4210 serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
4211 serial_bytes[2] = value & 0xff;
4212 i2c_write(dev, i2c_addr, serial_bytes, 3);
4213 return 0;
4214}
4215
9ef4dea6 4216/* Their i2c requires a huge delay on setting clock or data high for some reason */
5f74ea14
GKH
4217static const int i2c_high_udelay = 1000;
4218static const int i2c_low_udelay = 10;
88b12a9a 4219
9ef4dea6 4220/* set i2c data line high or low */
da91b269 4221static void i2c_set_sda(struct comedi_device *dev, int state)
88b12a9a
FMH
4222{
4223 static const int data_bit = CTL_EE_W;
f31d0008
GKH
4224 void __iomem *plx_control_addr = priv(dev)->plx9080_iobase +
4225 PLX_CONTROL_REG;
88b12a9a
FMH
4226
4227 if (state) {
9ef4dea6 4228 /* set data line high */
88b12a9a
FMH
4229 priv(dev)->plx_control_bits &= ~data_bit;
4230 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 4231 udelay(i2c_high_udelay);
0a85b6f0
MT
4232 } else { /* set data line low */
4233
88b12a9a
FMH
4234 priv(dev)->plx_control_bits |= data_bit;
4235 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 4236 udelay(i2c_low_udelay);
88b12a9a
FMH
4237 }
4238}
4239
9ef4dea6 4240/* set i2c clock line high or low */
da91b269 4241static void i2c_set_scl(struct comedi_device *dev, int state)
88b12a9a
FMH
4242{
4243 static const int clock_bit = CTL_USERO;
f31d0008
GKH
4244 void __iomem *plx_control_addr = priv(dev)->plx9080_iobase +
4245 PLX_CONTROL_REG;
88b12a9a
FMH
4246
4247 if (state) {
9ef4dea6 4248 /* set clock line high */
88b12a9a
FMH
4249 priv(dev)->plx_control_bits &= ~clock_bit;
4250 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 4251 udelay(i2c_high_udelay);
0a85b6f0
MT
4252 } else { /* set clock line low */
4253
88b12a9a
FMH
4254 priv(dev)->plx_control_bits |= clock_bit;
4255 writel(priv(dev)->plx_control_bits, plx_control_addr);
5f74ea14 4256 udelay(i2c_low_udelay);
88b12a9a
FMH
4257 }
4258}
4259
da91b269 4260static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
88b12a9a
FMH
4261{
4262 uint8_t bit;
4263 unsigned int num_bits = 8;
4264
4265 DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
4266
4267 for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
4268 i2c_set_scl(dev, 0);
4269 if ((byte & bit))
4270 i2c_set_sda(dev, 1);
4271 else
4272 i2c_set_sda(dev, 0);
4273 i2c_set_scl(dev, 1);
4274 }
4275}
4276
9ef4dea6 4277/* we can't really read the lines, so fake it */
da91b269 4278static int i2c_read_ack(struct comedi_device *dev)
88b12a9a
FMH
4279{
4280 i2c_set_scl(dev, 0);
4281 i2c_set_sda(dev, 1);
4282 i2c_set_scl(dev, 1);
4283
9ef4dea6 4284 return 0; /* return fake acknowledge bit */
88b12a9a
FMH
4285}
4286
9ef4dea6 4287/* send start bit */
da91b269 4288static void i2c_start(struct comedi_device *dev)
88b12a9a
FMH
4289{
4290 i2c_set_scl(dev, 1);
4291 i2c_set_sda(dev, 1);
4292 i2c_set_sda(dev, 0);
4293}
4294
9ef4dea6 4295/* send stop bit */
da91b269 4296static void i2c_stop(struct comedi_device *dev)
88b12a9a
FMH
4297{
4298 i2c_set_scl(dev, 0);
4299 i2c_set_sda(dev, 0);
4300 i2c_set_scl(dev, 1);
4301 i2c_set_sda(dev, 1);
4302}
4303
da91b269 4304static void i2c_write(struct comedi_device *dev, unsigned int address,
0a85b6f0 4305 const uint8_t * data, unsigned int length)
88b12a9a
FMH
4306{
4307 unsigned int i;
4308 uint8_t bitstream;
4309 static const int read_bit = 0x1;
4310
9ef4dea6 4311/* XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus */
88b12a9a 4312
9ef4dea6 4313 /* make sure we dont send anything to eeprom */
88b12a9a
FMH
4314 priv(dev)->plx_control_bits &= ~CTL_EE_CS;
4315
4316 i2c_stop(dev);
4317 i2c_start(dev);
4318
9ef4dea6 4319 /* send address and write bit */
88b12a9a
FMH
4320 bitstream = (address << 1) & ~read_bit;
4321 i2c_write_byte(dev, bitstream);
4322
9ef4dea6 4323 /* get acknowledge */
88b12a9a
FMH
4324 if (i2c_read_ack(dev) != 0) {
4325 comedi_error(dev, "i2c write failed: no acknowledge");
4326 i2c_stop(dev);
4327 return;
4328 }
9ef4dea6 4329 /* write data bytes */
88b12a9a
FMH
4330 for (i = 0; i < length; i++) {
4331 i2c_write_byte(dev, data[i]);
4332 if (i2c_read_ack(dev) != 0) {
4333 comedi_error(dev, "i2c write failed: no acknowledge");
4334 i2c_stop(dev);
4335 return;
4336 }
4337 }
4338 i2c_stop(dev);
4339}
90f703d3
AT
4340
4341MODULE_AUTHOR("Comedi http://www.comedi.org");
4342MODULE_DESCRIPTION("Comedi low-level driver");
4343MODULE_LICENSE("GPL");