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