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