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