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