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