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