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