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