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