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