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