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