2 comedi/drivers/me4000.c
3 Source code for the Meilhaus ME-4000 board family.
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 Description: Meilhaus ME-4000 series boards
21 Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, ME-4680is
22 Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>)
23 Updated: Mon, 18 Mar 2002 15:34:01 -0800
24 Status: broken (no support for loading firmware)
33 Configuration Options: not applicable, uses PCI auto config
35 The firmware required by these boards is available in the
36 comedi_nonfree_firmware tarball available from
37 http://www.comedi.org. However, the driver's support for
38 loading the firmware through comedi_config is currently
43 #include <linux/module.h>
44 #include <linux/delay.h>
45 #include <linux/interrupt.h>
47 #include "../comedi_pci.h"
49 #include "comedi_8254.h"
52 #define ME4000_FIRMWARE "me4000_firmware.bin"
55 * ME4000 Register map and bit defines
57 #define ME4000_AO_CHAN(x) ((x) * 0x18)
59 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x))
60 #define ME4000_AO_CTRL_MODE_0 BIT(0)
61 #define ME4000_AO_CTRL_MODE_1 BIT(1)
62 #define ME4000_AO_CTRL_STOP BIT(2)
63 #define ME4000_AO_CTRL_ENABLE_FIFO BIT(3)
64 #define ME4000_AO_CTRL_ENABLE_EX_TRIG BIT(4)
65 #define ME4000_AO_CTRL_EX_TRIG_EDGE BIT(5)
66 #define ME4000_AO_CTRL_IMMEDIATE_STOP BIT(7)
67 #define ME4000_AO_CTRL_ENABLE_DO BIT(8)
68 #define ME4000_AO_CTRL_ENABLE_IRQ BIT(9)
69 #define ME4000_AO_CTRL_RESET_IRQ BIT(10)
70 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x))
71 #define ME4000_AO_STATUS_FSM BIT(0)
72 #define ME4000_AO_STATUS_FF BIT(1)
73 #define ME4000_AO_STATUS_HF BIT(2)
74 #define ME4000_AO_STATUS_EF BIT(3)
75 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x))
76 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x))
77 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x))
78 #define ME4000_AI_CTRL_REG 0x74
79 #define ME4000_AI_STATUS_REG 0x74
80 #define ME4000_AI_CTRL_MODE_0 BIT(0)
81 #define ME4000_AI_CTRL_MODE_1 BIT(1)
82 #define ME4000_AI_CTRL_MODE_2 BIT(2)
83 #define ME4000_AI_CTRL_SAMPLE_HOLD BIT(3)
84 #define ME4000_AI_CTRL_IMMEDIATE_STOP BIT(4)
85 #define ME4000_AI_CTRL_STOP BIT(5)
86 #define ME4000_AI_CTRL_CHANNEL_FIFO BIT(6)
87 #define ME4000_AI_CTRL_DATA_FIFO BIT(7)
88 #define ME4000_AI_CTRL_FULLSCALE BIT(8)
89 #define ME4000_AI_CTRL_OFFSET BIT(9)
90 #define ME4000_AI_CTRL_EX_TRIG_ANALOG BIT(10)
91 #define ME4000_AI_CTRL_EX_TRIG BIT(11)
92 #define ME4000_AI_CTRL_EX_TRIG_FALLING BIT(12)
93 #define ME4000_AI_CTRL_EX_IRQ BIT(13)
94 #define ME4000_AI_CTRL_EX_IRQ_RESET BIT(14)
95 #define ME4000_AI_CTRL_LE_IRQ BIT(15)
96 #define ME4000_AI_CTRL_LE_IRQ_RESET BIT(16)
97 #define ME4000_AI_CTRL_HF_IRQ BIT(17)
98 #define ME4000_AI_CTRL_HF_IRQ_RESET BIT(18)
99 #define ME4000_AI_CTRL_SC_IRQ BIT(19)
100 #define ME4000_AI_CTRL_SC_IRQ_RESET BIT(20)
101 #define ME4000_AI_CTRL_SC_RELOAD BIT(21)
102 #define ME4000_AI_STATUS_EF_CHANNEL BIT(22)
103 #define ME4000_AI_STATUS_HF_CHANNEL BIT(23)
104 #define ME4000_AI_STATUS_FF_CHANNEL BIT(24)
105 #define ME4000_AI_STATUS_EF_DATA BIT(25)
106 #define ME4000_AI_STATUS_HF_DATA BIT(26)
107 #define ME4000_AI_STATUS_FF_DATA BIT(27)
108 #define ME4000_AI_STATUS_LE BIT(28)
109 #define ME4000_AI_STATUS_FSM BIT(29)
110 #define ME4000_AI_CTRL_EX_TRIG_BOTH BIT(31)
111 #define ME4000_AI_CHANNEL_LIST_REG 0x78
112 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL BIT(5)
113 #define ME4000_AI_LIST_RANGE(x) ((3 - ((x) & 3)) << 6)
114 #define ME4000_AI_LIST_LAST_ENTRY BIT(8)
115 #define ME4000_AI_DATA_REG 0x7c
116 #define ME4000_AI_CHAN_TIMER_REG 0x80
117 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84
118 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88
119 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c
120 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90
121 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94
122 #define ME4000_AI_START_REG 0x98
123 #define ME4000_IRQ_STATUS_REG 0x9c
124 #define ME4000_IRQ_STATUS_EX BIT(0)
125 #define ME4000_IRQ_STATUS_LE BIT(1)
126 #define ME4000_IRQ_STATUS_AI_HF BIT(2)
127 #define ME4000_IRQ_STATUS_AO_0_HF BIT(3)
128 #define ME4000_IRQ_STATUS_AO_1_HF BIT(4)
129 #define ME4000_IRQ_STATUS_AO_2_HF BIT(5)
130 #define ME4000_IRQ_STATUS_AO_3_HF BIT(6)
131 #define ME4000_IRQ_STATUS_SC BIT(7)
132 #define ME4000_DIO_PORT_0_REG 0xa0
133 #define ME4000_DIO_PORT_1_REG 0xa4
134 #define ME4000_DIO_PORT_2_REG 0xa8
135 #define ME4000_DIO_PORT_3_REG 0xac
136 #define ME4000_DIO_DIR_REG 0xb0
137 #define ME4000_AO_LOADSETREG_XX 0xb4
138 #define ME4000_DIO_CTRL_REG 0xb8
139 #define ME4000_DIO_CTRL_MODE_0 BIT(0)
140 #define ME4000_DIO_CTRL_MODE_1 BIT(1)
141 #define ME4000_DIO_CTRL_MODE_2 BIT(2)
142 #define ME4000_DIO_CTRL_MODE_3 BIT(3)
143 #define ME4000_DIO_CTRL_MODE_4 BIT(4)
144 #define ME4000_DIO_CTRL_MODE_5 BIT(5)
145 #define ME4000_DIO_CTRL_MODE_6 BIT(6)
146 #define ME4000_DIO_CTRL_MODE_7 BIT(7)
147 #define ME4000_DIO_CTRL_FUNCTION_0 BIT(8)
148 #define ME4000_DIO_CTRL_FUNCTION_1 BIT(9)
149 #define ME4000_DIO_CTRL_FIFO_HIGH_0 BIT(10)
150 #define ME4000_DIO_CTRL_FIFO_HIGH_1 BIT(11)
151 #define ME4000_DIO_CTRL_FIFO_HIGH_2 BIT(12)
152 #define ME4000_DIO_CTRL_FIFO_HIGH_3 BIT(13)
153 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc
154 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c
155 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0
157 #define ME4000_AI_FIFO_COUNT 2048
159 #define ME4000_AI_MIN_TICKS 66
160 #define ME4000_AI_MIN_SAMPLE_TIME 2000
162 #define ME4000_AI_CHANNEL_LIST_COUNT 1024
164 struct me4000_private
{
165 unsigned long plx_regbase
;
166 unsigned int ai_ctrl_mode
;
167 unsigned int ai_init_ticks
;
168 unsigned int ai_scan_ticks
;
169 unsigned int ai_chan_ticks
;
172 enum me4000_boardid
{
188 struct me4000_board
{
191 unsigned int can_do_diff_ai
:1;
192 unsigned int can_do_sh_ai
:1; /* sample & hold (8 channels) */
193 unsigned int ex_trig_analog
:1;
194 unsigned int has_ao
:1;
195 unsigned int has_ao_fifo
:1;
196 unsigned int has_counter
:1;
199 static const struct me4000_board me4000_boards
[] = {
305 * NOTE: the ranges here are inverted compared to the values
306 * written to the ME4000_AI_CHANNEL_LIST_REG,
308 * The ME4000_AI_LIST_RANGE() macro handles the inversion.
310 static const struct comedi_lrange me4000_ai_range
= {
319 static int me4000_xilinx_download(struct comedi_device
*dev
,
320 const u8
*data
, size_t size
,
321 unsigned long context
)
323 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
324 struct me4000_private
*devpriv
= dev
->private;
325 unsigned long xilinx_iobase
= pci_resource_start(pcidev
, 5);
326 unsigned int file_length
;
334 * Set PLX local interrupt 2 polarity to high.
335 * Interrupt is thrown by init pin of xilinx.
337 outl(PLX9052_INTCSR_LI2POL
, devpriv
->plx_regbase
+ PLX9052_INTCSR
);
339 /* Set /CS and /WRITE of the Xilinx */
340 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
341 val
|= PLX9052_CNTRL_UIO2_DATA
;
342 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
344 /* Init Xilinx with CS1 */
345 inb(xilinx_iobase
+ 0xC8);
347 /* Wait until /INIT pin is set */
349 val
= inl(devpriv
->plx_regbase
+ PLX9052_INTCSR
);
350 if (!(val
& PLX9052_INTCSR_LI2STAT
)) {
351 dev_err(dev
->class_dev
, "Can't init Xilinx\n");
355 /* Reset /CS and /WRITE of the Xilinx */
356 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
357 val
&= ~PLX9052_CNTRL_UIO2_DATA
;
358 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
360 /* Download Xilinx firmware */
361 file_length
= (((unsigned int)data
[0] & 0xff) << 24) +
362 (((unsigned int)data
[1] & 0xff) << 16) +
363 (((unsigned int)data
[2] & 0xff) << 8) +
364 ((unsigned int)data
[3] & 0xff);
367 for (i
= 0; i
< file_length
; i
++) {
368 outb(data
[16 + i
], xilinx_iobase
);
371 /* Check if BUSY flag is low */
372 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
373 if (val
& PLX9052_CNTRL_UIO1_DATA
) {
374 dev_err(dev
->class_dev
,
375 "Xilinx is still busy (i = %d)\n", i
);
380 /* If done flag is high download was successful */
381 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
382 if (!(val
& PLX9052_CNTRL_UIO0_DATA
)) {
383 dev_err(dev
->class_dev
, "DONE flag is not set\n");
384 dev_err(dev
->class_dev
, "Download not successful\n");
388 /* Set /CS and /WRITE */
389 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
390 val
|= PLX9052_CNTRL_UIO2_DATA
;
391 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
396 static void me4000_reset(struct comedi_device
*dev
)
398 struct me4000_private
*devpriv
= dev
->private;
402 /* Make a hardware reset */
403 val
= inl(devpriv
->plx_regbase
+ PLX9052_CNTRL
);
404 val
|= PLX9052_CNTRL_PCI_RESET
;
405 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
406 val
&= ~PLX9052_CNTRL_PCI_RESET
;
407 outl(val
, devpriv
->plx_regbase
+ PLX9052_CNTRL
);
409 /* 0x8000 to the DACs means an output voltage of 0V */
410 for (chan
= 0; chan
< 4; chan
++)
411 outl(0x8000, dev
->iobase
+ ME4000_AO_SINGLE_REG(chan
));
413 /* Set both stop bits in the analog input control register */
414 outl(ME4000_AI_CTRL_IMMEDIATE_STOP
| ME4000_AI_CTRL_STOP
,
415 dev
->iobase
+ ME4000_AI_CTRL_REG
);
417 /* Set both stop bits in the analog output control register */
418 val
= ME4000_AO_CTRL_IMMEDIATE_STOP
| ME4000_AO_CTRL_STOP
;
419 for (chan
= 0; chan
< 4; chan
++)
420 outl(val
, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
422 /* Enable interrupts on the PLX */
423 outl(PLX9052_INTCSR_LI1ENAB
|
424 PLX9052_INTCSR_LI1POL
|
425 PLX9052_INTCSR_PCIENAB
, devpriv
->plx_regbase
+ PLX9052_INTCSR
);
427 /* Set the adustment register for AO demux */
428 outl(ME4000_AO_DEMUX_ADJUST_VALUE
,
429 dev
->iobase
+ ME4000_AO_DEMUX_ADJUST_REG
);
432 * Set digital I/O direction for port 0
433 * to output on isolated versions
435 if (!(inl(dev
->iobase
+ ME4000_DIO_DIR_REG
) & 0x1))
436 outl(0x1, dev
->iobase
+ ME4000_DIO_CTRL_REG
);
439 static int me4000_ai_eoc(struct comedi_device
*dev
,
440 struct comedi_subdevice
*s
,
441 struct comedi_insn
*insn
,
442 unsigned long context
)
446 status
= inl(dev
->iobase
+ ME4000_AI_STATUS_REG
);
447 if (status
& ME4000_AI_STATUS_EF_DATA
)
452 static int me4000_ai_insn_read(struct comedi_device
*dev
,
453 struct comedi_subdevice
*s
,
454 struct comedi_insn
*insn
,
457 unsigned int chan
= CR_CHAN(insn
->chanspec
);
458 unsigned int range
= CR_RANGE(insn
->chanspec
);
459 unsigned int aref
= CR_AREF(insn
->chanspec
);
465 entry
= chan
| ME4000_AI_LIST_RANGE(range
);
466 if (aref
== AREF_DIFF
) {
467 if (!(s
->subdev_flags
&& SDF_DIFF
)) {
468 dev_err(dev
->class_dev
,
469 "Differential inputs are not available\n");
473 if (!comedi_range_is_bipolar(s
, range
)) {
474 dev_err(dev
->class_dev
,
475 "Range must be bipolar when aref = diff\n");
479 if (chan
>= (s
->n_chan
/ 2)) {
480 dev_err(dev
->class_dev
,
481 "Analog input is not available\n");
484 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
487 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
489 /* Clear channel list, data fifo and both stop bits */
490 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
491 tmp
&= ~(ME4000_AI_CTRL_CHANNEL_FIFO
| ME4000_AI_CTRL_DATA_FIFO
|
492 ME4000_AI_CTRL_STOP
| ME4000_AI_CTRL_IMMEDIATE_STOP
);
493 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
495 /* Set the acquisition mode to single */
496 tmp
&= ~(ME4000_AI_CTRL_MODE_0
| ME4000_AI_CTRL_MODE_1
|
497 ME4000_AI_CTRL_MODE_2
);
498 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
500 /* Enable channel list and data fifo */
501 tmp
|= ME4000_AI_CTRL_CHANNEL_FIFO
| ME4000_AI_CTRL_DATA_FIFO
;
502 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
504 /* Generate channel list entry */
505 outl(entry
, dev
->iobase
+ ME4000_AI_CHANNEL_LIST_REG
);
507 /* Set the timer to maximum sample rate */
508 outl(ME4000_AI_MIN_TICKS
, dev
->iobase
+ ME4000_AI_CHAN_TIMER_REG
);
509 outl(ME4000_AI_MIN_TICKS
, dev
->iobase
+ ME4000_AI_CHAN_PRE_TIMER_REG
);
511 for (i
= 0; i
< insn
->n
; i
++) {
514 /* start conversion by dummy read */
515 inl(dev
->iobase
+ ME4000_AI_START_REG
);
517 ret
= comedi_timeout(dev
, s
, insn
, me4000_ai_eoc
, 0);
521 /* read two's complement value and munge to offset binary */
522 val
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
);
523 data
[i
] = comedi_offset_munge(s
, val
);
529 static int me4000_ai_cancel(struct comedi_device
*dev
,
530 struct comedi_subdevice
*s
)
534 /* Stop any running conversion */
535 ctrl
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
536 ctrl
|= ME4000_AI_CTRL_STOP
| ME4000_AI_CTRL_IMMEDIATE_STOP
;
537 outl(ctrl
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
539 /* Clear the control register */
540 outl(0x0, dev
->iobase
+ ME4000_AI_CTRL_REG
);
545 static int me4000_ai_check_chanlist(struct comedi_device
*dev
,
546 struct comedi_subdevice
*s
,
547 struct comedi_cmd
*cmd
)
549 unsigned int aref0
= CR_AREF(cmd
->chanlist
[0]);
552 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
553 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
554 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
555 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
558 dev_dbg(dev
->class_dev
,
559 "Mode is not equal for all entries\n");
563 if (aref
== AREF_DIFF
) {
564 if (!(s
->subdev_flags
&& SDF_DIFF
)) {
565 dev_err(dev
->class_dev
,
566 "Differential inputs are not available\n");
570 if (chan
>= (s
->n_chan
/ 2)) {
571 dev_dbg(dev
->class_dev
,
572 "Channel number to high\n");
576 if (!comedi_range_is_bipolar(s
, range
)) {
577 dev_dbg(dev
->class_dev
,
578 "Bipolar is not selected in differential mode\n");
587 static void me4000_ai_round_cmd_args(struct comedi_device
*dev
,
588 struct comedi_subdevice
*s
,
589 struct comedi_cmd
*cmd
)
591 struct me4000_private
*devpriv
= dev
->private;
594 devpriv
->ai_init_ticks
= 0;
595 devpriv
->ai_scan_ticks
= 0;
596 devpriv
->ai_chan_ticks
= 0;
598 if (cmd
->start_arg
) {
599 devpriv
->ai_init_ticks
= (cmd
->start_arg
* 33) / 1000;
600 rest
= (cmd
->start_arg
* 33) % 1000;
602 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
604 devpriv
->ai_init_ticks
++;
605 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
607 devpriv
->ai_init_ticks
++;
611 if (cmd
->scan_begin_arg
) {
612 devpriv
->ai_scan_ticks
= (cmd
->scan_begin_arg
* 33) / 1000;
613 rest
= (cmd
->scan_begin_arg
* 33) % 1000;
615 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
617 devpriv
->ai_scan_ticks
++;
618 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
620 devpriv
->ai_scan_ticks
++;
624 if (cmd
->convert_arg
) {
625 devpriv
->ai_chan_ticks
= (cmd
->convert_arg
* 33) / 1000;
626 rest
= (cmd
->convert_arg
* 33) % 1000;
628 if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_NEAREST
) {
630 devpriv
->ai_chan_ticks
++;
631 } else if ((cmd
->flags
& CMDF_ROUND_MASK
) == CMDF_ROUND_UP
) {
633 devpriv
->ai_chan_ticks
++;
638 static void me4000_ai_write_chanlist(struct comedi_device
*dev
,
639 struct comedi_subdevice
*s
,
640 struct comedi_cmd
*cmd
)
644 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
645 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
646 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
647 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
650 entry
= chan
| ME4000_AI_LIST_RANGE(range
);
652 if (aref
== AREF_DIFF
)
653 entry
|= ME4000_AI_LIST_INPUT_DIFFERENTIAL
;
655 if (i
== (cmd
->chanlist_len
- 1))
656 entry
|= ME4000_AI_LIST_LAST_ENTRY
;
658 outl(entry
, dev
->iobase
+ ME4000_AI_CHANNEL_LIST_REG
);
662 static int me4000_ai_do_cmd(struct comedi_device
*dev
,
663 struct comedi_subdevice
*s
)
665 struct me4000_private
*devpriv
= dev
->private;
666 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
669 /* Write timer arguments */
670 outl(devpriv
->ai_init_ticks
- 1,
671 dev
->iobase
+ ME4000_AI_SCAN_PRE_TIMER_LOW_REG
);
672 outl(0x0, dev
->iobase
+ ME4000_AI_SCAN_PRE_TIMER_HIGH_REG
);
674 if (devpriv
->ai_scan_ticks
) {
675 outl(devpriv
->ai_scan_ticks
- 1,
676 dev
->iobase
+ ME4000_AI_SCAN_TIMER_LOW_REG
);
677 outl(0x0, dev
->iobase
+ ME4000_AI_SCAN_TIMER_HIGH_REG
);
680 outl(devpriv
->ai_chan_ticks
- 1,
681 dev
->iobase
+ ME4000_AI_CHAN_PRE_TIMER_REG
);
682 outl(devpriv
->ai_chan_ticks
- 1,
683 dev
->iobase
+ ME4000_AI_CHAN_TIMER_REG
);
686 ctrl
= devpriv
->ai_ctrl_mode
|
687 ME4000_AI_CTRL_CHANNEL_FIFO
|
688 ME4000_AI_CTRL_DATA_FIFO
;
691 if (cmd
->stop_src
== TRIG_COUNT
) {
692 outl(cmd
->chanlist_len
* cmd
->stop_arg
,
693 dev
->iobase
+ ME4000_AI_SAMPLE_COUNTER_REG
);
694 ctrl
|= ME4000_AI_CTRL_SC_IRQ
;
695 } else if (cmd
->stop_src
== TRIG_NONE
&&
696 cmd
->scan_end_src
== TRIG_COUNT
) {
697 outl(cmd
->scan_end_arg
,
698 dev
->iobase
+ ME4000_AI_SAMPLE_COUNTER_REG
);
699 ctrl
|= ME4000_AI_CTRL_SC_IRQ
;
701 ctrl
|= ME4000_AI_CTRL_HF_IRQ
;
703 /* Write the setup to the control register */
704 outl(ctrl
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
706 /* Write the channel list */
707 me4000_ai_write_chanlist(dev
, s
, cmd
);
709 /* Start acquistion by dummy read */
710 inl(dev
->iobase
+ ME4000_AI_START_REG
);
715 static int me4000_ai_do_cmd_test(struct comedi_device
*dev
,
716 struct comedi_subdevice
*s
,
717 struct comedi_cmd
*cmd
)
719 struct me4000_private
*devpriv
= dev
->private;
722 /* Step 1 : check if triggers are trivially valid */
724 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
725 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
726 TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
);
727 err
|= comedi_check_trigger_src(&cmd
->convert_src
,
728 TRIG_TIMER
| TRIG_EXT
);
729 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
,
730 TRIG_NONE
| TRIG_COUNT
);
731 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_NONE
| TRIG_COUNT
);
736 /* Step 2a : make sure trigger sources are unique */
738 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
739 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
740 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
741 err
|= comedi_check_trigger_is_unique(cmd
->scan_end_src
);
742 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
744 /* Step 2b : and mutually compatible */
746 if (cmd
->start_src
== TRIG_NOW
&&
747 cmd
->scan_begin_src
== TRIG_TIMER
&&
748 cmd
->convert_src
== TRIG_TIMER
) {
749 devpriv
->ai_ctrl_mode
= ME4000_AI_CTRL_MODE_0
;
750 } else if (cmd
->start_src
== TRIG_NOW
&&
751 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
752 cmd
->convert_src
== TRIG_TIMER
) {
753 devpriv
->ai_ctrl_mode
= ME4000_AI_CTRL_MODE_0
;
754 } else if (cmd
->start_src
== TRIG_EXT
&&
755 cmd
->scan_begin_src
== TRIG_TIMER
&&
756 cmd
->convert_src
== TRIG_TIMER
) {
757 devpriv
->ai_ctrl_mode
= ME4000_AI_CTRL_MODE_1
;
758 } else if (cmd
->start_src
== TRIG_EXT
&&
759 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
760 cmd
->convert_src
== TRIG_TIMER
) {
761 devpriv
->ai_ctrl_mode
= ME4000_AI_CTRL_MODE_1
;
762 } else if (cmd
->start_src
== TRIG_EXT
&&
763 cmd
->scan_begin_src
== TRIG_EXT
&&
764 cmd
->convert_src
== TRIG_TIMER
) {
765 devpriv
->ai_ctrl_mode
= ME4000_AI_CTRL_MODE_2
;
766 } else if (cmd
->start_src
== TRIG_EXT
&&
767 cmd
->scan_begin_src
== TRIG_EXT
&&
768 cmd
->convert_src
== TRIG_EXT
) {
769 devpriv
->ai_ctrl_mode
= ME4000_AI_CTRL_MODE_0
|
770 ME4000_AI_CTRL_MODE_1
;
778 /* Step 3: check if arguments are trivially valid */
780 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
782 if (cmd
->chanlist_len
< 1) {
783 cmd
->chanlist_len
= 1;
787 /* Round the timer arguments */
788 me4000_ai_round_cmd_args(dev
, s
, cmd
);
790 if (devpriv
->ai_init_ticks
< 66) {
791 cmd
->start_arg
= 2000;
794 if (devpriv
->ai_scan_ticks
&& devpriv
->ai_scan_ticks
< 67) {
795 cmd
->scan_begin_arg
= 2031;
798 if (devpriv
->ai_chan_ticks
< 66) {
799 cmd
->convert_arg
= 2000;
803 if (cmd
->stop_src
== TRIG_COUNT
)
804 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
806 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
812 * Stage 4. Check for argument conflicts.
814 if (cmd
->start_src
== TRIG_NOW
&&
815 cmd
->scan_begin_src
== TRIG_TIMER
&&
816 cmd
->convert_src
== TRIG_TIMER
) {
817 /* Check timer arguments */
818 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
819 dev_err(dev
->class_dev
, "Invalid start arg\n");
820 cmd
->start_arg
= 2000; /* 66 ticks at least */
823 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
824 dev_err(dev
->class_dev
, "Invalid convert arg\n");
825 cmd
->convert_arg
= 2000; /* 66 ticks at least */
828 if (devpriv
->ai_scan_ticks
<=
829 cmd
->chanlist_len
* devpriv
->ai_chan_ticks
) {
830 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
832 /* At least one tick more */
833 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
836 } else if (cmd
->start_src
== TRIG_NOW
&&
837 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
838 cmd
->convert_src
== TRIG_TIMER
) {
839 /* Check timer arguments */
840 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
841 dev_err(dev
->class_dev
, "Invalid start arg\n");
842 cmd
->start_arg
= 2000; /* 66 ticks at least */
845 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
846 dev_err(dev
->class_dev
, "Invalid convert arg\n");
847 cmd
->convert_arg
= 2000; /* 66 ticks at least */
850 } else if (cmd
->start_src
== TRIG_EXT
&&
851 cmd
->scan_begin_src
== TRIG_TIMER
&&
852 cmd
->convert_src
== TRIG_TIMER
) {
853 /* Check timer arguments */
854 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
855 dev_err(dev
->class_dev
, "Invalid start arg\n");
856 cmd
->start_arg
= 2000; /* 66 ticks at least */
859 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
860 dev_err(dev
->class_dev
, "Invalid convert arg\n");
861 cmd
->convert_arg
= 2000; /* 66 ticks at least */
864 if (devpriv
->ai_scan_ticks
<=
865 cmd
->chanlist_len
* devpriv
->ai_chan_ticks
) {
866 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
868 /* At least one tick more */
869 cmd
->scan_end_arg
= 2000 * cmd
->chanlist_len
+ 31;
872 } else if (cmd
->start_src
== TRIG_EXT
&&
873 cmd
->scan_begin_src
== TRIG_FOLLOW
&&
874 cmd
->convert_src
== TRIG_TIMER
) {
875 /* Check timer arguments */
876 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
877 dev_err(dev
->class_dev
, "Invalid start arg\n");
878 cmd
->start_arg
= 2000; /* 66 ticks at least */
881 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
882 dev_err(dev
->class_dev
, "Invalid convert arg\n");
883 cmd
->convert_arg
= 2000; /* 66 ticks at least */
886 } else if (cmd
->start_src
== TRIG_EXT
&&
887 cmd
->scan_begin_src
== TRIG_EXT
&&
888 cmd
->convert_src
== TRIG_TIMER
) {
889 /* Check timer arguments */
890 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
891 dev_err(dev
->class_dev
, "Invalid start arg\n");
892 cmd
->start_arg
= 2000; /* 66 ticks at least */
895 if (devpriv
->ai_chan_ticks
< ME4000_AI_MIN_TICKS
) {
896 dev_err(dev
->class_dev
, "Invalid convert arg\n");
897 cmd
->convert_arg
= 2000; /* 66 ticks at least */
900 } else if (cmd
->start_src
== TRIG_EXT
&&
901 cmd
->scan_begin_src
== TRIG_EXT
&&
902 cmd
->convert_src
== TRIG_EXT
) {
903 /* Check timer arguments */
904 if (devpriv
->ai_init_ticks
< ME4000_AI_MIN_TICKS
) {
905 dev_err(dev
->class_dev
, "Invalid start arg\n");
906 cmd
->start_arg
= 2000; /* 66 ticks at least */
910 if (cmd
->scan_end_src
== TRIG_COUNT
) {
911 if (cmd
->scan_end_arg
== 0) {
912 dev_err(dev
->class_dev
, "Invalid scan end arg\n");
913 cmd
->scan_end_arg
= 1;
921 /* Step 5: check channel list if it exists */
922 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
923 err
|= me4000_ai_check_chanlist(dev
, s
, cmd
);
931 static irqreturn_t
me4000_ai_isr(int irq
, void *dev_id
)
934 struct comedi_device
*dev
= dev_id
;
935 struct comedi_subdevice
*s
= dev
->read_subdev
;
943 if (inl(dev
->iobase
+ ME4000_IRQ_STATUS_REG
) &
944 ME4000_IRQ_STATUS_AI_HF
) {
945 /* Read status register to find out what happened */
946 tmp
= inl(dev
->iobase
+ ME4000_AI_STATUS_REG
);
948 if (!(tmp
& ME4000_AI_STATUS_FF_DATA
) &&
949 !(tmp
& ME4000_AI_STATUS_HF_DATA
) &&
950 (tmp
& ME4000_AI_STATUS_EF_DATA
)) {
951 c
= ME4000_AI_FIFO_COUNT
;
954 * FIFO overflow, so stop conversion
955 * and disable all interrupts
957 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
958 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
959 ME4000_AI_CTRL_SC_IRQ
);
960 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
962 s
->async
->events
|= COMEDI_CB_ERROR
;
964 dev_err(dev
->class_dev
, "FIFO overflow\n");
965 } else if ((tmp
& ME4000_AI_STATUS_FF_DATA
) &&
966 !(tmp
& ME4000_AI_STATUS_HF_DATA
) &&
967 (tmp
& ME4000_AI_STATUS_EF_DATA
)) {
968 c
= ME4000_AI_FIFO_COUNT
/ 2;
970 dev_err(dev
->class_dev
,
971 "Can't determine state of fifo\n");
975 * Undefined state, so stop conversion
976 * and disable all interrupts
978 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
979 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
980 ME4000_AI_CTRL_SC_IRQ
);
981 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
983 s
->async
->events
|= COMEDI_CB_ERROR
;
985 dev_err(dev
->class_dev
, "Undefined FIFO state\n");
988 for (i
= 0; i
< c
; i
++) {
989 /* Read value from data fifo */
990 lval
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
) & 0xFFFF;
993 if (!comedi_buf_write_samples(s
, &lval
, 1)) {
995 * Buffer overflow, so stop conversion
996 * and disable all interrupts
998 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
999 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
|
1000 ME4000_AI_CTRL_SC_IRQ
);
1001 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1006 /* Work is done, so reset the interrupt */
1007 tmp
|= ME4000_AI_CTRL_HF_IRQ_RESET
;
1008 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1009 tmp
&= ~ME4000_AI_CTRL_HF_IRQ_RESET
;
1010 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1013 if (inl(dev
->iobase
+ ME4000_IRQ_STATUS_REG
) &
1014 ME4000_IRQ_STATUS_SC
) {
1015 s
->async
->events
|= COMEDI_CB_EOA
;
1018 * Acquisition is complete, so stop
1019 * conversion and disable all interrupts
1021 tmp
= inl(dev
->iobase
+ ME4000_AI_CTRL_REG
);
1022 tmp
|= ME4000_AI_CTRL_IMMEDIATE_STOP
;
1023 tmp
&= ~(ME4000_AI_CTRL_HF_IRQ
| ME4000_AI_CTRL_SC_IRQ
);
1024 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1026 /* Poll data until fifo empty */
1027 while (inl(dev
->iobase
+ ME4000_AI_STATUS_REG
) &
1028 ME4000_AI_STATUS_EF_DATA
) {
1029 /* Read value from data fifo */
1030 lval
= inl(dev
->iobase
+ ME4000_AI_DATA_REG
) & 0xFFFF;
1033 if (!comedi_buf_write_samples(s
, &lval
, 1))
1037 /* Work is done, so reset the interrupt */
1038 tmp
|= ME4000_AI_CTRL_SC_IRQ_RESET
;
1039 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1040 tmp
&= ~ME4000_AI_CTRL_SC_IRQ_RESET
;
1041 outl(tmp
, dev
->iobase
+ ME4000_AI_CTRL_REG
);
1044 comedi_handle_events(dev
, s
);
1049 static int me4000_ao_insn_write(struct comedi_device
*dev
,
1050 struct comedi_subdevice
*s
,
1051 struct comedi_insn
*insn
,
1054 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1057 /* Stop any running conversion */
1058 tmp
= inl(dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1059 tmp
|= ME4000_AO_CTRL_IMMEDIATE_STOP
;
1060 outl(tmp
, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1062 /* Clear control register and set to single mode */
1063 outl(0x0, dev
->iobase
+ ME4000_AO_CTRL_REG(chan
));
1065 /* Write data value */
1066 outl(data
[0], dev
->iobase
+ ME4000_AO_SINGLE_REG(chan
));
1068 /* Store in the mirror */
1069 s
->readback
[chan
] = data
[0];
1074 static int me4000_dio_insn_bits(struct comedi_device
*dev
,
1075 struct comedi_subdevice
*s
,
1076 struct comedi_insn
*insn
,
1079 if (comedi_dio_update_state(s
, data
)) {
1080 outl((s
->state
>> 0) & 0xFF,
1081 dev
->iobase
+ ME4000_DIO_PORT_0_REG
);
1082 outl((s
->state
>> 8) & 0xFF,
1083 dev
->iobase
+ ME4000_DIO_PORT_1_REG
);
1084 outl((s
->state
>> 16) & 0xFF,
1085 dev
->iobase
+ ME4000_DIO_PORT_2_REG
);
1086 outl((s
->state
>> 24) & 0xFF,
1087 dev
->iobase
+ ME4000_DIO_PORT_3_REG
);
1090 data
[1] = ((inl(dev
->iobase
+ ME4000_DIO_PORT_0_REG
) & 0xFF) << 0) |
1091 ((inl(dev
->iobase
+ ME4000_DIO_PORT_1_REG
) & 0xFF) << 8) |
1092 ((inl(dev
->iobase
+ ME4000_DIO_PORT_2_REG
) & 0xFF) << 16) |
1093 ((inl(dev
->iobase
+ ME4000_DIO_PORT_3_REG
) & 0xFF) << 24);
1098 static int me4000_dio_insn_config(struct comedi_device
*dev
,
1099 struct comedi_subdevice
*s
,
1100 struct comedi_insn
*insn
,
1103 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1117 ret
= comedi_dio_insn_config(dev
, s
, insn
, data
, mask
);
1121 tmp
= inl(dev
->iobase
+ ME4000_DIO_CTRL_REG
);
1122 tmp
&= ~(ME4000_DIO_CTRL_MODE_0
| ME4000_DIO_CTRL_MODE_1
|
1123 ME4000_DIO_CTRL_MODE_2
| ME4000_DIO_CTRL_MODE_3
|
1124 ME4000_DIO_CTRL_MODE_4
| ME4000_DIO_CTRL_MODE_5
|
1125 ME4000_DIO_CTRL_MODE_6
| ME4000_DIO_CTRL_MODE_7
);
1126 if (s
->io_bits
& 0x000000ff)
1127 tmp
|= ME4000_DIO_CTRL_MODE_0
;
1128 if (s
->io_bits
& 0x0000ff00)
1129 tmp
|= ME4000_DIO_CTRL_MODE_2
;
1130 if (s
->io_bits
& 0x00ff0000)
1131 tmp
|= ME4000_DIO_CTRL_MODE_4
;
1132 if (s
->io_bits
& 0xff000000)
1133 tmp
|= ME4000_DIO_CTRL_MODE_6
;
1136 * Check for optoisolated ME-4000 version.
1137 * If one the first port is a fixed output
1138 * port and the second is a fixed input port.
1140 if (inl(dev
->iobase
+ ME4000_DIO_DIR_REG
)) {
1141 s
->io_bits
|= 0x000000ff;
1142 s
->io_bits
&= ~0x0000ff00;
1143 tmp
|= ME4000_DIO_CTRL_MODE_0
;
1144 tmp
&= ~(ME4000_DIO_CTRL_MODE_2
| ME4000_DIO_CTRL_MODE_3
);
1147 outl(tmp
, dev
->iobase
+ ME4000_DIO_CTRL_REG
);
1152 static int me4000_auto_attach(struct comedi_device
*dev
,
1153 unsigned long context
)
1155 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1156 const struct me4000_board
*board
= NULL
;
1157 struct me4000_private
*devpriv
;
1158 struct comedi_subdevice
*s
;
1161 if (context
< ARRAY_SIZE(me4000_boards
))
1162 board
= &me4000_boards
[context
];
1165 dev
->board_ptr
= board
;
1166 dev
->board_name
= board
->name
;
1168 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1172 result
= comedi_pci_enable(dev
);
1176 devpriv
->plx_regbase
= pci_resource_start(pcidev
, 1);
1177 dev
->iobase
= pci_resource_start(pcidev
, 2);
1178 if (!devpriv
->plx_regbase
|| !dev
->iobase
)
1181 result
= comedi_load_firmware(dev
, &pcidev
->dev
, ME4000_FIRMWARE
,
1182 me4000_xilinx_download
, 0);
1188 if (pcidev
->irq
> 0) {
1189 result
= request_irq(pcidev
->irq
, me4000_ai_isr
, IRQF_SHARED
,
1190 dev
->board_name
, dev
);
1192 dev
->irq
= pcidev
->irq
;
1195 result
= comedi_alloc_subdevices(dev
, 4);
1199 /* Analog Input subdevice */
1200 s
= &dev
->subdevices
[0];
1201 s
->type
= COMEDI_SUBD_AI
;
1202 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
;
1203 if (board
->can_do_diff_ai
)
1204 s
->subdev_flags
|= SDF_DIFF
;
1205 s
->n_chan
= board
->ai_nchan
;
1206 s
->maxdata
= 0xffff;
1207 s
->len_chanlist
= ME4000_AI_CHANNEL_LIST_COUNT
;
1208 s
->range_table
= &me4000_ai_range
;
1209 s
->insn_read
= me4000_ai_insn_read
;
1212 dev
->read_subdev
= s
;
1213 s
->subdev_flags
|= SDF_CMD_READ
;
1214 s
->cancel
= me4000_ai_cancel
;
1215 s
->do_cmdtest
= me4000_ai_do_cmd_test
;
1216 s
->do_cmd
= me4000_ai_do_cmd
;
1219 /*=========================================================================
1220 Analog output subdevice
1221 ========================================================================*/
1223 s
= &dev
->subdevices
[1];
1225 if (board
->has_ao
) {
1226 s
->type
= COMEDI_SUBD_AO
;
1227 s
->subdev_flags
= SDF_WRITABLE
| SDF_COMMON
| SDF_GROUND
;
1229 s
->maxdata
= 0xFFFF; /* 16 bit DAC */
1230 s
->range_table
= &range_bipolar10
;
1231 s
->insn_write
= me4000_ao_insn_write
;
1233 result
= comedi_alloc_subdev_readback(s
);
1237 s
->type
= COMEDI_SUBD_UNUSED
;
1240 /* Digital I/O subdevice */
1241 s
= &dev
->subdevices
[2];
1242 s
->type
= COMEDI_SUBD_DIO
;
1243 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
1246 s
->range_table
= &range_digital
;
1247 s
->insn_bits
= me4000_dio_insn_bits
;
1248 s
->insn_config
= me4000_dio_insn_config
;
1251 * Check for optoisolated ME-4000 version. If one the first
1252 * port is a fixed output port and the second is a fixed input port.
1254 if (!inl(dev
->iobase
+ ME4000_DIO_DIR_REG
)) {
1256 outl(ME4000_DIO_CTRL_MODE_0
,
1257 dev
->iobase
+ ME4000_DIO_DIR_REG
);
1260 /* Counter subdevice (8254) */
1261 s
= &dev
->subdevices
[3];
1262 if (board
->has_counter
) {
1263 unsigned long timer_base
= pci_resource_start(pcidev
, 3);
1268 dev
->pacer
= comedi_8254_init(timer_base
, 0, I8254_IO8
, 0);
1272 comedi_8254_subdevice_init(s
, dev
->pacer
);
1274 s
->type
= COMEDI_SUBD_UNUSED
;
1280 static void me4000_detach(struct comedi_device
*dev
)
1284 comedi_pci_detach(dev
);
1287 static struct comedi_driver me4000_driver
= {
1288 .driver_name
= "me4000",
1289 .module
= THIS_MODULE
,
1290 .auto_attach
= me4000_auto_attach
,
1291 .detach
= me4000_detach
,
1294 static int me4000_pci_probe(struct pci_dev
*dev
,
1295 const struct pci_device_id
*id
)
1297 return comedi_pci_auto_config(dev
, &me4000_driver
, id
->driver_data
);
1300 static const struct pci_device_id me4000_pci_table
[] = {
1301 { PCI_VDEVICE(MEILHAUS
, 0x4650), BOARD_ME4650
},
1302 { PCI_VDEVICE(MEILHAUS
, 0x4660), BOARD_ME4660
},
1303 { PCI_VDEVICE(MEILHAUS
, 0x4661), BOARD_ME4660I
},
1304 { PCI_VDEVICE(MEILHAUS
, 0x4662), BOARD_ME4660S
},
1305 { PCI_VDEVICE(MEILHAUS
, 0x4663), BOARD_ME4660IS
},
1306 { PCI_VDEVICE(MEILHAUS
, 0x4670), BOARD_ME4670
},
1307 { PCI_VDEVICE(MEILHAUS
, 0x4671), BOARD_ME4670I
},
1308 { PCI_VDEVICE(MEILHAUS
, 0x4672), BOARD_ME4670S
},
1309 { PCI_VDEVICE(MEILHAUS
, 0x4673), BOARD_ME4670IS
},
1310 { PCI_VDEVICE(MEILHAUS
, 0x4680), BOARD_ME4680
},
1311 { PCI_VDEVICE(MEILHAUS
, 0x4681), BOARD_ME4680I
},
1312 { PCI_VDEVICE(MEILHAUS
, 0x4682), BOARD_ME4680S
},
1313 { PCI_VDEVICE(MEILHAUS
, 0x4683), BOARD_ME4680IS
},
1316 MODULE_DEVICE_TABLE(pci
, me4000_pci_table
);
1318 static struct pci_driver me4000_pci_driver
= {
1320 .id_table
= me4000_pci_table
,
1321 .probe
= me4000_pci_probe
,
1322 .remove
= comedi_pci_auto_unconfig
,
1324 module_comedi_pci_driver(me4000_driver
, me4000_pci_driver
);
1326 MODULE_AUTHOR("Comedi http://www.comedi.org");
1327 MODULE_DESCRIPTION("Comedi low-level driver");
1328 MODULE_LICENSE("GPL");
1329 MODULE_FIRMWARE(ME4000_FIRMWARE
);