2 * Comedi driver for NI PCI-MIO E series cards
4 * COMEDI - Linux Control and Measurement Device Interface
5 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
20 * Description: National Instruments PCI-MIO-E series and M series (all boards)
21 * Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
22 * Herman Bruyninckx, Terry Barnaby
24 * Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
25 * PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014,
26 * PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E,
27 * PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E,
28 * PCI-6035E, PCI-6052E,
29 * PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224,
30 * PCI-6225, PXI-6225, PCI-6229, PCI-6250,
31 * PCI-6251, PXI-6251, PCIe-6251, PXIe-6251,
32 * PCI-6254, PCI-6259, PCIe-6259,
33 * PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
34 * PCI-6711, PXI-6711, PCI-6713, PXI-6713,
35 * PXI-6071E, PCI-6070E, PXI-6070E,
36 * PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
38 * Updated: Mon, 09 Jan 2012 14:52:48 +0000
40 * These boards are almost identical to the AT-MIO E series, except that
41 * they use the PCI bus instead of ISA (i.e., AT). See the notes for the
42 * ni_atmio.o driver for additional information about these boards.
44 * Autocalibration is supported on many of the devices, using the
45 * comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
46 * M-Series boards do analog input and analog output calibration entirely
47 * in software. The software calibration corrects the analog input for
48 * offset, gain and nonlinearity. The analog outputs are corrected for
49 * offset and gain. See the comedilib documentation on
50 * comedi_get_softcal_converter() for more information.
52 * By default, the driver uses DMA to transfer analog input data to
53 * memory. When DMA is enabled, not all triggering features are
56 * Digital I/O may not work on 673x.
58 * Note that the PCI-6143 is a simultaineous sampling device with 8
59 * convertors. With this board all of the convertors perform one
60 * simultaineous sample during a scan interval. The period for a scan
61 * is used for the convert time in a Comedi cmd. The convert trigger
62 * source is normally set to TRIG_NOW by default.
64 * The RTSI trigger bus is supported on these cards on subdevice 10.
65 * See the comedilib documentation for details.
67 * Information (number of channels, bits, etc.) for some devices may be
68 * incorrect. Please check this and submit a bug if there are problems
71 * SCXI is probably broken for m-series boards.
74 * - When DMA is enabled, COMEDI_EV_CONVERT does not work correctly.
78 * The PCI-MIO E series driver was originally written by
79 * Tomasz Motylewski <...>, and ported to comedi by ds.
82 * 341079b.pdf PCI E Series Register-Level Programmer Manual
83 * 340934b.pdf DAQ-STC reference manual
85 * 322080b.pdf 6711/6713/6715 User Manual
87 * 320945c.pdf PCI E Series User Manual
88 * 322138a.pdf PCI-6052E and DAQPad-6052E User Manual
91 * - need to deal with external reference for DAC, and other DAC
92 * properties in board properties
93 * - deal with at-mio-16de-10 revision D to N changes, etc.
94 * - need to add other CALDAC type
95 * - need to slow down DAC loading. I don't trust NI's claim that
96 * two writes to the PCI bus slows IO enough. I would prefer to
98 * Timing specs: (clock)
105 #include <linux/module.h>
106 #include <linux/delay.h>
108 #include "../comedi_pci.h"
110 #include <asm/byteorder.h>
118 * These are not all the possible ao ranges for 628x boards.
119 * They can do OFFSET +- REFERENCE where OFFSET can be
120 * 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
121 * be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's
122 * 63 different possibilities. An AO channel
123 * can not act as it's own OFFSET or REFERENCE.
125 static const struct comedi_lrange range_ni_M_628x_ao = {
139 static const struct comedi_lrange range_ni_M_625x_ao = {
147 enum ni_pcimio_boardid {
148 BOARD_PCIMIO_16XE_50,
149 BOARD_PCIMIO_16XE_10,
208 static const struct ni_board_struct ni_boards[] = {
209 [BOARD_PCIMIO_16XE_50] = {
210 .name = "pci-mio-16xe-50",
212 .ai_maxdata = 0xffff,
213 .ai_fifo_depth = 2048,
215 .gainlkup = ai_gain_8,
218 .ao_maxdata = 0x0fff,
219 .ao_range_table = &range_bipolar10,
221 .caldac = { dac8800, dac8043 },
223 [BOARD_PCIMIO_16XE_10] = {
224 .name = "pci-mio-16xe-10", /* aka pci-6030E */
226 .ai_maxdata = 0xffff,
227 .ai_fifo_depth = 512,
229 .gainlkup = ai_gain_14,
232 .ao_maxdata = 0xffff,
233 .ao_fifo_depth = 2048,
234 .ao_range_table = &range_ni_E_ao_ext,
236 .caldac = { dac8800, dac8043, ad8522 },
241 .ai_maxdata = 0xffff,
242 .ai_fifo_depth = 512,
244 .gainlkup = ai_gain_4,
247 .ao_maxdata = 0xffff,
248 .ao_range_table = &range_bipolar10,
250 .caldac = { ad8804_debug },
255 .ai_maxdata = 0xffff,
256 .ai_fifo_depth = 512,
258 .gainlkup = ai_gain_14,
261 .ao_maxdata = 0xffff,
262 .ao_fifo_depth = 2048,
263 .ao_range_table = &range_ni_E_ao_ext,
265 .caldac = { dac8800, dac8043, ad8522 },
267 [BOARD_PCIMIO_16E_1] = {
268 .name = "pci-mio-16e-1", /* aka pci-6070e */
270 .ai_maxdata = 0x0fff,
271 .ai_fifo_depth = 512,
272 .gainlkup = ai_gain_16,
275 .ao_maxdata = 0x0fff,
276 .ao_fifo_depth = 2048,
277 .ao_range_table = &range_ni_E_ao_ext,
279 .caldac = { mb88341 },
281 [BOARD_PCIMIO_16E_4] = {
282 .name = "pci-mio-16e-4", /* aka pci-6040e */
284 .ai_maxdata = 0x0fff,
285 .ai_fifo_depth = 512,
286 .gainlkup = ai_gain_16,
288 * there have been reported problems with
289 * full speed on this board
293 .ao_maxdata = 0x0fff,
294 .ao_fifo_depth = 512,
295 .ao_range_table = &range_ni_E_ao_ext,
297 .caldac = { ad8804_debug }, /* doc says mb88341 */
302 .ai_maxdata = 0x0fff,
303 .ai_fifo_depth = 512,
304 .gainlkup = ai_gain_16,
307 .ao_maxdata = 0x0fff,
308 .ao_fifo_depth = 512,
309 .ao_range_table = &range_ni_E_ao_ext,
311 .caldac = { mb88341 },
316 .ai_maxdata = 0xffff,
317 .ai_fifo_depth = 512,
319 .gainlkup = ai_gain_14,
322 .ao_maxdata = 0xffff,
323 .ao_fifo_depth = 2048,
324 .ao_range_table = &range_ni_E_ao_ext,
326 .caldac = { dac8800, dac8043, ad8522 },
331 .ai_maxdata = 0xffff,
332 .ai_fifo_depth = 512,
334 .gainlkup = ai_gain_14,
336 .caldac = { dac8800, dac8043, ad8522 },
341 .ai_maxdata = 0xffff,
342 .ai_fifo_depth = 512,
344 .gainlkup = ai_gain_14,
346 .caldac = { dac8800, dac8043, ad8522 },
351 .ai_maxdata = 0x0fff,
352 .ai_fifo_depth = 512,
354 .gainlkup = ai_gain_16,
357 .ao_maxdata = 0x0fff,
358 .ao_fifo_depth = 2048,
359 .ao_range_table = &range_ni_E_ao_ext,
361 .caldac = { ad8804_debug },
366 .ai_maxdata = 0x0fff,
367 .ai_fifo_depth = 512,
368 .gainlkup = ai_gain_4,
370 .caldac = { ad8804_debug }, /* manual is wrong */
375 .ai_maxdata = 0x0fff,
376 .ai_fifo_depth = 512,
377 .gainlkup = ai_gain_4,
380 .ao_maxdata = 0x0fff,
381 .ao_range_table = &range_bipolar10,
383 .caldac = { ad8804_debug }, /* manual is wrong */
388 .ai_maxdata = 0x0fff,
389 .ai_fifo_depth = 512,
390 .gainlkup = ai_gain_4,
393 .ao_maxdata = 0x0fff,
394 .ao_range_table = &range_bipolar10,
396 .caldac = { ad8804_debug }, /* manual is wrong */
402 .ai_maxdata = 0x0fff,
403 .ai_fifo_depth = 512,
404 .gainlkup = ai_gain_4,
407 .ao_maxdata = 0x0fff,
408 .ao_range_table = &range_ni_E_ao_ext,
410 .caldac = { ad8804_debug }, /* manual is wrong */
416 .ai_maxdata = 0xffff,
417 .ai_fifo_depth = 512,
419 .gainlkup = ai_gain_4,
421 .caldac = { ad8804_debug },
426 .ai_maxdata = 0xffff,
427 .ai_fifo_depth = 512,
429 .gainlkup = ai_gain_4,
432 .ao_maxdata = 0x0fff,
433 .ao_range_table = &range_bipolar10,
435 .caldac = { ad8804_debug },
440 .ai_maxdata = 0xffff,
441 .ai_fifo_depth = 512,
443 .gainlkup = ai_gain_16,
446 .ao_maxdata = 0xffff,
447 .ao_fifo_depth = 2048,
448 .ao_range_table = &range_ni_E_ao_ext,
450 /* manual is wrong */
451 .caldac = { ad8804_debug, ad8804_debug, ad8522 },
456 .ai_maxdata = 0x0fff,
457 .ai_fifo_depth = 8192,
459 .gainlkup = ai_gain_611x,
462 .ao_maxdata = 0xffff,
463 .reg_type = ni_reg_611x,
464 .ao_range_table = &range_bipolar10,
465 .ao_fifo_depth = 2048,
467 .caldac = { ad8804, ad8804 },
472 .ai_maxdata = 0x0fff,
473 .ai_fifo_depth = 8192,
474 .gainlkup = ai_gain_611x,
477 .ao_maxdata = 0xffff,
478 .reg_type = ni_reg_611x,
479 .ao_range_table = &range_bipolar10,
480 .ao_fifo_depth = 2048,
482 .caldac = { ad8804, ad8804 },
485 /* The 6115 boards probably need their own driver */
486 [BOARD_PCI6115] = { /* .device_id = 0x2ed0, */
489 .ai_maxdata = 0x0fff,
490 .ai_fifo_depth = 8192,
491 .gainlkup = ai_gain_611x,
494 .ao_maxdata = 0xffff,
496 .ao_fifo_depth = 2048,
500 .caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
504 [BOARD_PXI6115] = { /* .device_id = ????, */
507 .ai_maxdata = 0x0fff,
508 .ai_fifo_depth = 8192,
509 .gainlkup = ai_gain_611x,
512 .ao_maxdata = 0xffff,
514 .ao_fifo_depth = 2048,
518 .caldac = { ad8804_debug, ad8804_debug, ad8804_debug },
524 .ao_maxdata = 0x0fff,
525 /* data sheet says 8192, but fifo really holds 16384 samples */
526 .ao_fifo_depth = 16384,
527 .ao_range_table = &range_bipolar10,
529 .reg_type = ni_reg_6711,
530 .caldac = { ad8804_debug },
535 .ao_maxdata = 0x0fff,
536 .ao_fifo_depth = 16384,
537 .ao_range_table = &range_bipolar10,
539 .reg_type = ni_reg_6711,
540 .caldac = { ad8804_debug },
545 .ao_maxdata = 0x0fff,
546 .ao_fifo_depth = 16384,
547 .ao_range_table = &range_bipolar10,
549 .reg_type = ni_reg_6713,
550 .caldac = { ad8804_debug, ad8804_debug },
555 .ao_maxdata = 0x0fff,
556 .ao_fifo_depth = 16384,
557 .ao_range_table = &range_bipolar10,
559 .reg_type = ni_reg_6713,
560 .caldac = { ad8804_debug, ad8804_debug },
565 .ao_maxdata = 0xffff,
566 .ao_fifo_depth = 8192,
567 .ao_range_table = &range_bipolar10,
569 .reg_type = ni_reg_6711,
570 .caldac = { ad8804_debug },
573 [BOARD_PXI6731] = { /* .device_id = ????, */
576 .ao_maxdata = 0xffff,
577 .ao_fifo_depth = 8192,
578 .ao_range_table = &range_bipolar10,
579 .reg_type = ni_reg_6711,
580 .caldac = { ad8804_debug },
586 .ao_maxdata = 0xffff,
587 .ao_fifo_depth = 16384,
588 .ao_range_table = &range_bipolar10,
590 .reg_type = ni_reg_6713,
591 .caldac = { ad8804_debug, ad8804_debug },
596 .ao_maxdata = 0xffff,
597 .ao_fifo_depth = 16384,
598 .ao_range_table = &range_bipolar10,
600 .reg_type = ni_reg_6713,
601 .caldac = { ad8804_debug, ad8804_debug },
606 .ai_maxdata = 0x0fff,
607 .ai_fifo_depth = 512,
609 .gainlkup = ai_gain_16,
612 .ao_maxdata = 0x0fff,
613 .ao_fifo_depth = 2048,
614 .ao_range_table = &range_ni_E_ao_ext,
616 .caldac = { ad8804_debug },
621 .ai_maxdata = 0x0fff,
622 .ai_fifo_depth = 512,
624 .gainlkup = ai_gain_16,
627 .ao_maxdata = 0x0fff,
628 .ao_fifo_depth = 2048,
629 .ao_range_table = &range_ni_E_ao_ext,
631 .caldac = { ad8804_debug },
636 .ai_maxdata = 0xffff,
637 .ai_fifo_depth = 512,
639 .gainlkup = ai_gain_16,
642 .ao_maxdata = 0xffff,
643 .ao_fifo_depth = 2048,
644 .ao_range_table = &range_ni_E_ao_ext,
646 .caldac = { mb88341, mb88341, ad8522 },
651 .ai_maxdata = 0xffff,
652 .ai_fifo_depth = 512,
654 .gainlkup = ai_gain_14,
657 .ao_maxdata = 0xffff,
658 .ao_fifo_depth = 2048,
659 .ao_range_table = &range_ni_E_ao_ext,
661 .caldac = { dac8800, dac8043, ad8522 },
666 .ai_maxdata = 0xffff,
667 .ai_fifo_depth = 512,
669 .gainlkup = ai_gain_4,
672 .ao_maxdata = 0xffff,
673 .ao_range_table = &range_bipolar10,
675 .caldac = { ad8804_debug },
680 .ai_maxdata = 0xffff,
681 .ai_fifo_depth = 512, /* FIXME: guess */
682 .gainlkup = ai_gain_622x,
684 .reg_type = ni_reg_622x,
685 .caldac = { caldac_none },
690 .ai_maxdata = 0xffff,
691 .ai_fifo_depth = 4095,
692 .gainlkup = ai_gain_622x,
695 .ao_maxdata = 0xffff,
696 .ao_fifo_depth = 8191,
697 .ao_range_table = &range_bipolar10,
698 .reg_type = ni_reg_622x,
700 .caldac = { caldac_none },
702 [BOARD_PCI6221_37PIN] = {
703 .name = "pci-6221_37pin",
705 .ai_maxdata = 0xffff,
706 .ai_fifo_depth = 4095,
707 .gainlkup = ai_gain_622x,
710 .ao_maxdata = 0xffff,
711 .ao_fifo_depth = 8191,
712 .ao_range_table = &range_bipolar10,
713 .reg_type = ni_reg_622x,
715 .caldac = { caldac_none },
720 .ai_maxdata = 0xffff,
721 .ai_fifo_depth = 4095,
722 .gainlkup = ai_gain_622x,
724 .reg_type = ni_reg_622x,
726 .caldac = { caldac_none },
731 .ai_maxdata = 0xffff,
732 .ai_fifo_depth = 4095,
733 .gainlkup = ai_gain_622x,
735 .reg_type = ni_reg_622x,
737 .caldac = { caldac_none },
742 .ai_maxdata = 0xffff,
743 .ai_fifo_depth = 4095,
744 .gainlkup = ai_gain_622x,
747 .ao_maxdata = 0xffff,
748 .ao_fifo_depth = 8191,
749 .ao_range_table = &range_bipolar10,
750 .reg_type = ni_reg_622x,
753 .caldac = { caldac_none },
758 .ai_maxdata = 0xffff,
759 .ai_fifo_depth = 4095,
760 .gainlkup = ai_gain_622x,
763 .ao_maxdata = 0xffff,
764 .ao_fifo_depth = 8191,
765 .ao_range_table = &range_bipolar10,
766 .reg_type = ni_reg_622x,
769 .caldac = { caldac_none },
774 .ai_maxdata = 0xffff,
775 .ai_fifo_depth = 4095,
776 .gainlkup = ai_gain_622x,
779 .ao_maxdata = 0xffff,
780 .ao_fifo_depth = 8191,
781 .ao_range_table = &range_bipolar10,
782 .reg_type = ni_reg_622x,
785 .caldac = { caldac_none },
790 .ai_maxdata = 0xffff,
791 .ai_fifo_depth = 4095,
792 .gainlkup = ai_gain_628x,
794 .reg_type = ni_reg_625x,
795 .caldac = { caldac_none },
800 .ai_maxdata = 0xffff,
801 .ai_fifo_depth = 4095,
802 .gainlkup = ai_gain_628x,
805 .ao_maxdata = 0xffff,
806 .ao_fifo_depth = 8191,
807 .ao_range_table = &range_ni_M_625x_ao,
808 .reg_type = ni_reg_625x,
810 .caldac = { caldac_none },
815 .ai_maxdata = 0xffff,
816 .ai_fifo_depth = 4095,
817 .gainlkup = ai_gain_628x,
820 .ao_maxdata = 0xffff,
821 .ao_fifo_depth = 8191,
822 .ao_range_table = &range_ni_M_625x_ao,
823 .reg_type = ni_reg_625x,
825 .caldac = { caldac_none },
830 .ai_maxdata = 0xffff,
831 .ai_fifo_depth = 4095,
832 .gainlkup = ai_gain_628x,
835 .ao_maxdata = 0xffff,
836 .ao_fifo_depth = 8191,
837 .ao_range_table = &range_ni_M_625x_ao,
838 .reg_type = ni_reg_625x,
840 .caldac = { caldac_none },
845 .ai_maxdata = 0xffff,
846 .ai_fifo_depth = 4095,
847 .gainlkup = ai_gain_628x,
850 .ao_maxdata = 0xffff,
851 .ao_fifo_depth = 8191,
852 .ao_range_table = &range_ni_M_625x_ao,
853 .reg_type = ni_reg_625x,
855 .caldac = { caldac_none },
860 .ai_maxdata = 0xffff,
861 .ai_fifo_depth = 4095,
862 .gainlkup = ai_gain_628x,
864 .reg_type = ni_reg_625x,
866 .caldac = { caldac_none },
871 .ai_maxdata = 0xffff,
872 .ai_fifo_depth = 4095,
873 .gainlkup = ai_gain_628x,
876 .ao_maxdata = 0xffff,
877 .ao_fifo_depth = 8191,
878 .ao_range_table = &range_ni_M_625x_ao,
879 .reg_type = ni_reg_625x,
882 .caldac = { caldac_none },
887 .ai_maxdata = 0xffff,
888 .ai_fifo_depth = 4095,
889 .gainlkup = ai_gain_628x,
892 .ao_maxdata = 0xffff,
893 .ao_fifo_depth = 8191,
894 .ao_range_table = &range_ni_M_625x_ao,
895 .reg_type = ni_reg_625x,
898 .caldac = { caldac_none },
903 .ai_maxdata = 0x3ffff,
904 .ai_fifo_depth = 2047,
905 .gainlkup = ai_gain_628x,
907 .ao_fifo_depth = 8191,
908 .reg_type = ni_reg_628x,
909 .caldac = { caldac_none },
914 .ai_maxdata = 0x3ffff,
915 .ai_fifo_depth = 2047,
916 .gainlkup = ai_gain_628x,
919 .ao_maxdata = 0xffff,
920 .ao_fifo_depth = 8191,
921 .ao_range_table = &range_ni_M_628x_ao,
922 .reg_type = ni_reg_628x,
924 .caldac = { caldac_none },
929 .ai_maxdata = 0x3ffff,
930 .ai_fifo_depth = 2047,
931 .gainlkup = ai_gain_628x,
934 .ao_maxdata = 0xffff,
935 .ao_fifo_depth = 8191,
936 .ao_range_table = &range_ni_M_628x_ao,
937 .reg_type = ni_reg_628x,
939 .caldac = { caldac_none },
944 .ai_maxdata = 0x3ffff,
945 .ai_fifo_depth = 2047,
946 .gainlkup = ai_gain_628x,
948 .reg_type = ni_reg_628x,
950 .caldac = { caldac_none },
955 .ai_maxdata = 0x3ffff,
956 .ai_fifo_depth = 2047,
957 .gainlkup = ai_gain_628x,
960 .ao_maxdata = 0xffff,
961 .ao_fifo_depth = 8191,
962 .ao_range_table = &range_ni_M_628x_ao,
963 .reg_type = ni_reg_628x,
966 .caldac = { caldac_none },
971 .ai_maxdata = 0xffff,
972 .ai_fifo_depth = 1024,
973 .gainlkup = ai_gain_6143,
975 .reg_type = ni_reg_6143,
976 .caldac = { ad8804_debug, ad8804_debug },
981 .ai_maxdata = 0xffff,
982 .ai_fifo_depth = 1024,
983 .gainlkup = ai_gain_6143,
985 .reg_type = ni_reg_6143,
986 .caldac = { ad8804_debug, ad8804_debug },
990 #include "ni_mio_common.c"
992 static int pcimio_ai_change(struct comedi_device *dev,
993 struct comedi_subdevice *s)
995 struct ni_private *devpriv = dev->private;
998 ret = mite_buf_change(devpriv->ai_mite_ring, s);
1005 static int pcimio_ao_change(struct comedi_device *dev,
1006 struct comedi_subdevice *s)
1008 struct ni_private *devpriv = dev->private;
1011 ret = mite_buf_change(devpriv->ao_mite_ring, s);
1018 static int pcimio_gpct0_change(struct comedi_device *dev,
1019 struct comedi_subdevice *s)
1021 struct ni_private *devpriv = dev->private;
1024 ret = mite_buf_change(devpriv->gpct_mite_ring[0], s);
1031 static int pcimio_gpct1_change(struct comedi_device *dev,
1032 struct comedi_subdevice *s)
1034 struct ni_private *devpriv = dev->private;
1037 ret = mite_buf_change(devpriv->gpct_mite_ring[1], s);
1044 static int pcimio_dio_change(struct comedi_device *dev,
1045 struct comedi_subdevice *s)
1047 struct ni_private *devpriv = dev->private;
1050 ret = mite_buf_change(devpriv->cdo_mite_ring, s);
1057 static void m_series_init_eeprom_buffer(struct comedi_device *dev)
1059 struct ni_private *devpriv = dev->private;
1060 struct mite *mite = devpriv->mite;
1061 resource_size_t daq_phys_addr;
1062 static const int Start_Cal_EEPROM = 0x400;
1063 static const unsigned int window_size = 10;
1064 static const int serial_number_eeprom_offset = 0x4;
1065 static const int serial_number_eeprom_length = 0x4;
1066 unsigned int old_iodwbsr_bits;
1067 unsigned int old_iodwbsr1_bits;
1068 unsigned int old_iodwcr1_bits;
1071 /* IO Window 1 needs to be temporarily mapped to read the eeprom */
1072 daq_phys_addr = pci_resource_start(mite->pcidev, 1);
1074 old_iodwbsr_bits = readl(mite->mmio + MITE_IODWBSR);
1075 old_iodwbsr1_bits = readl(mite->mmio + MITE_IODWBSR_1);
1076 old_iodwcr1_bits = readl(mite->mmio + MITE_IODWCR_1);
1077 writel(0x0, mite->mmio + MITE_IODWBSR);
1078 writel(((0x80 | window_size) | daq_phys_addr),
1079 mite->mmio + MITE_IODWBSR_1);
1080 writel(0x1 | old_iodwcr1_bits, mite->mmio + MITE_IODWCR_1);
1081 writel(0xf, mite->mmio + 0x30);
1083 BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number));
1084 for (i = 0; i < serial_number_eeprom_length; ++i) {
1085 char *byte_ptr = (char *)&devpriv->serial_number + i;
1086 *byte_ptr = ni_readb(dev, serial_number_eeprom_offset + i);
1088 devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
1090 for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i)
1091 devpriv->eeprom_buffer[i] = ni_readb(dev, Start_Cal_EEPROM + i);
1093 writel(old_iodwbsr1_bits, mite->mmio + MITE_IODWBSR_1);
1094 writel(old_iodwbsr_bits, mite->mmio + MITE_IODWBSR);
1095 writel(old_iodwcr1_bits, mite->mmio + MITE_IODWCR_1);
1096 writel(0x0, mite->mmio + 0x30);
1099 static void init_6143(struct comedi_device *dev)
1101 const struct ni_board_struct *board = dev->board_ptr;
1102 struct ni_private *devpriv = dev->private;
1104 /* Disable interrupts */
1105 ni_stc_writew(dev, 0, NISTC_INT_CTRL_REG);
1107 /* Initialise 6143 AI specific bits */
1109 /* Set G0,G1 DMA mode to E series version */
1110 ni_writeb(dev, 0x00, NI6143_MAGIC_REG);
1111 /* Set EOCMode, ADCMode and pipelinedelay */
1112 ni_writeb(dev, 0x80, NI6143_PIPELINE_DELAY_REG);
1114 ni_writeb(dev, 0x00, NI6143_EOC_SET_REG);
1116 /* Set the FIFO half full level */
1117 ni_writel(dev, board->ai_fifo_depth / 2, NI6143_AI_FIFO_FLAG_REG);
1119 /* Strobe Relay disable bit */
1120 devpriv->ai_calib_source_enabled = 0;
1121 ni_writew(dev, devpriv->ai_calib_source | NI6143_CALIB_CHAN_RELAY_OFF,
1122 NI6143_CALIB_CHAN_REG);
1123 ni_writew(dev, devpriv->ai_calib_source, NI6143_CALIB_CHAN_REG);
1126 static void pcimio_detach(struct comedi_device *dev)
1128 struct ni_private *devpriv = dev->private;
1130 mio_common_detach(dev);
1132 free_irq(dev->irq, dev);
1134 mite_free_ring(devpriv->ai_mite_ring);
1135 mite_free_ring(devpriv->ao_mite_ring);
1136 mite_free_ring(devpriv->cdo_mite_ring);
1137 mite_free_ring(devpriv->gpct_mite_ring[0]);
1138 mite_free_ring(devpriv->gpct_mite_ring[1]);
1139 mite_detach(devpriv->mite);
1143 comedi_pci_disable(dev);
1146 static int pcimio_auto_attach(struct comedi_device *dev,
1147 unsigned long context)
1149 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1150 const struct ni_board_struct *board = NULL;
1151 struct ni_private *devpriv;
1155 if (context < ARRAY_SIZE(ni_boards))
1156 board = &ni_boards[context];
1159 dev->board_ptr = board;
1160 dev->board_name = board->name;
1162 ret = comedi_pci_enable(dev);
1166 ret = ni_alloc_private(dev);
1169 devpriv = dev->private;
1171 devpriv->mite = mite_attach(dev, false); /* use win0 */
1175 if (board->reg_type & ni_reg_m_series_mask)
1176 devpriv->is_m_series = 1;
1177 if (board->reg_type & ni_reg_6xxx_mask)
1178 devpriv->is_6xxx = 1;
1179 if (board->reg_type == ni_reg_611x)
1180 devpriv->is_611x = 1;
1181 if (board->reg_type == ni_reg_6143)
1182 devpriv->is_6143 = 1;
1183 if (board->reg_type == ni_reg_622x)
1184 devpriv->is_622x = 1;
1185 if (board->reg_type == ni_reg_625x)
1186 devpriv->is_625x = 1;
1187 if (board->reg_type == ni_reg_628x)
1188 devpriv->is_628x = 1;
1189 if (board->reg_type & ni_reg_67xx_mask)
1190 devpriv->is_67xx = 1;
1191 if (board->reg_type == ni_reg_6711)
1192 devpriv->is_6711 = 1;
1193 if (board->reg_type == ni_reg_6713)
1194 devpriv->is_6713 = 1;
1196 devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
1197 if (!devpriv->ai_mite_ring)
1199 devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite);
1200 if (!devpriv->ao_mite_ring)
1202 devpriv->cdo_mite_ring = mite_alloc_ring(devpriv->mite);
1203 if (!devpriv->cdo_mite_ring)
1205 devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite);
1206 if (!devpriv->gpct_mite_ring[0])
1208 devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite);
1209 if (!devpriv->gpct_mite_ring[1])
1212 if (devpriv->is_m_series)
1213 m_series_init_eeprom_buffer(dev);
1214 if (devpriv->is_6143)
1219 ret = request_irq(irq, ni_E_interrupt, IRQF_SHARED,
1220 dev->board_name, dev);
1225 ret = ni_E_init(dev, 0, 1);
1229 dev->subdevices[NI_AI_SUBDEV].buf_change = &pcimio_ai_change;
1230 dev->subdevices[NI_AO_SUBDEV].buf_change = &pcimio_ao_change;
1231 dev->subdevices[NI_GPCT_SUBDEV(0)].buf_change = &pcimio_gpct0_change;
1232 dev->subdevices[NI_GPCT_SUBDEV(1)].buf_change = &pcimio_gpct1_change;
1233 dev->subdevices[NI_DIO_SUBDEV].buf_change = &pcimio_dio_change;
1238 static struct comedi_driver ni_pcimio_driver = {
1239 .driver_name = "ni_pcimio",
1240 .module = THIS_MODULE,
1241 .auto_attach = pcimio_auto_attach,
1242 .detach = pcimio_detach,
1245 static int ni_pcimio_pci_probe(struct pci_dev *dev,
1246 const struct pci_device_id *id)
1248 return comedi_pci_auto_config(dev, &ni_pcimio_driver, id->driver_data);
1251 static const struct pci_device_id ni_pcimio_pci_table[] = {
1252 { PCI_VDEVICE(NI, 0x0162), BOARD_PCIMIO_16XE_50 }, /* 0x1620? */
1253 { PCI_VDEVICE(NI, 0x1170), BOARD_PCIMIO_16XE_10 },
1254 { PCI_VDEVICE(NI, 0x1180), BOARD_PCIMIO_16E_1 },
1255 { PCI_VDEVICE(NI, 0x1190), BOARD_PCIMIO_16E_4 },
1256 { PCI_VDEVICE(NI, 0x11b0), BOARD_PXI6070E },
1257 { PCI_VDEVICE(NI, 0x11c0), BOARD_PXI6040E },
1258 { PCI_VDEVICE(NI, 0x11d0), BOARD_PXI6030E },
1259 { PCI_VDEVICE(NI, 0x1270), BOARD_PCI6032E },
1260 { PCI_VDEVICE(NI, 0x1330), BOARD_PCI6031E },
1261 { PCI_VDEVICE(NI, 0x1340), BOARD_PCI6033E },
1262 { PCI_VDEVICE(NI, 0x1350), BOARD_PCI6071E },
1263 { PCI_VDEVICE(NI, 0x14e0), BOARD_PCI6110 },
1264 { PCI_VDEVICE(NI, 0x14f0), BOARD_PCI6111 },
1265 { PCI_VDEVICE(NI, 0x1580), BOARD_PXI6031E },
1266 { PCI_VDEVICE(NI, 0x15b0), BOARD_PXI6071E },
1267 { PCI_VDEVICE(NI, 0x1880), BOARD_PCI6711 },
1268 { PCI_VDEVICE(NI, 0x1870), BOARD_PCI6713 },
1269 { PCI_VDEVICE(NI, 0x18b0), BOARD_PCI6052E },
1270 { PCI_VDEVICE(NI, 0x18c0), BOARD_PXI6052E },
1271 { PCI_VDEVICE(NI, 0x2410), BOARD_PCI6733 },
1272 { PCI_VDEVICE(NI, 0x2420), BOARD_PXI6733 },
1273 { PCI_VDEVICE(NI, 0x2430), BOARD_PCI6731 },
1274 { PCI_VDEVICE(NI, 0x2890), BOARD_PCI6036E },
1275 { PCI_VDEVICE(NI, 0x28c0), BOARD_PCI6014 },
1276 { PCI_VDEVICE(NI, 0x2a60), BOARD_PCI6023E },
1277 { PCI_VDEVICE(NI, 0x2a70), BOARD_PCI6024E },
1278 { PCI_VDEVICE(NI, 0x2a80), BOARD_PCI6025E },
1279 { PCI_VDEVICE(NI, 0x2ab0), BOARD_PXI6025E },
1280 { PCI_VDEVICE(NI, 0x2b80), BOARD_PXI6713 },
1281 { PCI_VDEVICE(NI, 0x2b90), BOARD_PXI6711 },
1282 { PCI_VDEVICE(NI, 0x2c80), BOARD_PCI6035E },
1283 { PCI_VDEVICE(NI, 0x2ca0), BOARD_PCI6034E },
1284 { PCI_VDEVICE(NI, 0x70aa), BOARD_PCI6229 },
1285 { PCI_VDEVICE(NI, 0x70ab), BOARD_PCI6259 },
1286 { PCI_VDEVICE(NI, 0x70ac), BOARD_PCI6289 },
1287 { PCI_VDEVICE(NI, 0x70af), BOARD_PCI6221 },
1288 { PCI_VDEVICE(NI, 0x70b0), BOARD_PCI6220 },
1289 { PCI_VDEVICE(NI, 0x70b4), BOARD_PCI6250 },
1290 { PCI_VDEVICE(NI, 0x70b6), BOARD_PCI6280 },
1291 { PCI_VDEVICE(NI, 0x70b7), BOARD_PCI6254 },
1292 { PCI_VDEVICE(NI, 0x70b8), BOARD_PCI6251 },
1293 { PCI_VDEVICE(NI, 0x70bc), BOARD_PCI6284 },
1294 { PCI_VDEVICE(NI, 0x70bd), BOARD_PCI6281 },
1295 { PCI_VDEVICE(NI, 0x70bf), BOARD_PXI6281 },
1296 { PCI_VDEVICE(NI, 0x70c0), BOARD_PCI6143 },
1297 { PCI_VDEVICE(NI, 0x70f2), BOARD_PCI6224 },
1298 { PCI_VDEVICE(NI, 0x70f3), BOARD_PXI6224 },
1299 { PCI_VDEVICE(NI, 0x710d), BOARD_PXI6143 },
1300 { PCI_VDEVICE(NI, 0x716c), BOARD_PCI6225 },
1301 { PCI_VDEVICE(NI, 0x716d), BOARD_PXI6225 },
1302 { PCI_VDEVICE(NI, 0x717f), BOARD_PCIE6259 },
1303 { PCI_VDEVICE(NI, 0x71bc), BOARD_PCI6221_37PIN },
1304 { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 },
1305 { PCI_VDEVICE(NI, 0x72e8), BOARD_PXIE6251 },
1306 { PCI_VDEVICE(NI, 0x70ad), BOARD_PXI6251 },
1309 MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table);
1311 static struct pci_driver ni_pcimio_pci_driver = {
1312 .name = "ni_pcimio",
1313 .id_table = ni_pcimio_pci_table,
1314 .probe = ni_pcimio_pci_probe,
1315 .remove = comedi_pci_auto_unconfig,
1317 module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver);
1319 MODULE_AUTHOR("Comedi http://www.comedi.org");
1320 MODULE_DESCRIPTION("Comedi low-level driver");
1321 MODULE_LICENSE("GPL");