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